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 を呼び出しても機能します。しかし、cmd.exe の引数として winsat.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.exeWindows-on Windows 64-bit リダイレクトを使用してリダイレクトされます。何が起こっているかというと、(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.GetFolderPathOS が非標準の場所にインストールされている場合に備えて、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 に答える