4

I'm writing an application that creates a batch file and then run :

I know I can create a Batch file and run it no problem with that .

What I want to do is : once I have created the string that makes the file , Is there is any way to execute the string as a Batch file ? something like

string BatchFile = "echo \"bla bla\" \n iperf -c 123  ... ... .. "
Diagnostics.Process.Start(BatchFile);
Community
  • 1
  • 1
LordTitiKaka
  • 2,087
  • 2
  • 31
  • 51
  • 3
    So that you dont have to write the file to disk? No. Its actually windows that executes the batch file. If you're creating the string however, you could just execute the individual statements. – crthompson Dec 09 '14 at 16:40
  • 2
    No. There's a reason it's called a batch **file**. – Ken White Dec 09 '14 at 16:48
  • 1
    yeah you right (both of you :)) but still I had to ask , and actually i was expecting something novel like Dynamic or reflection :) – LordTitiKaka Dec 09 '14 at 21:56
  • If the string is redirected into cmd.exe's Stdin, then almost all batch file features may be used in the "batch" string; the exceptions are: batch file parameters, `GOTO` and `CALL :label` commands. See [my answer](http://stackoverflow.com/questions/27384126/running-string-as-a-batch-file-in-c-sharp/27393307#27393307) below. – Aacini Dec 10 '14 at 04:43

3 Answers3

2

You can run CMD.EXE with /c as an executable and have the rest as arguments :

Process.Start("cmd.exe", "/c echo \"bla bla\" \n iperf -c 123  ... ... .. ");
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Perfect28
  • 11,089
  • 3
  • 25
  • 45
  • 2
    That works fine if it's a simple command or a few. Try a real, functional batch file's content, and this simply won't work. – Ken White Dec 09 '14 at 16:49
  • 2
    @Robert: There's a limit to the length of a single command line that CMD.EXE will accept, and it's relatively short (8196 characters). Raymond Chen wrote about it [here](http://msdn.microsoft.com/en-us/library/bb776871%28v=vs.85%29.aspx). Quote: "If you are using the CMD.EXE command processor, then you are also subject to the 8192 character command line length limit imposed by CMD.EXE." This will execute fine from a batch file, but not passed as a single string to CMD.EXE as a parameter. – Ken White Dec 09 '14 at 16:57
  • @KenWhite: Right, figured that out already. Though 8192 characters is quite a lot; I've probably never actually seen a batch file larger than that (though I'm sure you have). – Robert Harvey Dec 09 '14 at 17:12
  • 1
    This is not the answer I was looking for , but it is the closest I think I can get – LordTitiKaka Dec 09 '14 at 21:58
  • 3
    This example don't works as shown; it requires to change all `\n` newline characters by an ampersand: `&` – Aacini Dec 10 '14 at 04:35
2

for me, I am using this code:

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();

        }
houssam
  • 1,823
  • 15
  • 27
1

You may create your Batch "file" as a long string with lines terminated in \n, exactly as you shown in your example, and then execute that string (I called it a "NotBatch-text") executing cmd.exe and redirecting such string into its Stdin standard handle. This way, your "NotBatch-text" may use a large number of Batch features, like expansion of %variables%, IF and FOR commands nested at any level, and many more. You may also use delayed !variable! expansion if you execute cmd.exe with /V:ON switch. Really, the only things that don't works in the NotBatch-text are: parameters and SHIFT command, and GOTO/CALL :label commands; further details at this post.

If you want to execute a more advanced "NotBatch-text" string, you may even simulate GOTO and CALL :label commands with the aid of a third party program, as described at this post.

Community
  • 1
  • 1
Aacini
  • 65,180
  • 12
  • 72
  • 108