Windowsでは同一プロセス内に、32ビットプログラムと64ビットプログラムの混在は許されていません。例えば、32ビット動作のプログラムをx86、64ビット動作のプログラムをx64とした場合、
OK:x86のExeとx86のDLL *1、x64のExeとx64のDLL *2 は呼出し可能
NG:x86のExeとx64のDLL、 x64のExeとx86のDLLは呼出し不可
*1:32ビットOS または Wow64配下で動作
*2:64ビットOSのみで動作
ですので、ネイティブ動作指向のVisualBasicでは IsWow64Process 関数とは無縁だよなぁ~と思ってしまいましたが、前回、既定値の「AnyCPU」を「x86」に変更した事もあり、使ってみる事に。
マイクロソフトのドキュメントによれば、GetCurrentProcess関数とIsWow64Process関数の構文は、
■ Retrieves a pseudo handle for the current process.
HANDLE GetCurrentProcess();
Return value
The return value is a pseudo handle to the current process.
■ Determines whether the specified process is running under WOW64 or an Intel64 of x64 processor.
BOOL IsWow64Process(HANDLE hProcess, PBOOL Wow64Process);
Return value
If the function succeeds, the return value is a nonzero value.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
なので、戻り値と引数の変数型を Integer と Boolean に置き換えれば、上手くゆく筈?
とは言うものの、一筋縄では行かないのはBOOLでしょうか。
マイクロソフトのドキュメントによれば、
・C/C++では、BOOL は int 型、BOOLEAN は BYTE 型の様です(TRUE または FALSE である必要があります)。
・VBでは、以下様なのだとか。
Boolean 型が数値型に正確に変換されない
Boolean データ型の値は数値として格納されず、格納された値は数値と等価であると見なされません。以前のバージョンとの互換性のために、Visual Basic は変換キーワード (CType 関数、CBool、CInt など) を使用して、Boolean と数値型の間で変換を行います。ただし、その他の言語では、.NET Framework メソッドと同様に、これらの変換が異なる方法で実行されることがあります。
True と False に対して等価の数値に依存するコードを記述することは避けてください。可能な限り、Boolean 変数には、仕様で定められている論理値以外の値を使用しないようにしてください。Boolean 値と数値を混在させる必要がある場合は、選択する変換方法をよく理解してください。
Visual Basic での変換
CType または CBool の変換キーワードを使用して数値データ型を Boolean に変換するとき、0 が False になり、その他のすべての値が True になります。変換キーワードを使用して Boolean 値を数値型に変換するとき、False は 0 になり、True は -1 になります。
<注意点>
・C/C++では、HANDLE は PVOID 型です。(AnyCPU では Integer ではなく IntPtr で)
・VBの Boolean 変数は サイズが2バイトらしいので、偶々、動作している可能性大。
・不測の事態を招かないために、IsWow64Process 関数の戻り値は失敗したかどうか、つまり"0"かどうかをチェックするのが宜しいかと。
・VisualStudio11と.NET4.5でマイクロソフトがAnyCPUを再定義したそうな
新たなデフォルトは、「AnyCPU32Bit優先」らしい。(何周遅れ? の気付き)
⇒これは動作が可能な場合、32Bitで動作する。という事らしい。
お試し環境
WindowsXP 32bit Edition、Windows7 64bit Edition
Visual Basic 2008 対象CPUはx86とAnyCPU
/*-------------------------------- お試し結果 ------------------------------*/
・敢えて、x86版を WindowsXP 32bit Edition で動作させてみる
・x86版を Windows7 64bit Edition で動作
・AnyCPU版を Windows7 64bit Edition で動作
/*----------------------------------------------------------------------------*/
/*-------------------------------- お試しソース ----------------------------*/
Public Class Form1
Declare Auto Function GetCurrentProcess Lib "kernel32" () As Integer
Declare Auto Function IsWow64Process Lib "kernel32" (ByVal hprcs As Integer, ByRef w64prcs As Boolean) As Boolean
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim hdl As Integer
Dim res As Boolean
Dim biw64 As Boolean
Dim msg As String
hdl = GetCurrentProcess
res = IsWow64Process(hdl, biw64)
If res <> 0 Then
msg = "return GetCurrentProcess : " & hdl.ToString & vbCrLf & _
"return IsWow64Process : " & res & vbCrLf & _
"Wow64Process value : " & biw64
MsgBox(msg, MsgBoxStyle.Information, "result IsRunningUnderWow64")
Else
MsgBox(Err.LastDllError, MsgBoxStyle.AbortRetryIgnore, "IsWow64Process Error Occured")
End If
End Sub
End Class
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*============================================================================*/