简体   繁体   English

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

[英]“File not found” error launching system32\winsat.exe using Process.Start()

I'm trying to run the Windows System Assessment Tool (winsat.exe) using the following code: 我正在尝试使用以下代码运行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();

This code works if I only call cmd.exe, and even if I call regedit.exe it still works. 如果我只调用cmd.exe,这个代码有效,即使我调用regedit.exe它仍然有效。 However, when I try to call winsat.exe as a argument of cmd.exe, it fails. 但是,当我尝试将winsat.exe作为cmd.exe的参数调用时,它会失败。 The command prompt shows this: 命令提示符显示:

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

I tried several ways to call winsat.exe: 我尝试了几种方法来调用winsat.exe:

  1. Call it directly by assigning "winsat.exe" to ProcessStartInfo.FileName . 通过将"winsat.exe"分配给ProcessStartInfo.FileName直接调用它。 It fails with a Win32Exception : The system cannot find the file specified 它因Win32Exception The system cannot find the file specified失败: The system cannot find the file specified

  2. As above, using the full path - @"c:\\windows\\system32\\winsat.exe" . 如上所述,使用完整路径 - @"c:\\windows\\system32\\winsat.exe" It fails with the same error. 它失败并出现同样的错误。

  3. Run the code as the System Administrator. 以系统管理员身份运行代码。 It still fails. 它仍然失败。

  4. Call winsat.exe as in the coded example. 如编码示例中那样调用winsat.exe。 It failed as I explained earlier. 它像我之前解释的那样失败了。

It's interesting that the command prompt launched from the code can only see .dll files in c:\\windows\\system32. 有趣的是,从代码启动的命令提示符只能在c:\\ windows \\ system32中看到.dll文件。

Does anyone have any idea why winsat.exe cannot be launched through System.Diagnostics.Process ? 有谁知道为什么winsat.exe无法通过System.Diagnostics.Process启动? Are there any limitations which I've misunderstood? 有没有我误解的限制?

Thanks, 谢谢,

Rex 雷克斯

winsat.exe is redirected using Windows-on Windows 64-bit redirection . 使用Windows-on Windows 64位重定向重定向 winsat.exe What's happening is that your launch request (from a 32-bit process) is being redirected to %windir%\\SysWOW64\\winsat.exe . 发生的事情是您的启动请求(来自32位进程)被重定向到%windir%\\SysWOW64\\winsat.exe Since there's no 32-bit version of this particular executable on 64-bit installs, the launch fails. 由于在64位安装上没有此特定可执行文件的32位版本,因此启动失败。 To bypass this process and allow your 32-bit process to access the native (64-bit) path, you can reference %windir%\\sysnative instead: 要绕过此过程并允许32位进程访问本机(64位)路径,您可以引用%windir%\\sysnative

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

Alternatively, if you build your program as x64, you can leave the path as c:\\windows\\system32 . 或者,如果您将程序构建为x64,则可以将路径保留为c:\\windows\\system32

Note that it's best to use Environment.GetFolderPath to get the path to the windows directory, just in case the OS is installed in a non-standard location: 请注意,最好使用Environment.GetFolderPath来获取Windows目录的路径,以防操作系统安装在非标准位置:

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

Based on Simon MᶜKenzie's answer , and the link he provided (thanks to soyuz for his comment) I wrote method that should work in either cases (to just copy/paste the code): 基于SimonMᶜ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;
}

and code to launch the process: 以及启动该过程的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM