“未找到文件”;使用Process.Start()启动system32winsat.exe时出错

本文关键字:Start 启动 system32winsat 出错 exe Process 使用 文件 未找到文件 | 更新日期: 2023-09-27 18:16:13

我正在尝试使用以下代码运行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直接调用。Win32Exception: The 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启动吗?有没有什么限制我误解了?

谢谢,

雷克斯

“未找到文件”;使用Process.Start()启动system32winsat.exe时出错

winsat.exe使用Windows-on Windows 64位重定向进行重定向。发生的事情是,您的启动请求(来自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");

根据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);