在 C# 中执行批处理文件
我正在尝试用 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 genericErrors)
我做错了什么?
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");
}
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.
When executing the code, it gives me an **ExitCode: 1** (Catch all for general errors)
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
经过 steinar 的大力帮助后,这对我有用:
After some great help from steinar this is what worked for me:
效果很好。我像这样测试了它:
我注释掉了关闭窗口,这样我就可以看到它运行。
It works fine. I tested it like this:
I commented out turning off the window so I could SEE it run.
这是示例C#代码,它们将2个参数发送到bat/cmd文件以进行答案,以 问题 。
评论:如何传递参数并读取命令执行的结果?
/by @贾纳特别克·沙谢耶夫
// c#解码蝙蝠文件并传递参数: //编辑01/2022
1. << /strong>创建蝙蝠并尽可能多地对其进行测试
2。将代码转换为base64
定义代码中的变量
3。用base64 strings 4 。
通过您的论点
Here is sample c# code that are sending 2 parameters to a bat/cmd file for answer this question.
Comment: how can I pass parameters and read a result of command execution?
/by @Janatbek Sharsheyev
// C# decode bat file and run passing arguments: // edit 01/2022
1. Create your bat and test it as much as possible
2. Convert the code to base64
3. Defines a variable in your code with the base64 strings
4. Decode at runtime to a pre-defined and proper location for execution
5. Call the bat execution on the path where it was decodes
6. If necessary, pass your arguments
下面的代码对我来说效果很好
Below code worked fine for me
您是否尝试过以管理员身份启动它?如果您使用 Visual Studio,请以管理员身份启动它,因为使用
.bat
文件需要这些权限。Have you tried starting it as an administrator? Start Visual Studio as an administrator if you use it, because working with
.bat
files requires those privileges.对于之前提出的解决方案,我一直在努力让多个 npm 命令在循环中执行并在控制台窗口上获取所有输出。
在我结合了之前评论中的所有内容,但重新安排了代码执行流程后,它终于开始工作了。
我注意到事件订阅完成得太晚(在进程已经开始之后),因此未捕获一些输出。
下面的代码现在执行以下操作:
因此确保不会丢失任何输出。
该代码已经针对死锁进行了测试,尽管它是同步的(同时执行一个进程),因此我无法保证如果并行运行会发生什么。
With previously proposed solutions, I have struggled to get multiple npm commands executed in a loop and get all outputs on the console window.
It finally started to work after I have combined everything from the previous comments, but rearranged the code execution flow.
What I have noticed is that event subscribing was done too late (after the process has already started) and therefore some outputs were not captured.
The code below now does the following:
therefore ensuring that no output is missed.
The code has been tested against the deadlocks, although it is synchronous (one process execution at the time) so I cannot guarantee what would happen if this was run in parallel.
我想要一些更直接可用的东西,而不需要组织特定的硬编码字符串值。我提供以下内容作为可直接重用的代码块。较小的缺点是在进行调用时需要确定并传递工作文件夹。
调用方式如下:
在此示例中,在 Visual Studio 2017 中,作为测试运行的一部分,我想在执行某些测试之前运行环境重置批处理文件。 (SpecFlow+xUnit)。我厌倦了单独手动运行 bat 文件的额外步骤,只想将 bat 文件作为 C# 测试设置代码的一部分运行。环境重置批处理文件将测试用例文件移回输入文件夹,清理输出文件夹等,以达到正确的测试开始状态进行测试。 QuotesAround 方法只是在命令行周围加上引号,以防文件夹名称中存在空格(“Program Files”,有人吗?)。其中的内容就是: private string QuotesAround(string input) {return "\"" + input + "\"";}
如果您的情况与我的情况类似,希望有人发现这很有用并节省几分钟。
I wanted something that was more directly usable without organization-specific hard-coded string values in it. I offer the following as a directly reusable chunk of code. The minor downside is needing to determine and pass the working folder when making the call.
Called like this:
In this example, from within Visual Studio 2017, as part of a test run, I want to run an environment reset batch file before executing some tests. (SpecFlow+xUnit). I got tired of extra steps for manually running the bat file separately, and wanted to just run the bat file as part of the C# test setup code. The environment reset batch file moves test case files back into the input folder, cleans up output folders, etc. to get to the proper test starting state for testing. The QuotesAround method simply puts quotes around the command line in case there are spaces in folder names ("Program Files", anyone?). All that's in it is this: private string QuotesAround(string input) {return "\"" + input + "\"";}
Hope some find this useful and save a few minutes if your scenario is similar to mine.
System.Diagnostics.Process.Start(BatchFileName,Parameters);
我知道这适用于批处理文件和参数,但不知道如何在 C# 中获取结果。
通常,输出在批处理文件中定义。
System.Diagnostics.Process.Start(BatchFileName, Parameters);
I know this will work for batch file and parameters, but no ideas how to get the results in C#.
Usually, the outputs are defined in the batch file.
这应该有效。您可以尝试转储输出和错误流的内容,以找出发生的情况:
* 编辑*
鉴于下面评论中的额外信息,我能够重新创建问题。似乎有一些安全设置导致了这种行为(尚未详细调查)。
如果批处理文件不在
C:\Windows\System32
中,此确实可以工作。尝试将其移动到其他位置,例如可执行文件的位置。请注意,将自定义批处理文件或可执行文件保留在 Windows 目录中无论如何都是不好的做法。* 编辑 2 *
事实证明 如果同步读取流,可能会发生死锁,无论是在
WaitForExit
之前同步读取,还是同时读取stderr
和stdout
一个接一个。如果使用异步读取方法,则不应发生这种情况,如下例所示:
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:
* EDIT *
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).
This does work if the batch 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 batch files or executables in the Windows directory is bad practice anyway.* 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 bothstderr
andstdout
synchronously one after the other.This should not happen if using the asynchronous read methods instead, as in the following example:
这个简单的行将执行批处理文件。
this simple line will execute the batch file.