使用Process.Start()启动system32 \ winsat.exe时出现“找不到文件”错误

时间:2013-05-30 02:56:03

标签: c# process system.diagnostics wow64

我正在尝试使用以下代码运行Windows System Assessment Tool(winsat.exe):

System.Diagnostics.Process WinSPro =
    new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo WinSSInfo = 
    new System.Diagnostics.ProcessStartInfo();
WinSSInfo.FileName = "cmd.exe";
WinSSInfo.Arguments = "/k winsat.exe";
WinSPro.StartInfo = WinSSInfo;
WinSPro.Start();

如果我只调用cmd.exe,则此代码有效,即使我调用regedit.exe,它仍然有效。 但是,当我尝试将winsat.exe作为cmd.exe的参数调用时,它会失败。 命令提示符显示:

'winsat.exe' is not recognized as an internal or external command, 
operable program or batch file.

我尝试了几种方法来调用winsat.exe:

  1. 通过将"winsat.exe"分配给ProcessStartInfo.FileName来直接调用它。它失败了Win32ExceptionThe system cannot find the file specified

  2. 如上所述,使用完整路径 - @"c:\windows\system32\winsat.exe"。它失败并出现相同的错误。

  3. 以系统管理员身份运行代码。它仍然失败。

  4. 如编码示例中那样调用winsat.exe。它失败了,正如我之前解释的那样。

  5. 有趣的是,从代码启动的命令提示符只能在c:\ windows \ system32中看到.dll文件。

    有没有人知道为什么winsat.exe无法通过System.Diagnostics.Process启动?有没有我误解的限制?

    谢谢,

    雷克斯

2 个答案:

答案 0 :(得分:10)

使用Windows-on Windows 64-bit redirection重定向

winsat.exe。发生的事情是您的启动请求(来自32位进程)被重定向到%windir%\SysWOW64\winsat.exe。由于在64位安装上没有此特定可执行文件的32位版本,因此启动失败。要绕过此过程并允许32位进程访问本机(64位)路径,您可以改为引用%windir%\sysnative

Process WinSPro = new Process();
ProcessStartInfo WinSSInfo = new ProcessStartInfo();
WinSSInfo.FileName = @"c:\windows\sysnative\winsat.exe";
WinSPro.StartInfo = WinSSInfo;
WinSPro.Start();

或者,如果您将程序构建为x64,则可以将路径保留为c:\windows\system32

请注意,最好使用Environment.GetFolderPath来获取Windows目录的路径,以防操作系统安装在非标准位置:

WinSSInfo.FileName = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.Windows),
    @"sysnative\winsat.exe");

答案 1 :(得分:2)

基于SimonMᶜKenzie的answer以及他提供的链接(感谢soyuz的评论)我编写的方法应该适用于任何一种情况(只需复制/粘贴代码):< / p>

public static string GetSystem32DirectoryPath()
{
    string winDir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
    string system32Directory = Path.Combine(winDir, "system32");
    if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
    {
        // For 32-bit processes on 64-bit systems, %windir%\system32 folder
        // can only be accessed by specifying %windir%\sysnative folder.
        system32Directory = Path.Combine(winDir, "sysnative");
    }
    return system32Directory;
}

和启动流程的代码:

var pi = new ProcessStartInfo
{
    FileName = Path.Combine(GetSystem32DirectoryPath(), "winsat.exe"),
    CreateNoWindow = true,
    UseShellExecute = false
};
Process.Start(pi);