c++ - 为什么 ShellExecute 找不到文件?

标签 c++ c windows winapi

作为来自 *nix 世界的人,我对 Windows 行为及其安全系统感到非常困惑。

我只是想在我的应用程序中执行一个外部程序。我发现 WinAPI 函数 ShellExecute 可以按预期工作,但启动位于 %windir%\System32 子目录中的一些程序时除外。

  • ping.exe执行成功

    ShellExecute(NULL, "open", "c:\\Windows\\System32\\ping.exe', NULL, NULL, SW_SHOW) );
    // ^^^ OK, retcode == 42
    
  • java.exe执行失败

    ShellExecute(NULL, "open", "c:\\Windows\\System32\\java.exe', NULL, NULL, SW_SHOW) );
    // ^^^ ERROR_FILE_NOT_FOUND, retcode == 2
    

很奇怪,因为java.exe在System32中确实存在,对Users组有读/执行权限,可以从cmd调用。

C:\>dir /q c:\Windows\System32\java.exe
 Volume in drive C has no label.
 Volume Serial Number is 56E3-0868

 Directory of c:\Windows\System32

11.01.2012  23:40           172 320 NT AUTHORITY\SYSTEM    java.exe
               1 File(s)        172 320 bytes
               0 Dir(s)  226 127 564 800 bytes free

C:\>cacls c:\Windows\System32\java.exe
c:\Windows\System32\java.exe NT AUTHORITY\SYSTEM:F
                             BUILTIN\Administrators:F
                             BUILTIN\Users:R

我在这里错过了什么?

操作系统是 Windows 7 家庭版。

更新:如果我将 c:\Windows\Sytem32\calc.exe 复制到 c:\Windows\Sytem32\calc2.exe,ShellExecute 可以运行原始 calc.exe 但失败calc2.exe 虽然文件是相同的!! 唯一的区别是缺少 calc2.exe 和 java.exe 的 TrustedInstaller 组的附加权限。巧合?

最佳答案

您运行的是 64 位操作系统吗?

如果是这样,C:\Windows\System32 将包含 64 位二进制文​​件,而 C:\Windows\SysWOW64 将包含 32 位二进制文​​件(是的,确实是方式)。出于向后兼容的原因,当运行 32 位进程时,Windows 会将对 C:\Windows\System32 的访问重定向到 C:\Windows\SysWOW64

因此,如果您使用 32 位进程查看 C:\Windows\System32,您实际上看到的是 C:\Windows\SysWOW64 中的内容.

您可以调用Wow64DisableWow64FsRedirection功能来禁用此行为。请注意文档中的警告并仔细考虑它是否适用于您的情况:

Note: The Wow64DisableWow64FsRedirection function affects all file operations performed by the current thread, which can have unintended consequences if file system redirection is disabled for any length of time. For example, DLL loading depends on file system redirection, so disabling file system redirection will cause DLL loading to fail. Also, many feature implementations use delayed loading and will fail while redirection is disabled. The failure state of the initial delay-load operation is persisted, so any subsequent use of the delay-load function will fail even after file system redirection is re-enabled. To avoid these problems, disable file system redirection immediately before calls to specific file I/O functions (such as CreateFile) that must not be redirected, and re-enable file system redirection immediately afterward using Wow64RevertWow64FsRedirection.

关于c++ - 为什么 ShellExecute 找不到文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8837059/

相关文章:

C 内存管理 -> 队列

c - 为什么在这次缓冲区溢出尝试中 eip 没有改变?

windows - WMI 不返回 Windows 7 64 上的所有安装程序

c++ - 当存储在 std::vector 属性中时,我可以删除析构函数中的指针吗?

c++ - 多态对象的容器

c - 为什么 mpirun 不尊重我对 BTL 的选择?

c++ - 在没有 WndProc 的情况下运行 win32 事件循环的不同方式的想法?

python - 使用 pywin32 获取 GUIThreadInfo()

c++ - 如何在 C++ 中返回没有模板的泛型类型?

c++ - 在 std::function 中调用递归函数