9

32 ビット アプリケーションから 64 ビット Windows Vista 上の 64 ビット Program Files ディレクトリの場所を特定する方法の問題に苦しんでいます。

を呼び出してSHGetKnownFolderPath(FOLDERID_ProgramFilesX64)も何も返されません。MSDNの記事KNOWNFOLDERIDにも、この特定の呼び出しFOLDERID_ProgramFilesX64は 32 ビット アプリケーションではサポートされていないと記載されています。

「C:\Program Files」へのパスをハードコーディングすることはできるだけ避けたいと思います。のようなことGetWindowsDirectory()をして、戻り値からドライブを抽出し、それに「\Program Files」を追加するのも魅力的ではありません。

32 ビット アプリケーションが 64 ビット Windows Vista からフォルダの場所を正しく取得するにはどうすればよいですか?

バックグラウンド

私たちのアプリケーションには、ユーザーセッション固有のコンポーネントからのリクエストに基づいて他のプロセスを起動するサービスコンポーネントがあります。起動するアプリケーションは、32 ビットまたは 64 ビットにすることができます。これはCreateProcessAsUser()、ユーザー セッション プロセスの開始からトークンを渡すことによって行います。への呼び出しのために、 APICreateProcessAsUserを介して環境ブロックを作成します。CreateEnvironmentBlock()問題はCreateEnvironmentBlock()、ユーザー セッション アプリケーションのトークンを使用して、ProgramW6432="C:\Program Files (x86)" でブロックを作成することです。これは 64 ビット アプリケーションの問題です。適切な値でオーバーライドする必要があります。

4

4 に答える 4

9

ご指摘のとおり、32 ビット アプリケーションから SHGetKnownFolderPath を使用しても、64 ビット オペレーティング システムでは機能しません。これは、Wow64 エミュレーションが有効になっているためです。

ただし、フラグを渡すRegOpenKeyExKEY_WOW64_64KEYを使用して、レジストリからプログラム ファイル ディレクトリを読み取ることができます。

レジストリ内の場所:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

あなたは文字列値に興味があります:

ProgramFilesDir

于 2009-12-24T17:08:39.007 に答える
1

環境変数を照会することもできますProgramW6432。明らかに 64 ビット Windows にしか存在しませんが、実際の 64 ビット Program Files ディレクトリを返す必要があり、64 ビット プログラムと 32 ビット プログラムの両方に対して定義されているようです。少なくとも私にとってはうまくいきました(C#、GetEnvironmentVariable)...

于 2014-08-19T21:36:12.753 に答える
1

そのページを注意深く読むと、FOLDERID_ProgramFilesX64 が 64 ビット OS 上の 32 ビット アプリケーションでサポートされていることがわかります。32 ビット OS ではサポートされていません。これは完全に理にかなっています。

于 2009-12-24T16:23:23.433 に答える
0

FOLDERID_ProgramFilesX64 がサポートされています...

MSDN はサポートされていると述べていますが、Microsoft の "WOW64" ベスト プラクティス ドキュメントはサポートされていないと述べています。http://download.microsoft.com/download/A/F/7/AF7777E5-7DCD-4800-8A0A-B18336565F5B/wow64_bestprac.docxを参照してください。

引用するには:

• 一部の変数は、プロセスが 64 ビットの場合にのみ機能します。たとえば、FOLDERID_ProgramFilesX64 は 32 ビットの呼び出し元では機能しません。Windows 7 より前のバージョンの Windows では、%ProgramW6432% は 32 ビット プロセスのコンテキストでは機能しませんでした。アプリケーションは、これらの変数を使用する前に、64 ビット プロセスで実行されているかどうかを判断する必要があります。

Windows 7 x64 で、Visual Studio デバッガーで 32 ビット アプリを実行すると、リターン コード 0x80070002 (および NULL ポインター) も返されます。64 ビットとしてコンパイルされた同じコードを実行すると、値 S_OK が返され、パスが正しく入力されます。

他の回避策が見つからないため、上記のレジストリ ハックを使用しました。

于 2010-07-28T20:14:11.887 に答える