2009-10-09 21 views
8

मैंने देशी Win32 API का उपयोग कर एक विंडोज़ एप्लिकेशन लिखा है। मेरा ऐप अन्य प्रक्रियाओं को लॉन्च करेगा और आउटपुट कैप्चर करेगा और लाल रंग में stderr आउटपुट को हाइलाइट करेगा।क्या मैं अलग-अलग stdout/stderr को कैप्चर कर सकता हूं और मूल ऑर्डर बनाए रख सकता हूं?

इसे पूरा करने के लिए मैं stdout और stderr के लिए एक अलग पाइप बनाता हूं और CreateProcess को कॉल करते समय STARTUPINFO संरचना में उनका उपयोग करता हूं। इसके बाद मैं प्रत्येक stdout/stderr हैंडल के लिए एक अलग थ्रेड लॉन्च करता हूं जो पाइप से पढ़ता है और आउटपुट को विंडो में लॉग करता है।

यह ज्यादातर मामलों में ठीक काम करता है। मेरी समस्या यह है कि यदि बच्चे की प्रक्रिया त्वरित उत्तराधिकार में stderr और stdout पर लॉग इन करती है, तो मेरा ऐप कभी-कभी गलत क्रम में आउटपुट प्रदर्शित करेगा। मुझे लगता है कि यह प्रत्येक हैंडल से पढ़ने के लिए दो धागे का उपयोग करने के कारण है।

क्या उन दोनों के बीच अंतर करने में सक्षम होने के दौरान, मूल क्रम में stdout और stderr को कैप्चर करना संभव है?

उत्तर

3

मुझे पूरा यकीन है कि इसे नहीं किया जा सकता है, स्पैन्ड प्रोग्राम लिखने के लिए पैकेट में लिखने और प्रत्येक को टाइम-स्टैंप जोड़ने के लिए। इसके बिना, आप आम तौर पर बाल प्रक्रिया की मानक लाइब्रेरी में होने वाली बफरिंग पर योजना बना सकते हैं, इसलिए जब तक वे पाइप के माध्यम से माता-पिता को भी प्रसारित कर रहे हों, तब तक यह एक अच्छा मौका है कि वे पहले से ही आदेश से बाहर हैं।

+0

हां, यह दृष्टिकोण है लेकिन मैं ओप को यह बताने के लिए पर्याप्त बहादुर नहीं था कि खुले मंच में ऐसा करने की कोशिश करने के लिए बहुत से वोट वोट अनिवार्य परिणाम हैं। –

+0

यह कैसे सच हो सकता है? CMD.exe हमेशा यह सही कैसे लगता है? – paulm

+0

ऐसा लगता है कि यह किया जा सकता है लेकिन यह जानना संभव नहीं है कि कौन सी स्ट्रीम लिखी गई थी: http://stackoverflow.com/questions/18529662/capture-process-stdout-and-stderr-in-the-correct-ordering – paulm

0

वास्तव में, आप ऐसा नहीं सोचेंगे लेकिन std_out सिस्टम डिजाइनरों के नियंत्रण में है - ठीक है और कब std_out लिखा जाता है सिस्टम शेड्यूलर के अधीन है, जो मेरे परीक्षण द्वारा उन मुद्दों के अधीन है जो दस्तावेज के रूप में नहीं हैं।

मैं एक दिन कुछ सामान लिख रहा था और सिस्टम में डिवाइसों में से एक पर कुछ काम किया था, जबकि मेरे पास संपादक में कोड खुला था और पता चला कि सिस्टम ड्राइवर को वास्तविक समय प्राथमिकता दे रहा था, मेरी सावधानी से छोड़कर स्वामित्व वाले कोड के रूप में कहीं भी दसवीं के रूप में महत्वपूर्ण सी-कोड।

पुन: इनवर्टर करना ताकि आपको लिखने का क्रमिक क्रम प्राप्त हो, कम से कम कहने के लिए चुनौतीपूर्ण होगा।

0

आप के लिए stdout stderr अनुप्रेषित कर सकते हैं:

command_name 2>&1

यह, पाइप का उपयोग कर के रूप में मुझे याद है सी में संभव है।

अद्यतन: ओह, क्षमा करें - दोनों के बीच अंतर करने में सक्षम होने के बारे में हिस्सा याद किया। मुझे पता है कि टेक्स्टमैट ने इसे किसी भी तरह से उपयोगकर्ता के दृश्य कोड का उपयोग किया है ... थोड़ी देर के लिए नहीं देखा है, लेकिन मैं इसे एक झलक दे दूंगा। लेकिन कुछ और विचारों के बाद, क्या आप रुबी में Open3 जैसे कुछ उपयोग कर सकते हैं? आपको एक ही समय में STDOUT और STDERR दोनों देखना होगा, लेकिन वास्तव में इन दोनों के संबंध में आउटपुट के निश्चित आदेश की अपेक्षा नहीं करनी चाहिए।

अद्यतन 2: मैं रूबी में क्या मतलब का उदाहरण:

require 'open3' 

Open3.popen3('ruby print3.rb') do |stdin, stdout, stderr| 
    loop do 
    puts stdout.gets 
    puts stderr.gets 
    end 
end 

... print3.rb सिर्फ वह जगह है जहाँ:

loop do 
    $stdout.puts 'hello from stdout' 
    $stderr.puts 'hello from stderr' 
end 

इसके बजाय सीधे puts के उत्पादन फेंकने की, तो आप एक भेज सकता है एक पर्यवेक्षक को संदेश जो आपके कार्यक्रम में इसे प्रिंट करेगा। क्षमा करें, मेरे पास इस मशीन पर विंडोज नहीं है (या कोई भी तत्काल उपलब्ध है), लेकिन मुझे उम्मीद है कि यह अवधारणा को दर्शाता है।

0

मुझे पूरा यकीन है कि अगर आप उन्हें अलग नहीं करते हैं, तो भी आपको गारंटी नहीं है कि वे सही क्रम में एक-दूसरे का आदान-प्रदान करेंगे।

2

मैंने देखा है कि stdout और stderr के अधिकांश कार्यान्वयन में, stdout buffered है और stderr नहीं है। असल में इसका मतलब यह है कि आपको गारंटी नहीं है कि वे सीधे कमांड लाइन पर प्रोग्राम चलाते समय भी क्रम में होने जा रहे हैं।

http://en.wikipedia.org/wiki/Stderr#Standard_error_.28stderr.29

संक्षिप्त उत्तर: आप सुनिश्चित नहीं कर सकते कि आप एक ही क्रम में लाइनों पढ़ा है कि वे cmd.exe पर प्रकट क्योंकि जिस क्रम में वे cmd.exe पर प्रकट इसकी गारंटी नहीं है।

0

चूंकि आउटपुट एक मौजूदा प्रोग्राम के आउटपुट को एनोटेट करना है, इसलिए दो धाराओं के किसी भी संभावित इंटरलिविंग को सही होना चाहिए। मूल डेवलपर ने यह सुनिश्चित करने के लिए उचित फ्लश() कॉल रखे होंगे कि किसी भी अनिवार्य आदेश को सम्मानित किया जाए।

जैसा कि पहले समझाया गया था, एक समय टिकट के साथ लिखे गए प्रत्येक टुकड़े को रिकॉर्ड करें, और आउटपुट उपकरणों द्वारा वास्तव में देखे गए अनुक्रम को पुनर्प्राप्त करने के लिए इसका उपयोग करें।

संबंधित मुद्दे

 संबंधित मुद्दे