6

我正在尝试使用以下代码运行Windows 系统评估工具(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' 未被识别为内部或外部命令,
可运行的程序或批处理文件。

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

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

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

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

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

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

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

谢谢,

雷克斯

4

2 回答 2

12

winsat.exe使用Windows-on Windows 64-bit redirection 进行重定向。发生的事情是您的启动请求(来自 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");
于 2013-05-30T03:56:33.050 回答
2

根据 Simon MᶜKenzie 的回答,以及他提供的链接(感谢soyuz的评论),我编写了适用于任何一种情况的方法(只需复制/粘贴代码):

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);
于 2014-06-26T09:21:39.280 回答