2016-08-17 103 views
2

我有一個連接到ST-Link的程序。此刻,您可以從組合框中選擇固件,按下啓動鍵,它會將固件編程到與ST-Link相連的電路板上。無法從CLI讀取數據

爲此,我使用CLI使用ST-LINK_CLI.exe向ST-Link發送命令。固件編程後,它會在命令提示符下出現:「運行應用程序退出」。在這裏用戶按下Enter鍵,應用程序在板上運行,CLI退出。

但是,我需要做的是沒有提示用戶按下輸入,並自動做到這一點。

我的想法是從CLI讀取輸出,並找出用戶提示時的輸出結果。我想我可以做一個循環,輸出數據被讀入,當用戶必須按下輸入時它與輸出數據相匹配,我將使用SendKeys.Send(「{ENTER}」)。

但是,我無法讀取數據。以下是不工作:

 string STPath = @"C:\Users\Falconex\Documents\FalconexTest\FalconexTest\ST-LINK Utility\ST-LINK_CLI.exe"; 
     string path2 = @"C:\Users\Falconex\Documents\FalconexTest\FalconexTest\Firmware\PXL3-DELL-2B.SREC"; 

     Process p = new Process(); 
     p.StartInfo.FileName = STPath; 
     p.StartInfo.Arguments = "-ME -p " + firmwareLocation + " -v -Run "; 
     p.StartInfo.RedirectStandardOutput = true; 
     p.StartInfo.RedirectStandardInput = true; 
     p.StartInfo.UseShellExecute = false; 
     p.StartInfo.CreateNoWindow = false; 

     p.Start(); 
     p.BeginOutputReadLine(); 
     p.WaitForExit(); 

     while (!p.StandardOutput.EndOfStream) 
     { 

      string line = p.StandardOutput.ReadLine(); 
      File.WriteAllText("New.txt", line); 

     } 

以下是出現的錯誤消息: 「‘System.InvalidOperationException’類型的未處理的異常出現在System.dll中和點流部分的結束。

我想知道是否有人知道爲什麼這發生?或者,如果有周圍的提示問題的另一種方式?

感謝 露西

回答

0

可能還沒有到最好的辦法做到這一點,但要讓它在沒有用戶的情況下退出並且仍然運行,我只是不斷地向它發送回車鍵直到它退出。

while (process.HasExited == false) 
       { 
        SendKeys.SendWait("{ENTER}"); 
       } 
+0

這是一個繁忙的循環?如果是這樣,爲了限制發送的按鍵量和CPU使用量,增加一個「睡眠」呼叫(可能是50毫秒)可能是一個好主意。 –

+0

這是一個好主意,謝謝 – lucycopp

1

如果CLI應用程序使用標準I/O,你可以只寫輸入流:

p.StandardInput.WriteLine(); 

還要注意的是,當您重定向數據流,你必須讀取它們。在你的情況下,你只能讀一行,然後等待程序退出。如果程序打印出更多適合緩衝區的文本,則會發生死鎖。只要擺脫p.WaitForExit(),這是毫無意義和危險的。

1

由於p.BeginOutputReadLine()啓動了異步讀取,因此您將得到異常。這通常會在處理outputdatareceived事件時結束。

但是,您不處理此事件,因爲異步事件長時間運行,並且在發生與ReadLine()的同步調用時未完成,這與異步讀取不兼容。

我懷疑你需要的是像這樣的東西來取代你的代碼:

string STPath = @"C:\Users\Falconex\Documents\FalconexTest\FalconexTest\ST-LINK Utility\ST-LINK_CLI.exe"; 
    string path2 = @"C:\Users\Falconex\Documents\FalconexTest\FalconexTest\Firmware\PXL3-DELL-2B.SREC"; 

    using (Process p = new Process()) 
    { 
     p.StartInfo.FileName = STPath; 
     p.StartInfo.Arguments = "-ME -p " + firmwareLocation + " -v -Run "; 
     p.StartInfo.RedirectStandardOutput = true; 
     p.StartInfo.RedirectStandardInput = true; 
     p.StartInfo.UseShellExecute = false; 
     p.StartInfo.CreateNoWindow = false; 

     p.Start(); 

     while (!p.StandardOutput.EndOfStream) 
     { 
      string line = p.StandardOutput.ReadLine(); 
      Console.WriteLine(line); 
      if (line == "run application to exit") 
      { 
       p.StandardInput.WriteLine(); 
      } 
     } 

     p.WaitForExit(); 
    }