2016-05-31 116 views
2

我試圖用C#中的參數執行命令行程序。我會想象,在C#中站起來並做到這一點將是微不足道的,但即使擁有本站和其他站點上的所有可用資源,它仍然具有挑戰性。我很茫然,所以我會盡可能提供更多細節。使用C#中的參數執行命令行.exe。

我目前的方法和代碼如下,在調試器中,變量命令具有以下值。

command = "C:\\Folder1\\Interfaces\\Folder2\\Common\\JREbin\\keytool.exe -import -noprompt -trustcacerts -alias myserver.us.goodstuff.world -file C:\\SSL_CERT.cer -storepass changeit -keystore keystore.jks" 

問題可能是我如何調用和格式化該變量命令中使用的字符串。

有什麼想法可能是這個問題?

ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command); 

    procStartInfo.RedirectStandardOutput = true; 
    procStartInfo.UseShellExecute = false; 
    procStartInfo.CreateNoWindow = true; 
    Process process = new Process(); 
    process.StartInfo = procStartInfo; 
    process.Start(); 
    string result = process.StandardOutput.ReadToEnd(); 
    Console.WriteLine(result); 

一旦完成變量結果,我就不會收到任何信息或錯誤。

+1

你在命令行中嘗試這個命令?也許你需要將'command'字符串換成雙引號。你真的得到了什麼錯誤? –

+0

我可以在命令行中成功運行確切的命令。也許這些步驟略有不同,因爲我將目錄設置爲C:\ Folder1 \ Interfaces \ Folder2 \ Common \ JREbin \,然後執行keytool.exe -import -noprompt -trustcacerts -alias myserver.us.goodstuff.world -file C:\ SSL_CERT.cer -storepass changeit -keystore keystore.jks當這個運行時,我收到沒有錯誤,不幸的是控制檯字符串是空的。 –

回答

8

等待進程結束(讓它做工作):

ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command); 

procStartInfo.RedirectStandardOutput = true; 
procStartInfo.UseShellExecute = false; 
procStartInfo.CreateNoWindow = true; 

// wrap IDisposable into using (in order to release hProcess) 
using(Process process = new Process()) { 
    process.StartInfo = procStartInfo; 
    process.Start(); 

    // Add this: wait until process does its work 
    process.WaitForExit(); 

    // and only then read the result 
    string result = process.StandardOutput.ReadToEnd(); 
    Console.WriteLine(result); 
} 
+0

經過一番修改和手指fu I後,我得到了這個工作,包括控制檯窗口。感謝您的及時回覆。 –

+0

使用您的代碼我無法生成keystore.jks文件並且沒有收到任何錯誤。 – Hkachhia

+0

@Hkachhia:嘗試使用*絕對路徑*:而不是'... -keystore keystore.jks'放置類似'... -keystore c:\ mydir \ keystore.jks'的東西,並檢查是否有'c: \ mydir \ keystore.jks'文件創建 –

0

我意識到我可能已經離開了一些細節,有些人可能需要在未來解決這個問題。

以下是運行時方法參數的值。我對ProcessStartInfo和Process的對象需要正確地站起來有些困惑,我認爲別人也可能會這樣。

exeDir = 「C:\ folder1中\文件夾2 \ BIN \ keytool.exe的」

ARGS = 「-delete -noprompt -alias server.us.goodstuff.world -storepass的changeit -keystore keystore.jks」

public bool ExecuteCommand(string exeDir, string args) 
{ 
    try 
    { 
    ProcessStartInfo procStartInfo = new ProcessStartInfo(); 

    procStartInfo.FileName = exeDir; 
    procStartInfo.Arguments = args; 
    procStartInfo.RedirectStandardOutput = true; 
    procStartInfo.UseShellExecute = false; 
    procStartInfo.CreateNoWindow = true; 

    using (Process process = new Process()) 
    { 
     process.StartInfo = procStartInfo; 
     process.Start(); 

     process.WaitForExit(); 

     string result = process.StandardOutput.ReadToEnd(); 
     Console.WriteLine(result); 
    } 
    return true; 
    } 
    catch (Exception ex) 
    { 
    Console.WriteLine("*** Error occured executing the following commands."); 
    Console.WriteLine(exeDir); 
    Console.WriteLine(args); 
    Console.WriteLine(ex.Message); 
    return false; 
    } 

梅德援助和下面的資源之間,

http://www.codeproject.com/Articles/25983/How-to-Execute-a-Command-in-C

我能湊齊了一起。謝謝!

+0

對於那些可能已經發現我試圖將證書自動安裝到JRE密鑰庫中的人,這裏是我正在使用的導入命令,「-import -noprompt -trustcacerts -alias server.us.goodstuffworld -file C:\\ folder1 \\ mycertname.cer -storepass changeit -keystore keystore.jks「 –

0

當談到從C#執行CLI進程時,它可能看起來像一個簡單的任務,但有很多缺陷,甚至可能在很晚之後纔會發現。例如,如果子進程向標準輸出寫入足夠的數據,則目前給出的兩個答案都不起作用,如解釋here所述。

我寫了一個庫,通過完全抽象Process交互來簡化CLI的工作,通過執行一個方法來解決整個任務 - CliWrap

您的代碼會再看看這樣的:

var cli = new Cli("cmd"); 
var output = cli.Execute("/c " + command); 
var stdout = output.StandardOutput;