32 位应用程序如何在 Windows Vista 64 位上找到 64 位 Program Files 目录的位置?
我正在努力解决如何从 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()
传入启动用户会话进程的令牌来完成此操作。为了调用 CreateProcessAsUser
,我们通过 CreateEnvironmentBlock()
API 创建一个环境块。问题是 CreateEnvironmentBlock()
使用用户会话应用程序的令牌创建一个 ProgramW6432="C:\Program Files (x86)" 的块,这对于 64 位来说是一个问题应用程序。我们需要用适当的值覆盖它。
I'm struggling with a problem of how to determine the location of the 64-bit Program Files directory on 64-bit Windows Vista from a 32-bit application.
Calls to SHGetKnownFolderPath(FOLDERID_ProgramFilesX64)
do not return anything. The MSDN article KNOWNFOLDERID also states that this particular call with FOLDERID_ProgramFilesX64
is not supported for a 32-bit application.
I would like to avoid as much as possible hardcoding the path to "C:\Program Files".
Doing something like GetWindowsDirectory()
, extracting the drive from the return value and adding "\Program Files" to it is not appealing either.
How can a 32-bit application properly get the location of the folder from 64-bit Windows Vista?
Background
Our application has a service component which is supposed to launch other processes based on requests from user-session-specific component. The applications launched can be 32-bit or 64-bit. We do this is via CreateProcessAsUser()
by passing in a token from initiating user-session process. For call to CreateProcessAsUser
, we create an environment block via the CreateEnvironmentBlock()
API. The problem is that CreateEnvironmentBlock()
, using the token of the user-session application, creates a block with ProgramW6432="C:\Program Files (x86)", which is a problem for 64-bit applications. We need to override it with the proper value.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如您所提到的,从 32 位应用程序使用 SHGetKnownFolderPath 将无法在 64 位操作系统上运行。这是因为 Wow64 模拟已生效。
但是,您可以使用 RegOpenKeyEx 传入标志 < code>KEY_WOW64_64KEY 然后从注册表中读取程序文件目录。
注册表中的位置:
您对字符串值感兴趣:
As you mentioned, using SHGetKnownFolderPath from a 32-bit application will not work on a 64-bit operating system. This is because Wow64 emulation is in effect.
You can however use RegOpenKeyEx passing in the flag
KEY_WOW64_64KEY
and then read the program files directory from registry.The location in registry:
You are interested in the string value:
如果您仔细阅读该页面,您将看到 64 位操作系统上的 32 位应用程序支持 FOLDERID_ProgramFilesX64。 32 位操作系统不支持它,这是完全有道理的。
If you read that page carefully you will see that FOLDERID_ProgramFilesX64 is supported for 32 bits applications on a 64-bit OS. It's NOT supported on a 32-bit OS, which makes complete sense.
您还可以查询环境变量
ProgramW6432
。它显然只存在于64位Windows中,但它应该返回真正的64位Program Files目录,并且它似乎是为64位和32位程序定义的。至少它对我有用(C#,GetEnvironmentVariable
)...You can also query the environment variable
ProgramW6432
. It obviously exists only in 64-bit Windows, but it should return the real 64-bit Program Files directory, and it seems to be defined for both 64-bit and 32-bit programs. At least it worked for me (C#,GetEnvironmentVariable
)...MSDN 表示支持,但 Microsoft 的“WOW64”最佳实践文档表示不支持。请参阅 http://download .microsoft.com/download/A/F/7/AF7777E5-7DCD-4800-8A0A-B18336565F5B/wow64_bestprac.docx
引用:
在 Windows 7 x64 下,在 Visual Studio 调试器中运行 32 位应用程序时,我还得到返回代码 0x80070002(和 NULL 指针)。运行编译为 64 位的相同代码会返回值 S_OK,并且路径已正确填写。
我使用了上面列出的注册表 hack,因为我找不到任何其他解决方法。
MSDN says it is supported, but Microsoft's "WOW64" best practices document says it is not. See http://download.microsoft.com/download/A/F/7/AF7777E5-7DCD-4800-8A0A-B18336565F5B/wow64_bestprac.docx
To quote:
Under Windows 7 x64, running a 32-bit app in the Visual Studio debugger, I also get a return code of 0x80070002 (and a NULL pointer). Running the same code compiled as 64-bit returns the value S_OK and the path is properly filled in.
I've used the registry hack as listed above since I can't find any other workaround.