【问题标题】:How can 32-bit application find the location of 64-bit Program Files directory on Windows Vista 64-bit?32 位应用程序如何在 64 位 Windows Vista 上找到 64 位 Program Files 目录的位置?
【发布时间】:2010-12-29 20:31:41
【问题描述】:

我正在努力解决如何从 32 位应用程序确定 64 位 Windows Vista 上 64 位 Program Files 目录的位置的问题。

调用SHGetKnownFolderPath(FOLDERID_ProgramFilesX64) 不会返回任何内容。 MSDN 文章 KNOWNFOLDERID 还指出,32 位应用程序不支持使用 FOLDERID_ProgramFilesX64 进行此特定调用。

我想尽可能避免硬编码到“C:\Program Files”的路径。 像GetWindowsDirectory() 这样的操作,从返回值中提取驱动器并将“\Program Files”添加到其中也没有吸引力。

32 位应用程序如何从 64 位 Windows Vista 中正确获取文件夹的位置?

背景

我们的应用程序有一个服务组件,它应该根据来自用户会话特定组件的请求启动其他进程。启动的应用程序可以是 32 位或 64 位。我们通过CreateProcessAsUser() 传递来自启动用户会话过程的令牌来做到这一点。为了调用CreateProcessAsUser,我们通过CreateEnvironmentBlock() API 创建一个环境块。问题是CreateEnvironmentBlock() 使用用户会话应用程序的令牌创建了一个带有 ProgramW6432="C:\Program Files (x86)" 的块,这对于 64 位应用程序来说是个问题。我们需要用适当的值覆盖它。

【问题讨论】:

  • 出于好奇.. 为什么?如果你是一个在 64 位上运行的 32 位程序,那么你不需要知道 64 位程序文件目录的位置,你应该使用返回给你的那个,它是这样的:C:\Program Files (x86)

标签: 32bit-64bit vista64


【解决方案1】:

正如您所提到的,在 32 位应用程序中使用 SHGetKnownFolderPath 将无法在 64 位操作系统上运行。这是因为 Wow64 仿真有效。

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

注册表中的位置:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

你对字符串值感兴趣:

程序文件目录

【讨论】:

  • 感谢您的回答布赖恩,这有效。感谢您的帮助
  • 谢谢,这对于 32 位应用程序很有用,例如前端控制可以处理文件的服务,例如从 32 位 UI 添加 64 位程序文件作为扫描仪目标
  • 64位程序文件还有一个特殊的环境变量——不需要直接从注册表中读取。但至少我现在知道如何在 Wow6432Node 之外访问注册表 :)
【解决方案2】:

如果您仔细阅读该页面,您会发现 64 位操作系统上的 32 位应用程序支持 FOLDERID_ProgramFilesX64。它在 32 位操作系统上不受支持,这是完全合理的。

【讨论】:

  • 该页面的官方部分声明它适用于 64 位操作系统。然而,在页面底部有一条评论(我假设它在那里,因为微软没有拒绝它),说对于 32 位调用者,该方法成功但不返回任何内容。是的,我从 32 位调用者尝试过,没有返回路径(错误代码 0x80070002)。环境变量 %ProgramW6432% 也不会从 32 位应用程序扩展。
  • MSDN 中的表格已更新,表明它不适用于在 64 位操作系统上运行的 32 位程序。他们实际上回应了 cmets!
【解决方案3】:

您也可以查询环境变量ProgramW6432。它显然只存在于 64 位 Windows 中,但它应该返回真正的 64 位 Program Files 目录,而且它似乎是为 64 位和 32 位程序定义的。至少它对我有用(C#,GetEnvironmentVariable)...

【讨论】:

【解决方案4】:

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

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

【讨论】:

  • 看我的回答。无需读取 64 位注册表 - 还有一个名为 ProgramW6432 的环境变量可用于 64 位 Windows 中的 32 位和 64 位进程。使用它来获取真正的 64 位程序文件路径。
猜你喜欢
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
相关资源
最近更新 更多