2013-07-05 5 views
1

У меня есть исполняемая команда стороннего разработчика, которая входит в мое приложение winform. Команда помещается в каталог под названием «инструменты» из каталога, в котором выполняется приложение.Выполнение пользовательских команд из командной строки в winform C#

Например, если my winform mytestapp.exe находится в каталоге D: \ apps \ mytestapp, то путь к третьей стороне - D: \ apps \ mytestapp \ tools \ mycommand.exe. Я использую Application.StartupPath для определения местоположения mytestapp.exe, чтобы его можно было запускать из любого места.

Я выполняю эту команду, запустив процесс - System.Diagnostics.Process.Start и выполнив то же самое с помощью командной строки. Для запуска команды требуются дополнительные параметры.

Проблема я столкнулся в том, если путь к моему заявлению и команда не имеет каких-либо пробелов в нем, он отлично работает

Например, если мое приложение и команда помещается, как показано ниже , она работает D: \ Apps \ mytestapp \ mytestapp.exe D: \ приложения \ mytestapp \ инструменты \ mycommand.exe "параметр1" "параметр2" - это работает

однако, если у меня есть пробелы в пути , он не работает

C: \ Documents and Settings \ mytestapp \ tools \ mycommand.exe "param eter1 "" parameter2 "- не работает C: \ Documents and Settings \ mytestapp \ tools \ mycommand.exe" параметр1 parameter2 "- не работает " C: \ Documents and Settings \ mytestapp \ tools \ mycommand.exe "" parameter1 parameter2 "- не работает " C: \ Documents and Settings \ mytestapp \ tools \ mycommand.exe parameter1 parameter2 "- не работает

Я попытался использовать двойные кавычки для выполнения команды, как показано выше, и это не сработает. Итак, как мне выполнить свою пользовательскую команду. Любые входы или работа вокруг этой проблемы? Спасибо заранее.

Вот код для начала процесса

try 
     { 
      System.Diagnostics.ProcessStartInfo procStartInfo = 
       new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command); 
      procStartInfo.RedirectStandardOutput = true; 
      procStartInfo.UseShellExecute = false; 
      procStartInfo.CreateNoWindow = true; 
      System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
      proc.StartInfo = procStartInfo; 
      proc.Start(); 
      proc.WaitForExit(); 
     } 
     catch (Exception objException) 
     { 
      // Log the exception 
     } 
+0

Какое исключение? Можете ли вы поделиться своим кодом вокруг Process.Start – rene

+0

Показать свой установочный код processstartinfo, и вы должны получить быстрые ответы :) –

+0

@retailcoder, я не думаю, что в processstartinfo есть ошибка, так как я получаю требуемый вывод, когда нет белые пробелы на пути. –

ответ

1

Пытаться извлечь рабочий каталог от вашей команды и установить WorkingDirectory свойство для объекта ProcessStartInfo. Затем в вашей команде передается только имя файла.

В этом примере предполагается, что команда содержит только полное имя файла.
Нужно быть отрегулирован для фактического текста команды

string command = "C:\Documents and settings\mytestapp\tools\mycommand.exe"; 
string parameters = "parameter1 parameter2"; 

try 
{ 
    string workDir = Path.GetDirectoryName(command); 
    string fileCmd = Path.GetFileName(command); 
    System.Diagnostics.ProcessStartInfo procStartInfo = 
     new System.Diagnostics.ProcessStartInfo("cmd", "/c " + fileCmd + " " + parameters); 
    procStartInfo.WorkingDirectory = workDir; 
    procStartInfo.RedirectStandardOutput = true; 
    procStartInfo.UseShellExecute = false; 
    procStartInfo.CreateNoWindow = true; 
    System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
    proc.StartInfo = procStartInfo; 
    proc.Start(); 
    proc.WaitForExit(); 
} 
catch (Exception objException) 
{ 
    // Log the exception 
} 
+0

Спасибо за ответ, Стив. Чтобы разработать мою проблему, C: \ Users \ mytestapp \ command.exe C: \ somefolder \ somefile.txt D: \ newfolder \ newfolder.txt - работает "C: \ Users \ mytestapp \ command.exe C: \ somefolder \ somefile.txt D: \ newfolder \ newfolder.txt "- работает C: \ Users \ mytestapp \ command.exe" C: \ somefolder \ somefile.txt "" D: \ newfolder \ newfolder.txt "- работает " C: \ Users \ mytestapp \ command.exe "C: \ somefolder \ somefile.txt D: \ newfolder \ newfolder.txt - работает Любое пустое пространство в пути command.exe или путь file1 или путь file2 - не удается , Я пробовал комбинации цитат. :( –

+0

Вы можете передать command.exe отдельно от своих параметров? Как и в моем обновленном ответе? – Steve

0

Я считаю следующие работы: "C: \ Documents и Settings \ mytestapp \ Tools \ mycommand.exe" "параметр1" "PARAMETER2"

Возможно, у вас что-то еще не так. Попробуйте отладить и проверить, используется ли котировка дважды, или если есть кавычки в середине.

+0

Я пробовал это, он тоже не работал .. :( –

0

Я думаю, это может быть потому, что кавычки необходимы в цепочках args (и command), которые ссылаются на пути, которые содержат пробелы; также они должны быть экранированы, если определены не-verbatim (т.нет @ предшествующей строку) в-коды, так что command строки не будет определен следующим образом:

var command = "\"C:\\Documents and settings\\mytestapp\\tools\\mycommand.exe\""; 
      //^escaped quote           ^escaped quote 

Специально для запуска процессов я написал этот метод не так давно, это может быть немного слишком специализировано для этого конкретного случай, но можно было бы легко принять его, как это и/или писать перегруженные с разными параметрами для разных вкусов настройки процесса:

private ProcessStartInfo CreateStartInfo(string command, string args, string workingDirectory, bool useShellExecute) 
{ 
    var defaultWorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty; 
    var result = new ProcessStartInfo 
    { 
     WorkingDirectory = string.IsNullOrEmpty(workingDirectory) 
           ? defaultWorkingDirectory 
           : workingDirectory, 
     FileName = command, 
     Arguments = args, 
     UseShellExecute = useShellExecute, 
     CreateNoWindow = true, 
     ErrorDialog = false, 
     WindowStyle = ProcessWindowStyle.Hidden, 
     RedirectStandardOutput = !useShellExecute, 
     RedirectStandardError = !useShellExecute, 
     RedirectStandardInput = !useShellExecute 
    }; 
    return result; 
} 

Я использую его, как показано ниже; здесь объект _process может быть любым Process - наличие его как переменной экземпляра может быть недействительным для вашего случая использования; также OutputDataReceived и ErrorDataReceived обработчиков событий (не показано), вход только выходная строки - но вы можете разобрать его и базы некоторых курсовые действий на него:

public bool StartProcessAndWaitForExit(string command, string args, 
        string workingDirectory, bool useShellExecute) 
{ 
    var info = CreateStartInfo(command, args, workingDirectory, useShellExecute);    
    if (info.RedirectStandardOutput) _process.OutputDataReceived += _process_OutputDataReceived; 
    if (info.RedirectStandardError) _process.ErrorDataReceived += _process_ErrorDataReceived; 

    var logger = _logProvider.GetLogger(GetType().Name); 
    try 
    { 
     _process.Start(info, TimeoutSeconds); 
    } 
    catch (Exception exception) 
    { 
     logger.WarnException(log.LogProcessError, exception); 
     return false; 
    } 

    logger.Debug(log.LogProcessCompleted); 
    return _process.ExitCode == 0; 
} 

args строка, которую вы передать именно то, как вы бы ввести его в командной строке, так что в вашем случае это может выглядеть:

CreateStartInfo("\"C:\\Documents and settings\\mytestapp\\tools\\mycommand.exe\"", 
       "-switch1 -param1:\"SomeString\" -param2:\"Some\\Path\\foo.bar\"", 
       string.Empty, true); 

Если вы вместо того, чтобы положить строки путь/команду в файле настроек, вы можете хранить их без необходимости экранировать кавычки и обратные слэши.