问题描述
我试图执行在C#中的批处理文件,但我没有得到任何运气这样做。
I'm trying to execute a batch file in C# but I'm not getting any luck doing it.
我发现在互联网上的多个例子这样做,但它不是为我工作。
I've found multiple examples on the internet doing it but it is not working for me.
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)。当我手动执行批处理文件就可以正常工作
The command string contains the name of the batch file (stored in system32) and some files it should manipulate. (Example: txtmanipulator file1.txt file2.txt file3.txt) When I execute the batch file manually it works correctly.
在执行code它给了我一个的退出code:1 (捕获所有一般错误)
When executing the code it gives me an ExitCode: 1 (Catch all for general errors)
我在做什么错了?
推荐答案
这应该工作。你可以尝试倾倒了输出和错误流的内容,以找出发生了什么:
This should work. You could try to dump out the contents of the output and error streams in order to find out what's happening:
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");
}
*编辑*
鉴于您的评论的额外信息下面,我能够重现问题。似乎有一些安全设置,导致这种行为(没有调查,在细节)。
Given the extra information in your comment below I was able to recreate the problem. There seems to be some security setting that results in this behaviour (haven't investigated that in detail).
此的确实的工作是否bat文件不位于C:\\ WINDOWS \\ SYSTEM32。尝试将它移动到其他位置,如您的可执行文件的位置。需要注意的是保持自BAT文件或可执行文件在Windows目录是不好的做法呢。
This does work if the bat file is not located in c:\windows\system32. Try moving it to some other location, e.g. the location of your executable. Note that keeping custom bat files or executables in the Windows directory is bad practice anyway.
*编辑2 *
它turns出的,如果流同步读取,可发生死锁,无论是之前 WaitForExit
同步阅读或通过阅读这两种标准错误和stdout同步一前一后。
* EDIT 2 *It turns out that if the streams are read synchronously, a deadlock can occur, either by reading synchronously before WaitForExit
or by reading both stderr and stdout synchronously one after the other.
此不应该发生,如果使用异步读取方法代替,如在下面的例子:
This should not happen if using the asynchronous read methods instead, as in the following example:
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();
}
这篇关于执行批处理文件在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!