为什么ShellExecute找不到文件?

从一个* 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 /qc:\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失败,尽pipe文件是相同的! 唯一的区别是对于缺lesscalc2.exe和java.exe的TrustedInstaller组的附加权限。 巧合 ?

Solutions Collecting From Web of "为什么ShellExecute找不到文件?"

你正在运行一个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函数来禁用此行为。 请注意文档中的警告,并仔细考虑它是否适用于您的案例:

注意: Wow64DisableWow64FsRedirection函数会影响当前线程执行的所有文件操作,如果文件系统重定向在任何时间长度内都被禁用,则可能会产生意想不到的后果。 例如,DLL加载取决于文件系统重定向,因此禁用文件系统重定向将导致DLL加载失败。 此外,许多功能实现使用延迟加载,并将禁用重定向时失败。 初始延迟加载操作的故障状态将持续存在,因此即使在重新启用文件系统重定向后,后续使用延迟加载功能也将失败。 为避免这些问题,请在调用特定的文件I / O函数(如CreateFile )之前立即禁用文件系统重定向,然后使用Wow64RevertWow64FsRedirection立即重新启用文件系统重定向。

使用ProcessMonitor来确定哪些文件正在被访问,哪些文件操作失败以及为什么。

检查环境设置,例如“PATH”。 Windows为系统和用户保留一个单独的环境。 Java.exe所需的DLL可能只在一个环境中列出,当您通过ShellExecute运行它时,它正在使用其他环境。