使用带有约束的 C# 模拟批处理文件

发布于 2024-10-17 09:14:35 字数 538 浏览 2 评论 0原文

我提出了问题 Mimic Batch file with C#,并得到了一些很好的答案。

但是,问题是这三个命令应该在同一个进程中运行。

vsperfcmd /start:coverage /output:run.coverage
hello
vsperfcmd /shutdown

因此,Process.Start 方法

Process.Start("vsperfcmd", "/start:coverage /output:run.coverage");
Process.Start("hello");
Process.Start("vsperfcmd", "/shutdown");

不应该起作用,因为它独立运行三个进程。

还有其他方法可以在同一进程中运行这三个命令吗?我的意思是,一个接一个地跑。

I have asked the question Mimic batch file with C#, and got some good answers.

But, the problem is that these three commands should be run in the same process.

vsperfcmd /start:coverage /output:run.coverage
hello
vsperfcmd /shutdown

So, the Process.Start method

Process.Start("vsperfcmd", "/start:coverage /output:run.coverage");
Process.Start("hello");
Process.Start("vsperfcmd", "/shutdown");

shouldn't work, as it runs three processes independently.

Is there any other way to run those three commands in the same process? I mean, run one after another.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

纸短情长 2024-10-24 09:14:35

如果您实际上不一定需要在同一进程中运行这些步骤,而只是按顺序运行,则可以在 Process 上使用“WaitForExit”方法,该方法将阻止当前线程上的执行,直到进程完成。例如,以下代码将打开记事本,等待您关闭它(进程退出),然后打开记事本的第二个实例:

        p.StartInfo.FileName = "notepad.exe";
        p.Start();
        p.WaitForExit();
        p.Close();

        p.StartInfo.FileName = "notepad.exe";
        p.Start();
        p.WaitForExit();
        p.Close();

但是,这两个实例将发生在不同的进程中 - 您可以通过检查记事本的 PID 来看到这一点例如,任务管理器中的 .exe。

如果您确实想在同一进程中按顺序运行多个 CLI 程序,您可能只想打开一个运行“cmd.exe”的进程,并通过其 StandardInput 向其提供命令。 StandardInput 流是程序从中读取输入的流 - 对于 cmd.exe,它就像直接在其中键入这些命令一样。例如,试试这个:

        Process p = new Process();

        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardInput = true;

        p.Start();
        p.StandardInput.WriteLine("echo Hello there!");
        p.StandardInput.WriteLine("dir");
        p.StandardInput.WriteLine("echo Goodbye!");

        p.WaitForExit();
        p.Close();

这种方法的一个问题是,您不知道传入的最后一个命令是否实际上已经轻松完成执行...“WaitForExit”调用将等待,直到进程自行退出,但对于 cmd.exe 窗口,需要用户点击角落里的“X”。您可以跳过“WaitForExit”调用,但这可能会终止进程,而您的最后一个命令实际上仍在执行某些操作。

幸运的是,在这种特殊情况下,如果您向 cmd.exe 提供“退出”命令,cmd.exe 将自行终止:

        Process p = new Process();

        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardInput = true;

        p.Start();
        p.StandardInput.WriteLine("echo Hello there!");
        p.StandardInput.WriteLine("dir");
        p.StandardInput.WriteLine("echo Goodbye!");
        p.StandardInput.WriteLine("exit");

        p.WaitForExit();
        p.Close();

在这种情况下,您必须分别将 UseShellExecute 和 RedirectStandardInput 属性设置为 true 和 false,否则使用 StandardInput 流将引发异常一种或另一种类型 - 尝试一下看看!您可以在这里阅读更多相关信息:

http://msdn .microsoft.com/en-us/library/system.diagnostics.process.standardinput.aspx

If you don't actually necessarily need the steps to be run in the same process, but just sequentially, you can use the 'WaitForExit' method on Process, which will block execution on the current thread until the process completes. For example, the following code will open notepad, wait for you to close it (process exits) and then open a second instance of notepad:

        p.StartInfo.FileName = "notepad.exe";
        p.Start();
        p.WaitForExit();
        p.Close();

        p.StartInfo.FileName = "notepad.exe";
        p.Start();
        p.WaitForExit();
        p.Close();

However, the two instances will occur in different processes - you can see this by checking the PID of notepad.exe in Task Manager, for example.

If you really want to run several CLI programs in sequence in the same process, you may want to simply open a process running 'cmd.exe' and feed commands to it via its StandardInput. The StandardInput stream is the stream that the program reads its input from - in the case of cmd.exe, it's exactly as if you'd typed those commands into it directly. For example, try this:

        Process p = new Process();

        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardInput = true;

        p.Start();
        p.StandardInput.WriteLine("echo Hello there!");
        p.StandardInput.WriteLine("dir");
        p.StandardInput.WriteLine("echo Goodbye!");

        p.WaitForExit();
        p.Close();

One problem with this approach is that you don't know whether the last command you passed in has actually finished executing that easily... the 'WaitForExit' call will wait until the process exits of its own accord, but in the case of the cmd.exe window that would require a user to come along and click the 'X' in the corner. You could skip the 'WaitForExit' call, but that may terminate the process while your last command is still actually doing something.

Luckily in this particular case, cmd.exe will terminate itself if you feed it the 'exit' command:

        Process p = new Process();

        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardInput = true;

        p.Start();
        p.StandardInput.WriteLine("echo Hello there!");
        p.StandardInput.WriteLine("dir");
        p.StandardInput.WriteLine("echo Goodbye!");
        p.StandardInput.WriteLine("exit");

        p.WaitForExit();
        p.Close();

As it goes, you have to set the UseShellExecute and RedirectStandardInput properties to true and false respectively, or using the StandardInput stream will throw an exception of one type or another - try it and see! You can read more about it here:

http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput.aspx

剑心龙吟 2024-10-24 09:14:35

看起来你可以使用 System.Diagnostics.Process()

var proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName="vsperfcmd";
proc.StartInfo.Arguments="/start:coverage /output:run.coverage";
proc.Start();
proc.WaitForExit();

var proc2 = new System.Diagnostics.Process();
proc2.EnableRaisingEvents=false;
proc2.StartInfo.FileName="hello";
proc2.StartInfo.Arguments="";
proc2.Start();
proc2.WaitForExit();

var proc3 = new System.Diagnostics.Process();
proc3.EnableRaisingEvents=false;
proc3.StartInfo.FileName="vsperfcmd";
proc3.StartInfo.Arguments="/shutdown";
proc3.Start();
proc3.WaitForExit();

Looks like you could use System.Diagnostics.Process()

var proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents=false;
proc.StartInfo.FileName="vsperfcmd";
proc.StartInfo.Arguments="/start:coverage /output:run.coverage";
proc.Start();
proc.WaitForExit();

var proc2 = new System.Diagnostics.Process();
proc2.EnableRaisingEvents=false;
proc2.StartInfo.FileName="hello";
proc2.StartInfo.Arguments="";
proc2.Start();
proc2.WaitForExit();

var proc3 = new System.Diagnostics.Process();
proc3.EnableRaisingEvents=false;
proc3.StartInfo.FileName="vsperfcmd";
proc3.StartInfo.Arguments="/shutdown";
proc3.Start();
proc3.WaitForExit();
嘿看小鸭子会跑 2024-10-24 09:14:35

如果直接运行批处理文件不符合您的需求,我相信您可以从 C# 打开控制台并向其发送命令,一旦您获取了控制台的标准输入。

if running the batch file directly does not fit your needs, I believe you can open the console from c# and send your command to it, once you have grabbed the standard input of the console.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文