简体   繁体   English

如何从32位WOW进程获取Program Files文件夹路径(不是Program Files(x86))?

[英]How to get Program Files folder path (not Program Files (x86)) from 32bit WOW process?

I need to get the path to the native (rather than the WOW) program files directory from a 32bit WOW process. 我需要从32位WOW进程获取本机(而不是WOW)程序文件目录的路径。

When I pass CSIDL_PROGRAM_FILES (or CSIDL_PROGRAM_FILESX86) into SHGetSpecialFolderPath it returns the WOW (Program Files (x86)) folder path. 当我将CSIDL_PROGRAM_FILES(或CSIDL_PROGRAM_FILESX86)传递给SHGetSpecialFolderPath时,它返回WOW(Program Files(x86))文件夹路径。

I'd prefer to avoid using an environment variable if possible. 如果可能的话,我宁愿避免使用环境变量。

I want to compare some values I read from the registry, if the values point to the path of either the WOW or native version of my app then my code does something, if not it does something else. 我想比较一下我从注册表中读取的一些值,如果值指向我的应用程序的WOW或本机版本的路径,那么我的代码会执行某些操作,否则它会执行其他操作。 To figure out where the native and WOW versions of my app are expected to be I need to get the paths to "Program Files (x86)" and "Program Files". 要弄清楚我的应用程序的原生和WOW版本应该在哪里,我需要获得“Program Files(x86)”和“Program Files”的路径。

I appreciate all the help and, especially, the warnings in this thread. 我感谢所有的帮助,尤其是这个帖子中的警告。 However, I really do need this path and this is how I got it in the end: 但是,我确实需要这条路径,这就是我最终得到它的方式:

(error checking removed for clarity, use at your own risk, etc) (为清楚起见,错误检查已删除,使用风险由您自行承担,等等)

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

Let me quote Raymond Chen 's excellent blogpost on the issue: 让我引用Raymond Chen关于这个问题的优秀博文

On 64-bit Windows, 32-bit programs run in an emulation layer. 在64位Windows上,32位程序在仿真层中运行。 This emulation layer simulates the x86 architecture, virtualizing the CPU, the file system, the registry, the environment variables, the system information functions, all that stuff. 此仿真层模拟x86架构,虚拟化CPU,文件系统,注册表,环境变量,系统信息功能,以及所有这些功能。 If a 32-bit program tries to look at the system, it will see a 32-bit system. 如果32位程序试图查看系统,它将看到一个32位系统。 For example, if the program calls the GetSystemInfo function to see what processor is running, it will be told that it's running on a 32-bit processor, with a 32-bit address space, in a world with a 32-bit sky and 32-bit birds in the 32-bit trees. 例如,如果程序调用GetSystemInfo函数来查看正在运行的处理器,它将被告知它运行在具有32位地址空间的32位处理器上,在具有32位天空和32位的世界中32位树中的鸟类。

And that's the point of the emulation: To keep the 32-bit program happy by simulating a 32-bit execution environment. 这就是仿真的重点:通过模拟32位执行环境来保持32位程序的快乐。

... ...

The question is "What is the way of finding the x64 Program Files directory from a 32-bit application?" 问题是“从32位应用程序中查找x64 Program Files目录的方法是什么?”

The answer is " It is better to work with the system than against it. " If you're a 32-bit program, then you're going to be fighting against the emulator each time you try to interact with the outside world. 答案是“ 使用系统比使用系统更好。 ”如果你是一个32位程序,那么每次你尝试与外界交互时,你都会与模拟器作斗争。 Instead, just recompile your installer as a 64-bit program. 相反,只需将安装程序重新编译为64位程序即可。 Have the 32-bit installer detect that it's running on a 64-bit system and launch the 64-bit installer instead. 让32位安装程序检测到它在64位系统上运行并启动64位安装程序。 The 64-bit installer will not run in the 32-bit emulation layer, so when it tries to copy a file or update a registry key, it will see the real 64-bit file system and the real 64-bit registry. 64位安装程序不会在32位仿真层中运行,因此当它尝试复制文件或更新注册表项时,它将看到真正的64位文件系统和真正的64位注册表。

If you still want to do this, I recommend reading the comments on this blogpost as they contain some good hints. 如果您仍想这样做,我建议您阅读此博客帖子上的评论,因为它们包含一些很好的提示。

You're on the right path - Use the KNOWNFOLDERID of FOLDERID_ProgramFilesX64 你在正确的道路上 - 使用FOLDERID_ProgramFilesX64的KNOWNFOLDERID

The SHGetKnownFolderPath function can be used to retrieve the full path of a given KnownFolder. SHGetKnownFolderPath函数可用于检索给定KnownFolder的完整路径。

I needed it to get the x64 Program Folder from a Logonscript and used: 我需要它从Logonscript获取x64程序文件夹并使用:

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

WScript.Echo sProgramDirPath

This is almost certainly a bad idea, according to a recent-ish post by the infamous Raymond Chen. 据臭名昭着的雷蒙德·陈(Raymond Chen)最近发布的帖子称,这几乎肯定是一个坏主意。 See here for details. 详情请见此处 Bottom line, I think it can be done, but it's a lot of hard work and there's almost certainly an easier way. 最重要的是,我认为可以做到,但这是一项艰苦的工作,几乎可以肯定是一种更简单的方法。

Microsoft built the WOW emulation layer to make your life easier. Microsoft构建了WOW仿真层,让您的生活更轻松。 Don't waste all their time and effort by fighting it :-). 不要浪费所有的时间和精力来打击它:-)。

Perhaps if you told us why you need the non-WOW Program Files directory, we could assist further. 也许如果你告诉我们为什么你需要非WOW Program Files目录,我们可以进一步提供帮助。

The best and universal way to get path to "Program Files", is to query it from the registry: 获取“程序文件”路径的最佳和通用方法是从注册表中查询它:

64-Bit-Process can query: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ProgramFilesDir to get "C:\\Program Files" HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\ProgramFilesDir to get "C:\\Program Files (x86)" 64位进程可以查询: HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ Windows \\ CurrentVersion \\ ProgramFilesDir 获取“C:\\ Program Files” HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Wow6432Node \\ Microsoft \\ Windows \\ CurrentVersion \\ ProgramFilesDir 获取“C:\\ Program Files( 86)”

32-Bit-Process (Wow64) can query: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ProgramFilesDir to get "C:\\Program Files (x86)" HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ProgramFilesDir with KEY_WOW64_64KEY option! 32位进程(Wow64)可以查询: HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ Windows \\ CurrentVersion \\ ProgramFilesDir 以获取“C:\\ Program Files(x86)” HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ Windows \\ CurrentVersion \\ ProgramFilesDir以及KEY_WOW64_64KEY选项! to get "C:\\Program Files" 得到“C:\\ Program Files”

Pseudo-code: 伪代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在64位x86环境中编译32位x86应用程序? - How to compile 32bit x86 application in 64bit x86 environment? C++ | 如何删除位于 (C:\Program Files (x86)) 的文件夹中的文件 - C++ | How can i delete files in a folder located in (C:\Program Files (x86)) 为什么编译64位程序时CMake默认为Program Files x86? - Why does CMake default to Program Files x86 when compiling 64 bit program? 从32位程序启动64位进程 - Launching 64bit process from 32bit program 32 位 x86 上的 64 位 int 算术(来自 c ) - 64 bit int arthimetic on 32bit x86 (from c ) Qt可执行文件在发行文件夹中运行-程序文件(x86)中的运行时错误 - Qt executable running in release folder - Runtime error in Program Files (x86) 在Windows中是否有一个简单的C ++程序文件/程序文件(x86)指令? - Is there a simple Program Files/Program Files (x86) directive for C++ in windows? 使用g ++将32位和64位.so文件链接到c ++程序 - Linking both 32bit and 64bit .so files with g++ for a c++ program 我在笔记本电脑上找不到文件夹C:\\ Program Files(x86)\\ Microsoft Visual Studio 14.0 \\ VC \\ include \\ gl。 如何添加? - I cannot find the folder C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\gl on my laptop. How do I add it? 在64位(或32位)Windows上以32位进程访问> 2,3,4GB文件 - Accessing >2,3,4GB Files in 32bit Process on 64bit (or 32bit) Windows
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM