32 位应用程序如何在 Windows Vista 64 位上找到 64 位 Program Files 目录的位置?

发布于 2024-08-16 18:04:12 字数 974 浏览 7 评论 0原文

我正在努力解决如何从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

左岸枫 2024-08-23 18:04:12

正如您所提到的,从 32 位应用程序使用 SHGetKnownFolderPath 将无法在 64 位操作系统上运行。这是因为 Wow64 模拟已生效。

但是,您可以使用 RegOpenKeyEx 传入标志 < code>KEY_WOW64_64KEY 然后从注册表中读取程序文件目录。

注册表中的位置:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

您对字符串值感兴趣:

程序文件目录

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:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

You are interested in the string value:

ProgramFilesDir

温柔少女心 2024-08-23 18:04:12

如果您仔细阅读该页面,您将看到 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.

九八野马 2024-08-23 18:04:12

您还可以查询环境变量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)...

时光是把杀猪刀 2024-08-23 18:04:12

支持 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,并且路径已正确填写。

我使用了上面列出的注册表 hack,因为我找不到任何其他解决方法。

FOLDERID_ProgramFilesX64 is supported...

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:

• Some variables work only if the process is 64-bit.
For example, FOLDERID_ProgramFilesX64 does not work for 32-bit callers. In versions of Windows earlier than Windows 7, %ProgramW6432% did not work in the context of 32-bit processes. An application must determine whether it is running in a 64-bit process before it uses these variables.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文