32ビットアプリケーションは、Windows Vista 64ビットの64ビットプログラムファイルディレクトリの場所をどのように見つけることができますか?
-
21-09-2019 - |
質問
32ビットアプリケーションから64ビットWindows Vistaの64ビットプログラムファイルディレクトリの場所を決定する方法の問題に苦労しています。
通話 SHGetKnownFolderPath(FOLDERID_ProgramFilesX64)
何も返さないでください。 MSDN 論文 既知のfolderid また、この特定の呼び出しがあると述べています FOLDERID_ProgramFilesX64
32ビットアプリケーションではサポートされていません。
パスを「C:プログラムファイル」へのパスをハードコードすることを可能な限り避けたいと思います。のようなことをしています GetWindowsDirectory()
, 、ドライブを返品値から抽出し、「プログラムファイル」を追加することも魅力的ではありません。
32ビットアプリケーションは、64ビットWindows Vistaからフォルダーの場所を適切に取得するにはどうすればよいですか?
バックグラウンド
当社のアプリケーションには、ユーザーセッション固有のコンポーネントからのリクエストに基づいて他のプロセスを起動することになっているサービスコンポーネントがあります。起動されたアプリケーションは、32ビットまたは64ビットにすることができます。これを行います CreateProcessAsUser()
ユーザーセッションプロセスの開始からトークンを渡すことにより。通話用 CreateProcessAsUser
, 、介して環境ブロックを作成します CreateEnvironmentBlock()
API。問題はそれです CreateEnvironmentBlock()
, 、ユーザーセッションアプリケーションのトークンを使用して、ProgramW6432 = "C: Program Files(x86)"を備えたブロックを作成します。これは、64ビットアプリケーションの問題です。適切な値でオーバーライドする必要があります。
解決
あなたが言ったように、32ビットアプリケーションからShgetKnownFolderPathを使用しても、64ビットオペレーティングシステムでは機能しません。これは、WOW64エミュレーションが有効であるためです。
ただし、使用できます regopenkeyex 旗を渡す KEY_WOW64_64KEY
次に、レジストリからプログラムファイルディレクトリを読み取ります。
レジストリの場所:
hkey_local_machine software microsoft windows currentversion
あなたは文字列値に興味があります:
ProgramFilesDir
他のヒント
そのページを注意深く読むと、FolderID_Programfilesx64が64ビットOSの32ビットアプリケーションでサポートされていることがわかります。 32ビットOSではサポートされていません。これは完全に理にかなっています。
folderid_programfilesx64がサポートされています...
MSDNはそれがサポートされていると言いますが、Microsoftの「Wow64」のBest Practices Documentはそうではないと言います。見る http://download.microsoft.com/download/a/f/7/af7777e5-7dcd-4800-8a0a-b18336565f5b/wow64_bestprac.docx
引用する:
•一部の変数は、プロセスが64ビットの場合にのみ機能します。たとえば、FolderID_Programfilesx64は32ビット発信者では機能しません。 Windows 7より前のWindowsのバージョンでは、32ビットプロセスのコンテキストでは%プログラムWIDW6432%が機能しませんでした。アプリケーションは、これらの変数を使用する前に64ビットプロセスで実行されているかどうかを判断する必要があります。
Windows 7 X64の下で、Visual Studio Debuggerで32ビットアプリを実行しているため、0x80070002(およびNull Pointer)の返品コードも取得します。 64ビットとコンパイルされた同じコードを実行すると、値が値を返し、パスが適切に記入されます。
他の回避策が見つからないため、上記のようにレジストリハックを使用しました。
環境変数を照会することもできます ProgramW6432
. 。明らかに64ビットのウィンドウにのみ存在しますが、実際の64ビットプログラムファイルディレクトリを返すはずであり、64ビットプログラムと32ビットプログラムの両方で定義されているようです。少なくともそれは私のために働いた(C#、 GetEnvironmentVariable
)...