Executing Batch File in C#

前端 未结 12 1774
有刺的猬
有刺的猬 2020-11-22 05:22

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

相关标签:
12条回答
  • 2020-11-22 05:34

    Below code worked fine for me

    using System.Diagnostics;
    
    public void ExecuteBatFile()
    {
        Process proc = null;
    
        string _batDir = string.Format(@"C:\");
        proc = new Process();
        proc.StartInfo.WorkingDirectory = _batDir;
        proc.StartInfo.FileName = "myfile.bat";
        proc.StartInfo.CreateNoWindow = false;
        proc.Start();
        proc.WaitForExit();
        ExitCode = proc.ExitCode;
        proc.Close();
        MessageBox.Show("Bat file executed...");
    }
    
    0 讨论(0)
  • 2020-11-22 05:39
    System.Diagnostics.Process.Start("c:\\batchfilename.bat");
    

    this simple line will execute the batch file.

    0 讨论(0)
  • 2020-11-22 05:39

    It works fine. I tested it like this:

    String command = @"C:\Doit.bat";
    
    ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
    // ProcessInfo.CreateNoWindow = true;
    

    I commented out turning off the window so I could SEE it run.

    0 讨论(0)
  • 2020-11-22 05:44

    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:

    1. Subscribes to the events, before the process has started, therefore ensuring that no output is missed.
    2. Begins reading from outputs as soon as the process is started.

    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.

        static void RunCommand(string command, string workingDirectory)
        {
            Process process = new Process
            {
                StartInfo = new ProcessStartInfo("cmd.exe", $"/c {command}")
                {
                    WorkingDirectory = workingDirectory,
                    CreateNoWindow = true,
                    UseShellExecute = false,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true
                }
            };
    
            process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => Console.WriteLine("output :: " + e.Data);
    
            process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => Console.WriteLine("error :: " + e.Data);
    
            process.Start();
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();
    
            Console.WriteLine("ExitCode: {0}", process.ExitCode);
            process.Close();
        }
    
    0 讨论(0)
  • 2020-11-22 05:45

    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.

    public static void ExecuteCommand(string command, string workingFolder)
            {
                int ExitCode;
                ProcessStartInfo ProcessInfo;
                Process process;
    
                ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
                ProcessInfo.CreateNoWindow = true;
                ProcessInfo.UseShellExecute = false;
                ProcessInfo.WorkingDirectory = workingFolder;
                // *** Redirect the output ***
                ProcessInfo.RedirectStandardError = true;
                ProcessInfo.RedirectStandardOutput = true;
    
                process = Process.Start(ProcessInfo);
                process.WaitForExit();
    
                // *** Read the streams ***
                string output = process.StandardOutput.ReadToEnd();
                string error = process.StandardError.ReadToEnd();
    
                ExitCode = process.ExitCode;
    
                MessageBox.Show("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
                MessageBox.Show("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
                MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
                process.Close();
            }
    

    Called like this:

        // This will get the current WORKING directory (i.e. \bin\Debug)
        string workingDirectory = Environment.CurrentDirectory;
        // This will get the current PROJECT directory
        string projectDirectory = Directory.GetParent(workingDirectory).Parent.FullName;
        string commandToExecute = Path.Combine(projectDirectory, "TestSetup", "WreckersTestSetupQA.bat");
        string workingFolder = Path.GetDirectoryName(commandToExecute);
        commandToExecute = QuotesAround(commandToExecute);
        ExecuteCommand(commandToExecute, workingFolder);
    

    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.

    0 讨论(0)
  • 2020-11-22 05:47

    After some great help from steinar this is what worked for me:

    public void ExecuteCommand(string command)
    {
        int ExitCode;
        ProcessStartInfo ProcessInfo;
        Process process;
    
        ProcessInfo = new ProcessStartInfo(Application.StartupPath + "\\txtmanipulator\\txtmanipulator.bat", command);
        ProcessInfo.CreateNoWindow = true;
        ProcessInfo.UseShellExecute = false;
        ProcessInfo.WorkingDirectory = Application.StartupPath + "\\txtmanipulator";
        // *** Redirect the output ***
        ProcessInfo.RedirectStandardError = true;
        ProcessInfo.RedirectStandardOutput = true;
    
        process = Process.Start(ProcessInfo);
        process.WaitForExit();
    
        // *** Read the streams ***
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();
    
        ExitCode = process.ExitCode;
    
        MessageBox.Show("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
        MessageBox.Show("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
        MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
        process.Close();
    }
    
    0 讨论(0)
提交回复
热议问题