2011-08-19 13 views
5

द्वारा बाहरी शेल कमांड परिणाम लाइन प्राप्त करें मैं एक सी # विनफॉर्म एप्लिकेशन लिख रहा हूं जो "डीआईआर" और "पिंग" जैसे खोल कमांड निष्पादित करने के लिए दूसरी प्रक्रिया शुरू करता है। मैं दूसरी प्रक्रिया के आउटपुट को रीडायरेक्ट करता हूं ताकि मेरा ऐप कमांड परिणाम प्राप्त कर सके। यह मोटे तौर पर ठीक काम करता है।सी #: लाइन

एकमात्र समस्या यह है कि मेरा Winform ऐप पंक्ति के अनुसार लाइन के बजाय कमांड लाइन आउटपुट प्राप्त करता है। उदाहरण के लिए, इसे बाहरी "पिंग" कमांड को समाप्त करने के लिए इंतजार करना पड़ता है (जिसमें कई सेकंड या अधिक समय लगता है) और उसके बाद पूरे आउटपुट (कई लाइनें) एक बार में प्राप्त होता है।

मुझे क्या चाहिए यह ऐप वास्तविक समय में cmdline आउटपुट प्राप्त करता है, यानी ब्लॉक द्वारा नहीं। क्या यह करने योग्य है?

मैं उत्पादन को पढ़ने के लिए इस कोड का उपयोग कर रहा हूँ: जबकि (! (परिणाम = proc.StandardOutput.ReadLine()) = नल)

लेकिन यह जिस तरह से मैं उम्मीद काम नहीं करता। अग्रिम धन्यवाद।

संपादित करें:

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

    procStartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

    // The following commands are needed to redirect the standard output. 
    procStartInfo.RedirectStandardOutput = true; 
    procStartInfo.UseShellExecute = false; 
    procStartInfo.CreateNoWindow = true; 
    // Now we create a process, assign its ProcessStartInfo and start it 
    System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
    proc.StartInfo = procStartInfo; 
    proc.Start(); 

    // Get the output into a string 
    string result; 
    try { 
     while ((result = proc.StandardOutput.ReadLine()) != null) 
     { 
      AppendRtfText(result+"\n", Brushes.Black); 
     } 
    } // here I expect it to update the text box line by line in real time 
     // but it does not. 
+1

[संभव डुप्लिकेट] का उपयोग (http://stackoverflow.com/questions/ को पूरा विवरण दिया देने के लिए प्रदान करता है:

इसके अलावा इस समाधान नहीं मिला 415620/रीडायरेक्ट-कंसोल-आउटपुट-टू-टेक्स्टबॉक्स-इन-अलग-प्रोग्राम-सी) –

+0

आपके द्वारा किए गए कोड को दिखाकर सहायक होगा। –

उत्तर

3

रीडली एसिंक पढ़ने के तरीके पर this msdn article में उदाहरण देखें।

परे है कि मैं अपने कोड की उम्मीद अब लाइन द्वारा लाइन को पढ़ने के लिए करता है लेकिन यूआई किसी भी समय फिर से रंगना (लापता Application.DoEvents() नहीं मिलता है; RTFTextBox

+0

धन्यवाद @ एडी, आप सही हैं। लेकिन DoEvents() WPF में उपलब्ध नहीं है। मैंने इस समाधान का उपयोग किया: http://stackoverflow.com/questions/4502037/where-is-the-plication-doevents-in-wpf – Charlie

2

के बजाय पाश while ((result = proc.StandardOutput.ReadLine()) != null) आप का उपयोग करने का होना चाहिए का उपयोग कर: यहाँ कोड मैं का उपयोग कर रहा है

... 
proc.OutputDataReceived += proc_DataReceived; 
proc.Start(); 
proc.BeginOutputReadLine(); 
proc.WaitForExit(); 

यह अतुल्यकालिक लाइनों को पढ़ने के लिए जब वे आता है शुरू कर देंगे, तो आप फिर e.Dataproc_DataReceived हैंडलर में पढ़ने वाली लाइनों को संभाल लें, क्योंकि आप BeginOutputReadlinee.Data का उपयोग कर रहे हैं एक स्ट्रिंग लाइन होगी।

0

मैं एक ही मुद्दा था और चारों ओर यह निम्नलिखित के साथ मिला है। मैंने पाया है कि अगर मैं बाहरी अनुप्रयोग में एक त्रुटि थी मैं सभी में कोई उत्पादन हो रही थी का उपयोग कर ReadToEnd() विधि, इसलिए रेखा स्ट्रीमर द्वारा लाइन का उपयोग करने के लिए स्विच किया गया। साएड द्वारा दिए गए उत्तर का उपयोग करने के लिए स्विचिंग हो जाएगा, हालांकि यह इसे संभालने के उचित तरीके की तरह दिखता है। c# coding convention public/private contexts जो त्रुटि एक ही समय में हैंडलिंग और externalApp.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data);

Process externalApp = new Process(); 
     externalApp.StartInfo.FileName = config.ExternalApps + @"\location\DeleteApp.exe"; 
     externalApp.StartInfo.Arguments = Directory.GetCurrentDirectory() + @"\..\..\..\project\argumentsForDeleteApp.xml"; 
     externalApp.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     externalApp.StartInfo.UseShellExecute = false; 
     externalApp.StartInfo.RedirectStandardOutput = true; 
     Console.Out.WriteLine(DateTime.UtcNow.ToLocalTime().ToString() + 
      ":###### External app: " + externalApp.StartInfo.FileName + " -  START"); 
     externalApp.Start(); 
     using (StreamReader reader = externalApp.StandardOutput) 
     { 
      while (!reader.EndOfStream) 
      { 
       string result = reader.ReadLine(); 
       Console.Out.WriteLine(result); 
      } 
     } 
     externalApp.WaitForExit(); 
संबंधित मुद्दे