在 C# 中执行批处理文件

2023-12-10

我正在尝试用 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 *

鉴于您下面评论中的额外信息,我能够重现该问题。似乎有一些安全设置导致了这种行为(尚未详细调查)。

This does如果批处理文件不位于则工作C:\Windows\System32。尝试将其移动到其他位置,例如您的可执行文件的位置。请注意,将自定义批处理文件或可执行文件保留在 Windows 目录中无论如何都是不好的做法。

* 编辑 2 * It 事实证明如果同步读取流,则可能会发生死锁,无论是在之前同步读取WaitForExit或者通过阅读两者stderr and stdout一个接着一个同步进行。

如果使用异步读取方法,则不应发生这种情况,如下例所示:

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();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中执行批处理文件 的相关文章

随机推荐