在c#中将字符串作为批处理文件运行

Posted

技术标签:

【中文标题】在c#中将字符串作为批处理文件运行【英文标题】:Running string as a Batch file in c# 【发布时间】:2014-12-09 16:38:57 【问题描述】:

我正在编写一个创建批处理文件然后运行的应用程序:

我知道我可以创建一个批处理文件和run it 没问题。

我想做的是: 一旦我创建了制作文件的字符串,有没有办法将 string 作为批处理文件执行? 像

string BatchFile = "echo \"bla bla\" \n iperf -c 123  ... ... .. "
Diagnostics.Process.Start(BatchFile);

【问题讨论】:

这样您就不必将文件写入磁盘?不。它实际上是执行批处理文件的窗口。但是,如果您正在创建字符串,则可以只执行单个语句。 没有。它被称为批处理文件是有原因的。 是的,你说得对(你们俩 :))但我还是要问,实际上我期待一些新奇的东西,比如动态或反射 :) 如果字符串被重定向到cmd.exe的Stdin,那么几乎所有的批处理文件特性都可以用在“batch”字符串中;例外情况是:批处理文件参数、GOTOCALL :label 命令。请参阅下面的my answer。 【参考方案1】:

您可以使用 /c 作为可执行文件运行 CMD.EXE,并将其余部分作为参数:

Process.Start("cmd.exe", "/c echo \"bla bla\" \n iperf -c 123  ... ... .. ");

【讨论】:

如果它是一个简单的命令或几个,那效果很好。尝试一个真实的、实用的批处理文件的内容,这根本行不通。 @Robert:CMD.EXE 接受的单个命令行的长度是有限制的,而且相对较短(8196 个字符)。 Raymond Chen 写了关于它here。引用:“如果您使用的是 CMD.EXE 命令处理器,那么您还必须遵守 CMD.EXE 施加的 8192 个字符的命令行长度限制。”这将从批处理文件中正常执行,但不会作为单个字符串作为参数传递给 CMD.EXE。 @KenWhite:对,已经想通了。虽然 8192 个字符相当多;我可能从未真正见过比这更大的批处理文件(尽管我相信你有)。 这不是我想要的答案,但它是我认为我能得到的最接近的答案 这个例子不如图所示;它需要用 & 符号更改所有 \n 换行符:&【参考方案2】:

对我来说,我正在使用以下代码:

Process process;
        private void button1_Click(object sender, EventArgs e)
        
            process = new Process();
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.FileName = "cmd";
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardInput = true;
            process.Start();
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerAsync();

            process.StandardInput.WriteLine("cd d:/tempo" );
            process.StandardInput.WriteLine("dir");



        
        void worker_DoWork(object sender, DoWorkEventArgs e)
        
            string line;
            while (!process.StandardOutput.EndOfStream)
            
                line = process.StandardOutput.ReadLine();
                if (!string.IsNullOrEmpty(line))
                
                    SetText(line);
                
            
        

        delegate void SetTextCallback(string text);
        private void SetText(string text)
        
            if (this.textBox1.InvokeRequired)
            
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[]  text );
            
            else
            
                this.textBox1.Text += text + Environment.NewLine;
            
        
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        
            process.StandardInput.WriteLine("exit");
            process.Close();

        

【讨论】:

你的答案是正确的,而且可能更好。但 Haga R. 的答案更接近我的意思(但我给了你 +1 :))【参考方案3】:

您可以将批处理“文件”创建为一个以\n 结尾的长字符串,就像您在示例中显示的那样,然后执行该字符串(我称之为“NotBatch-text”)执行 cmd。 exe 并将此类字符串重定向到其 Stdin 标准句柄。这样,您的“NotBatch-text”可能会使用大量的批处理功能,例如扩展 %variables%、IFFOR 嵌套在任何级别的命令等等。您也可以使用延迟的!变量!如果您使用/V:ON 开关执行 cmd.exe,则展开。实际上,NotBatch-text 中唯一不起作用的是:参数和SHIFT 命令,以及GOTO/CALL :label 命令;更多详情请访问this post。

如果您想执行更高级的“NotBatch-text”字符串,您甚至可以在第三方程序的帮助下模拟GOTOCALL :label 命令,如@ 987654322@.

【讨论】:

以上是关于在c#中将字符串作为批处理文件运行的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中将 Exe 文件作为嵌入式资源运行

在批处理脚本中将变量字符串作为命令运行[关闭]

如何在 PowerShell 中将文件作为流逐行处理

从 C# 执行批处理文件

使用 .R 文件作为资源并直接在 C# 中创建批处理

如何在批处理文件中将输入传递给.exe?