1. ホーム
  2. c#

[解決済み] C#でバッチファイルを実行する

2022-04-26 14:16:02

質問

C#でバッチファイルを実行しようとしているのですが、うまくいきません。

インターネット上でそれを行う複数の例を見つけましたが、私の場合はうまくいきません。

public void ExecuteCommand(string command)
{
    int ExitCode;
    ProcessStartInfo ProcessInfo;
    Process Process;

    ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
    ProcessInfo.CreateNoWindow = true;
    ProcessInfo.UseShellExecute = false;

    Process = Process.Start(ProcessInfo);
    Process.WaitForExit();

    ExitCode = Process.ExitCode;
    Process.Close();

    MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
}

コマンド文字列には、バッチファイルの名前 ( system32 と、操作するファイルを指定します。(例 txtmanipulator file1.txt file2.txt file3.txt ). バッチファイルを手動で実行すると、正常に動作します。

コードを実行すると **ExitCode: 1** (Catch all for general errors)

何が間違っているのでしょうか?

どうすればいいですか?

これでうまくいくはずです。何が起こっているのかを知るために、出力ストリームとエラーストリームの内容をダンプアウトしてみてください。

static void ExecuteCommand(string command)
{
    int exitCode;
    ProcessStartInfo processInfo;
    Process process;

    processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
    processInfo.CreateNoWindow = true;
    processInfo.UseShellExecute = false;
    // *** Redirect the output ***
    processInfo.RedirectStandardError = true;
    processInfo.RedirectStandardOutput = true;

    process = Process.Start(processInfo);
    process.WaitForExit();

    // *** Read the streams ***
    // Warning: This approach can lead to deadlocks, see Edit #2
    string output = process.StandardOutput.ReadToEnd();
    string error = process.StandardError.ReadToEnd();

    exitCode = process.ExitCode;

    Console.WriteLine("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
    Console.WriteLine("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
    Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
    process.Close();
}

static void Main()
{
    ExecuteCommand("echo testing");
}   

* EDIT

下のコメントで追加された情報をもとに、問題を再現することができました。このような挙動になるのは、何らかのセキュリティ設定があるようです(詳しくは調査していません)。

これは が行います。 にない場合、バッチファイルは動作しません。 C:\Windows\System32 . 他の場所(例えば実行ファイルの場所)に移動してみてください。カスタムバッチファイルや実行ファイルをWindowsディレクトリに置くことは、いずれにしても悪い習慣であることに注意してください。

* EDIT 2 それは が判明した。 ストリームが同期的に読み込まれる場合、デッドロックが発生する可能性があります。 WaitForExit または stderrstdout を次々と同期させる。

次の例のように、非同期読み出しメソッドを使用する場合は、このようなことは起こりません。

static void ExecuteCommand(string command)
{
    var processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
    processInfo.CreateNoWindow = true;
    processInfo.UseShellExecute = false;
    processInfo.RedirectStandardError = true;
    processInfo.RedirectStandardOutput = true;

    var process = Process.Start(processInfo);

    process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
        Console.WriteLine("output>>" + e.Data);
    process.BeginOutputReadLine();

    process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
        Console.WriteLine("error>>" + e.Data);
    process.BeginErrorReadLine();

    process.WaitForExit();

    Console.WriteLine("ExitCode: {0}", process.ExitCode);
    process.Close();
}