2013-07-05 218 views
1

我有一個第三方可執行命令被綁定到我的winform應用程序中。該命令放置在執行應用程序的目錄中名爲「tools」的目錄中。例如,如果我的winform mytestapp.exe被放置在D:\ apps \ mytestapp目錄中,則第三方命令的路徑是D:\ apps \ mytestapp \ tools \ mycommand.exe。我使用Application.StartupPath來識別mytestapp.exe的位置,以便它可以從任何位置運行。在winform中執行命令提示符下的自定義命令C#

我正在通過啓動一個進程 - System.Diagnostics.Process.Start並使用命令提示執行相同的命令來執行此命令。還有其他參數需要傳遞來運行該命令。

我面臨的問題是,如果路徑到我的應用程序和命令不具有任何空格,它工作正常

例如,如果 我的應用程序和命令放在像下面,它的工作原理 d:\ APPS \ mytestapp \ mytestapp.exe d:\ APPS \ mytestapp \工具\ mycommand.exe 「參數1」 「參數2」 - 這部作品

但是如果我必須在路徑中的空格,它失敗

C:\ Documents and settings \ mytestapp \ tools \ mycommand.exe「param eter1「」parameter2「 - does not work C:\ Documents and settings \ mytestapp \ tools \ mycommand.exe」parameter1 parameter2「 - does not work 」C:\ Documents and Settings \ mytestapp \ tools \ mycommand.exe「」parameter1 parameter2 「 - does not work 」C:\ Documents and Settings \ mytestapp \ tools \ mycommand.exe parameter1 parameter2「 - does not work

我試着用雙引號執行命令,如上所示,它不起作用。 那麼,我該如何執行我的自定義命令。任何輸入或解決此問題? 在此先感謝。

這是啓動過程的

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:\用戶\ mytestapp \ COMMAND.EXE C:\ somefolder \ somefile.txt d:\ newfolder \ newfolder.txt - 工程 「C:\用戶\ mytestapp \ COMMAND.EXE C:\ somefolder \ somefile.txt d:\ newfolder \ newfolder.txt 「 - 工程 C:\用戶\ 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路徑或文件1路徑或文件2路 - 失敗。我嘗試了引號的組合。 :( –

+0

你能夠通過command.exe從它的參數分開?在我更新的答案? – Steve

0

我相信了以下工作: 「C:\ Documents和Settings \ mytestapp \工具\ mycommand.exe」 「參數1」 「參數2」

您可能有其他問題。嘗試調試並檢查報價是否使用了兩次,或者中間是否有引號。

+0

我曾試過這個,它也沒有工作.. :( –

0

我認爲這可能是因爲在引用包含空白的路徑的args(和command)字符串中需要引號;當它們被定義爲非逐字(即,沒有@在代碼字符串),所以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 - 將它作爲實例變量可能對您的用例無效;也OutputDataReceivedErrorDataReceived事件處理(未顯示)僅記錄輸出字符串 - 但你可以分析它和底座後,它的行動的一些過程:

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

如果你不是把路徑/命令串在設置文件,你可以將它們存儲而無需轉義引號和反斜線。

相關問題