VB作成のプログラム動作がWOW64配下かどうか、IsWow64Process関数で確認

|

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 版 WindowsXP 32bit Edition で動作

・x86版を Windows7 64bit Edition で動作

x86 版 Windows7 64bit Edition で動作

・AnyCPU版を 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

/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/*============================================================================*/