Migaro. 技術Tips

                       

ミガロ. 製品の技術情報
IBMiの活用に役立つ情報を掲載!


Delphi System32とSysWOW64を使い分ける手順

64bit OSのWindows PCやWindows Server(以下、64bit端末)では、
Windowsの動作に必要なファイルが、c:\Windows 内の
「System32」「SysWOW64」というシステムフォルダに格納されています。


 

64bit端末においては

  • SysWOW64フォルダには32bit用のファイルが格納される
  • System32フォルダには64bit用のファイルが格納される

という使い分けになっています。
(32bit端末では64bit用のファイルが存在しないので、
 全てのシステムファイルが「System32」フォルダに格納されます)

 

ここで注意が必要になるのが、64bit端末において
32bitのアプリケーションを使ってシステムフォルダを参照する場合です。

32bitのアプリケーションで64bit用フォルダである「System32」に対して読み書きを試みた場合、
32bit版用フォルダである「SysWOW64」フォルダに自動的にリダイレクトされます。

これは64bitのWindowsの仕様で、たとえば32bitのアプリケーションから
本当に64bit用フォルダである「System32」フォルダを対象として
ファイルの参照やファイルコピーなどを行いたい場合も、
そのまま「System32」を指定すると、SysWOW64フォルダを参照してしまいます。


(例:Delphi/400のConfiguration)

Delphi/400の「Configuration」も32bitのアプリケーションなので、DLL Informationタブで
「FULL NAME: C:\WINDOWS\SYSTEM32\~~~.DLL」と記載されたDLLがあった場合、
64bit端末においては実際のDLLはSystem32ではなく、SysWOW64フォルダに存在します。
(System32に同名のDLLが一部存在しますが、64bit用の別々のDLLです)

 

このような場合、代わりに「Sysnative」エイリアスを指定することで、
32bitのアプリケーションからでも64bit用のフォルダを指定できます。

// <例> ※64bit用のコマンドプロンプトを起動させる場合
ShellExecute(Handle, 'open', PChar('C:\windows\Sysnative\cmd.exe'), '', '', SW_SHOWDEFAULT);

※32bit端末では「Sysnative」エイリアスが存在しないため、
 従来通り「C:\Windows\System32」を対象とする必要があります。

 

これらを踏まえて、異なるbit数の端末が混在する環境では、
自端末のbit数を判断するためのロジックが別途必要になります。

例えば以下のようなロジックを使うことで、
動作しているWindowsが32bitか64bitかを判別することができます。
(※引用元:[ 822_コピーフック ] – Mr.XRAY

//-----------------------------------------------------------------------------
//  32ビットのWindowsか64ビットのWindowsかを調べる関数
//  64ビット版のWindowsの場合はTrueを返す
//-----------------------------------------------------------------------------
function Is64bitWindows: Boolean;
var
  Wow64Proc : function(hProcess: THandle; var Wow64: BOOL): BOOL stdcall;
  RetFlag   : LongBool;
begin
  // Windows Vista以上の場合
  @Wow64Proc := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'IsWow64Process');
  if @Wow64Proc <> nil then
  begin
    Wow64Proc(GetCurrentProcess, RetFlag);

    if SizeOf(THandle) = 4 then
    begin
      Result := RetFlag;
    end
    else
    if SizeOf(THandle) = 8 then
    begin
      Result := True;
    end;
  end
  else
  begin
    // Windows XPの場合、64ビット版か
    Result := CheckWin32Version(5, 2);
  end;
end;

 

※余談ですが、上記の経緯より64bit端末で「C:\Windows\Sysnative」というフォルダが
 本当に存在する場合、System32にリダイレクトされるため参照できません。

 

 

(Tipsメルマガ 2020年10月号より)