Выполнение пакетного файла в 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 general errors)
что я делаю не так?
7 ответов:
это должно работать. Вы можете попробовать выгрузить содержимое выходных и ошибочных потоков, чтобы узнать, что происходит:
static void ExecuteCommand(string command) { int exitCode; ProcessStartInfo processInfo; Process process; processInfo = new ProcessStartInfo("cmd.exe", "/c " + command); processInfo.CreateNoWindow = true; processInfo.UseShellExecute = false; // *** Redirect the output *** processInfo.RedirectStandardError = true; processInfo.RedirectStandardOutput = true; process = Process.Start(processInfo); process.WaitForExit(); // *** Read the streams *** // Warning: This approach can lead to deadlocks, see Edit #2 string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); exitCode = process.ExitCode; Console.WriteLine("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output)); Console.WriteLine("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error)); Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand"); process.Close(); } static void Main() { ExecuteCommand("echo testing"); }* EDIT*
учитывая дополнительную информацию в вашем комментарии ниже, я смог воссоздать проблему. Кажется, есть некоторые настройки безопасности, которые приводят к такому поведению (не исследовали это подробно).
этой тут работать, если пакетный файл не находится в
C:\Windows\System32. Попробуйте переместить его в другое место, например, в расположение исполняемого файла. Обратите внимание, что хранение пользовательских пакетных файлов или исполняемых файлов в каталоге Windows является плохой практикой в любом случае.* EDIT 2* Это получается что если потоки читаются синхронно, может произойти взаимоблокировка, либо путем синхронного чтения перед
WaitForExitи одновременноstderrиstdoutсинхронно один за другим.этого не должно произойти, если вместо этого используйте асинхронные методы чтения, как в следующем примере:
static void ExecuteCommand(string command) { var processInfo = new ProcessStartInfo("cmd.exe", "/c " + command); processInfo.CreateNoWindow = true; processInfo.UseShellExecute = false; processInfo.RedirectStandardError = true; processInfo.RedirectStandardOutput = true; var process = Process.Start(processInfo); process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => Console.WriteLine("output>>" + e.Data); process.BeginOutputReadLine(); process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => Console.WriteLine("error>>" + e.Data); process.BeginErrorReadLine(); process.WaitForExit(); Console.WriteLine("ExitCode: {0}", process.ExitCode); process.Close(); }
System.Diagnostics.Process.Start("c:\batchfilename.bat");эта простая строка будет выполнять пакетный файл.
после некоторой большой помощи от steinar это то, что сработало для меня:
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(); }
Он работает нормально. Я проверил это так:
String command = @"C:\Doit.bat"; ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + command); // ProcessInfo.CreateNoWindow = true;Я прокомментировал выключение окна, чтобы я мог видеть, как он работает.
ниже код работал штрафа для меня
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..."); }
using System.Diagnostics; private void ExecuteBatFile() { Process proc = null; try { string targetDir = string.Format(@"D:\mydir"); //this is where mybatch.bat lies proc = new Process(); proc.StartInfo.WorkingDirectory = targetDir; proc.StartInfo.FileName = "lorenzo.bat"; proc.StartInfo.Arguments = string.Format("10"); //this is argument proc.StartInfo.CreateNoWindow = false; proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //this is for hiding the cmd window...so execution will happen in back ground. proc.Start(); proc.WaitForExit(); } catch (Exception ex) { Console.WriteLine("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace.ToString()); } }
вы пробовали запустить его в качестве администратора? Запустите Visual Studio в качестве администратора, если вы используете его, потому что работа с
.batфайлы требуют этих привилегий.
Comments