【问题标题】:How to get Program Files folder path (not Program Files (x86)) from 32bit WOW process?如何从 32 位 WOW 进程中获取 Program Files 文件夹路径(不是 Program Files (x86))?
【发布时间】:2009-01-14 23:52:01
【问题描述】:

我需要从 32 位 WOW 进程中获取到本机(而不是 WOW)程序文件目录的路径。

当我将 CSIDL_PROGRAM_FILES(或 CSIDL_PROGRAM_FILESX86)传递到 SHGetSpecialFolderPath 时,它会返回 WOW(Program Files (x86))文件夹路径。

如果可能,我宁愿避免使用环境变量。

我想比较我从注册表中读取的一些值,如果这些值指向我的应用程序的 WOW 或本机版本的路径,那么我的代码会执行某些操作,否则它会执行其他操作。 为了弄清楚我的应用程序的原生版本和 WOW 版本应该在哪里,我需要获取“Program Files (x86)”和“Program Files”的路径。

【问题讨论】:

  • 你不应该依赖于你的程序“预期在哪里”。应用程序是用户想要它们的地方。小型 SSD 变得越来越流行,它们将为许多 PC 添加额外的安装位置。
  • 完全可以,但在这种情况下,它确实会在程序文件文件夹中。
  • 对我来说,为什么要更新 Chrome 的扩展列表,它可能位于 AppData、Program Files (x86) 或 Program Files 中。 (当然,Program Files 的名称可以是其他名称。)

标签: c++ windows 64-bit


【解决方案1】:

感谢所有帮助,尤其是此线程中的警告。但是,我确实需要这条路,这就是我最终得到它的方式:

(为了清楚起见,删除了错误检查,使用风险自负等)

WCHAR szNativeProgramFilesFolder[MAX_PATH];
ExpandEnvironmentStrings(L"%ProgramW6432%", 
                       szNativeProgramFilesFolder, 
                       ARRAYSIZE(szNativeProgramFilesFolder);

【讨论】:

  • 谢谢!在特殊情况下,我正是需要这个。
【解决方案2】:

让我引用 Raymond Chenexcellent blogpost 关于这个问题:

在 64 位 Windows 上,32 位程序运行 在仿真层。这个仿真 层模拟x86架构, 虚拟化 CPU、文件系统、 注册表,环境 变量,系统信息 功能,所有这些东西。如果是 32 位 程序试图查看系统, 它将看到一个 32 位系统。为了 例如,如果程序调用 GetSystemInfo 函数看看什么 处理器正在运行,它会被告知 它在 32 位上运行 处理器,具有 32 位地址 空间,在一个拥有 32 位天空的世界中 和 32 位树中的 32 位鸟。

这就是仿真的重点: 为了让 32 位程序满意 模拟 32 位执行 环境。

...

问题是“什么是 查找 x64 程序文件 来自 32 位应用程序的目录?”

答案是“工作更好 支持系统而不是反对系统。" 如果 你是一个 32 位程序,那么你是 将与 每次尝试交互时的模拟器 与外界。相反,只是 将安装程序重新编译为 64 位 程序。有 32 位安装程序 检测到它在 64 位上运行 系统并启动 64 位安装程序 反而。 64 位安装程序不会 在 32 位仿真层中运行,所以 当它试图复制文件或更新时 一个注册表项,它将看到真实的 64位文件系统和真正的64位 注册表。

如果您仍想这样做,我建议您阅读这篇博文中的 cmets,因为它们包含一些很好的提示。

【讨论】:

  • 从 32b 程序获取 64b ProgFiles 的一个完全合法的用例是当它试图备份您的计算机但想要忽略程序文件时。当然你也想忽略 64b Program Files 文件夹。
【解决方案3】:

您走在正确的道路上 - 使用 FOLDERID_ProgramFilesX64 的 KNOWNFOLDERID

SHGetKnownFolderPath 函数可用于检索给定 KnownFolder 的完整路径。

【讨论】:

  • 这不是只有在 Vista 或更高版本上可用吗?当 codde 在 Vista 之前的 Windows 上调用它时会发生什么?
  • 我刚刚遇到了这个问题,我也需要它在 XP 和 Server 2003 x64 上工作。
  • SHGetKnownFolderPath 和 FOLDERID_ProgramFilesX64 不适用于 32 位版本的 Windows。它被记录为工作,但不幸的是,它实际上并没有工作。请参阅此处的社区内容部分:msdn.microsoft.com/en-us/library/bb762584%28VS.85%29.aspx
【解决方案4】:

根据臭名昭著的 Raymond Chen 最近的一篇帖子,这几乎可以肯定是个坏主意。有关详细信息,请参阅here。归根结底,我认为这是可以做到的,但这是一项艰巨的工作,而且几乎可以肯定有更简单的方法。

Microsoft 构建了 WOW 仿真层,让您的生活更轻松。不要浪费他们所有的时间和精力来对抗它:-)。

也许如果您告诉我们为什么您需要非 WOW Program Files 目录,我们可以提供进一步的帮助。

【讨论】:

    【解决方案5】:

    我需要它从 Logonscript 中获取 x64 程序文件夹并使用:

    Dim oWshShell : Set oWshShell = CreateObject("WScript.Shell")
    Dim sProgramDirPath : sProgramDirPath = 
        oWshShell.ExpandEnvironmentStrings("%ProgramW6432%")
    
    WScript.Echo sProgramDirPath
    

    【讨论】:

      【解决方案6】:

      获取“程序文件”路径的最佳和通用方法是从注册表中查询它:

      64-Bit-Process 可以查询: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir 获取“C:\Program Files” HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ProgramFilesDir 获取“C:\Program Files (x86)”

      32-Bit-Process (Wow64) 可以查询: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir 获取“C:\Program Files (x86)” HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir 带有 KEY_WOW64_64KEY 选项! 获取“C:\Program Files”

      伪代码:

      OpenKey(hKey, HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", KEY_READ | KEY_WOW64_64KEY);
      QueryStringValue(hKey, L"ProgramFilesDir", sValue);
      

      【讨论】:

      • 您应该使用 API 函数来获取位置:SHGetFolderPath 或 ExpandEnvironmentStrings。
      • 如果注册表项在 Windows 9 中发生变化怎么办?
      猜你喜欢
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-21
      • 2021-11-08
      • 2010-10-19
      相关资源
      最近更新 更多