2013-11-01 206 views
0

我有一個按鈕,我單擊它執行命令。該命令可能會提示輸入一些標準輸入,我需要對該輸入作出響應,問題在於程序運行的方式可能每天都有所不同,因此我需要解釋標準輸出並相應地重定向標準輸入。C#進程調用,與標準輸入和標準輸出交互

我有這樣一段簡單的代碼,它逐行讀取標準輸出,當它看到提示輸入密碼時,它會發送標準輸入,但程序只是掛起,因爲它從不會看到提示輸入密碼,但是當我運行批處理文件時,密碼提示符就在那裏。

這裏是我打電話要執行這個測試的批處理文件:

@echo off 
echo This is a test of a prompt 
echo At the prompt, Enter a response 
set /P p1=Enter the Password: 
echo you entered "%p1%" 

下面是在命令行中運行時,該批處理文件的輸出:

C:\Projects\SPP\MOSSTester\SPPTester\bin\Debug>test4.bat 
This is a test of a prompt 
At the prompt, Enter a response 
Enter the Password: Test1 
you entered "Test1" 

這裏是C#我用來調用掛起的批處理文件的代碼片段:

var proc = new Process(); 
    proc.StartInfo.FileName = "cmd.exe"; 
    proc.StartInfo.Arguments = "/c test4.bat"; 
    proc.StartInfo.RedirectStandardOutput = true; 
    proc.StartInfo.RedirectStandardError = true; 
    proc.StartInfo.RedirectStandardInput = true; 
    proc.StartInfo.UseShellExecute = false; 
    proc.StartInfo.CreateNoWindow = true; 
    proc.Start(); 
    //read the standard output and look for prompt for password 
    StreamReader sr = proc.StandardOutput; 
    while (!sr.EndOfStream) 
    { 
     string line = sr.ReadLine(); 
     Debug.WriteLine(line); 
     if (line.Contains("Password")) 
     { 
      Debug.WriteLine("Password Prompt Found, Entering Password"); 
      proc.StandardInput.WriteLine("thepassword"); 
     } 
    } 
    sr.Close(); 
    proc.WaitForExit(); 

這裏是調試標準輸出我看到,注意到我從來沒有看到提示輸入密碼,爲什麼?它只是掛起?

This is a test of a prompt 
At the prompt, Enter a response 

有沒有辦法讓我看到提示的標準輸出並據此做出反應?

回答

3

你的主要問題是,你是通過流讀取器使用sr.ReadLine()這個工作是一個問題,因爲提示輸入密碼暫停直到用戶輸入新行(在輸入密碼後點擊進入)。

因此,您需要一次讀取流1字符。這個例子可以幫助你開始。

while (!sr.EndOfStream) 
{ 
    var inputChar = (char)sr.Read(); 
    input.Append(inputChar); 
    if (StringBuilderEndsWith(input, Environment.NewLine)) 
    { 
     var line = input.ToString(); 
     input = new StringBuilder(); 
     Debug.WriteLine(line); 
    } 
    else if (StringBuilderEndsWith(input, "Password:")) 
    { 
     Debug.WriteLine("Password Prompt Found, Entering Password"); 
     proc.StandardInput.WriteLine("thepassword"); 
     var line = input.ToString(); 
     input = new StringBuilder(); 
     Debug.WriteLine(line); 
    } 
} 

private static bool StringBuilderEndsWith(StringBuilder haystack, string needle) 
{ 
    var needleLength = needle.Length - 1; 
    var haystackLength = haystack.Length - 1; 
    for (int i = 0; i < needleLength; i++) 
    { 
     if (haystack[haystackLength - i] != needle[needleLength - i]) 
     { 
      return false; 
     } 
    } 
    return true; 
} 
+0

有趣的是,我曾嘗試閱讀字符之前,但沒有任何運氣,讓我試試這種方法,並回到你身邊,這是合乎邏輯的意義! – Becker

+0

優秀的,只是測試它,這個代碼對於我在做什麼來說非常棒,非常感謝! – Becker

0

使用進程類可以直接運行批處理文件。標準的I/O可能不會得到通過,因爲它要經過CMD第一

proc.StartInfo.FileName = "test4.bat"; 
proc.StartInfo.Arguments = ""; 
相關問題