2010-07-24 17 views
6

मैं जो करना चाहता हूं वह है कि विजुअल स्टूडियो अपनी आउटपुट विंडो या अन्य एडिटर में अन्य टूलर्स में क्या करता है: मेरी प्रक्रिया ए से एक और प्रक्रिया बी शुरू करें और अपने stdout/stderr आउटपुट को कैप्चर करें।विलंब के बिना Win32 में किसी अन्य प्रक्रिया से stdout कैप्चर कैसे करें?

अब तक, मुझे CreatePipe() के साथ काम मिल गया है, लेकिन किसी कारण से, बी के आउटपुट बी पर सही होने पर बी पर नहीं पहुंचते हैं। यह किसी प्रकार के बफर की तरह अधिक व्यवहार करता है और जब यह पूरा हो जाता है, तो सभी बफर सामग्री एक बार में ए में आती है। मैंने अपना खुद का टेस्ट प्रोग्राम लिखा है जो कुछ आउटपुट करता है और बाद में fflush(stdout) करता है। फिर आउटपुट सीधे ए पर आता है लेकिन मैं उन सभी बी प्रक्रियाओं का कोड नहीं बदल सकता जो मैं इस तरह उपयोग करना चाहता हूं। ए से पाइप फ्लश करने की कोशिश भी काम नहीं करता है।

यह कैसे काम करना चाहिए?

मेरे प्रवर्तन कोड के साथ-साथ उपभोक्ता कोड:

sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
sa.bInheritHandle = TRUE; 
sa.lpSecurityDescriptor = NULL; 

err = CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &sa, stdouthistory); 
if (err == 0) 
    return 1; 
err = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, 
         GetCurrentProcess(), &hChildStdoutRdDup , 0, 
         FALSE, 
         DUPLICATE_SAME_ACCESS); 
if (err == 0) 
    return 3; 
CloseHandle(hChildStdoutRd); 

DWORD a, b, c; 
a = PIPE_READMODE_BYTE | PIPE_NOWAIT; 
b = 0; 
c = 0; 
SetNamedPipeHandleState(hChildStdoutRdDup, &a, &b, &c); 

err = CreatePipe(&hChildStdinRd, &hChildStdinWr, &sa, stdinhistory); 
if (err == 0) 
    return 1; 
err = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, 
         GetCurrentProcess(), &hChildStdinWrDup , 0, 
         FALSE, 
         DUPLICATE_SAME_ACCESS); 
if (err == 0) 
    return 4; 
CloseHandle(hChildStdinWr); 

a = PIPE_READMODE_BYTE | PIPE_NOWAIT; 
b = 0; 
c = 0; 

ZeroMemory(&si,sizeof(STARTUPINFO)); 
si.cb = sizeof(STARTUPINFO); 
si.dwFlags = STARTF_USESTDHANDLES; 
si.wShowWindow = SW_SHOW; 

si.hStdOutput = hChildStdoutWr; 
si.hStdError = hChildStdoutWr; 
si.hStdInput = hChildStdinRd; 

ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); 

err = CreateProcess(0, this->cmdline, 0, 0, true, CREATE_NO_WINDOW, 0, 0, &si, &pi); 
if (err == 0) 
    return 4; 

की खपत:

DWORD avail; 
unsigned int ofs = 0; 
if (PeekNamedPipe(hChildStdoutRdDup, NULL, 0, NULL, &avail, NULL)) 
{ 
    if (avail != 0) 
    { 
     int err = ReadFile(hChildStdoutRdDup, s + ofs, slen, &threadbuffern, 0); 
          // Consume ... 
    } 
} 

संपादित करें: Continuously read from STDOUT of external process in Ruby: मैं सिर्फ इस सवाल का पाया। यह वही समस्या है, लेकिन रुबी के संदर्भ में। अफसोस की बात है कि समाधान कुछ रूबी लाइब्रेरी का उपयोग करना था जो इसे काम करता है। यह पुस्तकालय यह कैसे करता है? Win32/C++ में समतुल्य क्या है?

+1

जुड़ा हुआ धागा एक * निक्स समाधान है। Win32 में कुछ भी समान नहीं है। –

+0

आप कैसे जानते हैं कि यह केवल यूनिक्स से संबंधित है? यह भी ध्यान दें कि विंडोज़ पर प्रोग्राम मौजूद हैं जो इसे अच्छी तरह से बंद कर सकते हैं - बंद स्रोत वाले:/ – marc40000

उत्तर

3

आप ऐसा नहीं कर सकते हैं। अगर उत्पादन को आपत्तिजनक प्रक्रिया में फहराया नहीं गया है, तो इसे वास्तव में पहले स्थान पर नहीं लिखा गया है। यही है, ओएस ने अभी तक लक्ष्य प्रक्रिया से डेटा भी प्राप्त नहीं किया है।

यह पाइप के साथ किसी भी प्रकार की अंतर्निहित विलंबता नहीं है, यह है कि जिन प्रोग्रामों की आप निगरानी कर रहे हैं, वे वास्तव में इसे अभी तक पाइप में नहीं लिखे हैं।

आपको प्रोग्रामों को निष्पादित करते समय कमांड प्रॉम्प्ट के लिए सटीक वही व्यवहार नोटिस करना चाहिए, क्योंकि कमांड प्रॉम्प्ट आपके द्वारा उपयोग किए जा रहे उसी पाइप समाधान का उपयोग करता है। यदि ऐसा नहीं है क्योंकि प्रश्न में प्रोग्राम यह पता लगा रहे हैं कि वे कंसोल हैंडल की बजाय फ़ाइल हैंडल पर लिख रहे हैं, और अतिरिक्त बफरिंग कर रहे हैं।

+0

हम्म, वे इसका पता कैसे लगाते हैं? क्या मैं उसके आसपास काम कर सकता हूँ? मेरे द्वारा पोस्ट किए गए दूसरे प्रश्न के लिंक में वह रूबी लाइब्रेरी ऐसा करने में सक्षम है। – marc40000

+0

@marc: 1. रूबी लाइब्रेरी विंडोज़ पर नहीं थी। 2. रूबी पुस्तकालय एक अलग कार्यक्रम को नियंत्रित नहीं कर सकता/हो सकता है। रूबी में वास्तविक पुस्तकालय की आवश्यकता नियंत्रित अनुप्रयोग की सीमा नहीं, रूबी की सीमा के कारण है। इस प्रकार एक पुस्तकालय इसे ठीक करने में सक्षम था। –

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