2009-09-21 7 views
14

मेरे पास एक एप्लिकेशन ए है कि मैं कॉन्फ़िगरेशन फ़ाइल में किसी उपयोगकर्ता द्वारा निर्दिष्ट मनमाने ढंग से अन्य प्रक्रियाओं को आमंत्रित करने में सक्षम होना चाहता हूं।विंडोज़ पर मनमाने ढंग से उपप्रोकैस चलाएं और अभी भी साफ-सफाई समाप्त करें?

बैच स्क्रिप्ट बी ऐसी एक प्रक्रिया है जिसे उपयोगकर्ता ए बी द्वारा बुलाया जाना चाहते हैं, कुछ पर्यावरण चर सेट करता है, कुछ संदेश दिखाता है और कुछ काम करने के लिए एक कंपाइलर सी को आमंत्रित करता है।

क्या विंडोज़ मनमाने ढंग से प्रक्रियाओं को साफ तरीके से समाप्त करने का एक मानक तरीका प्रदान करता है? मान लें कि ए कंसोल में चलाया जाता है और CTRL + C प्राप्त करता है। क्या यह बी और सी को पास कर सकता है? मान लीजिए कि एक खिड़की में एक रन और उपयोगकर्ता विंडो बंद करने का प्रयास करता है, क्या यह बी और सी को रद्द कर सकता है?

टर्मिनेट प्रोसेस एक विकल्प है, लेकिन बहुत अच्छा नहीं है। यदि ए बी पर टर्मिनेट प्रोसेस का उपयोग करता है, सी चल रहा रहता है। यदि सी लंबे समय से चल रहा है, तो यह खराब समस्याएं पैदा कर सकता है, क्योंकि हम उसी फाइल पर काम करने के लिए सी का एक और उदाहरण शुरू कर सकते हैं जबकि सी का पहला उदाहरण अभी भी काम पर गुप्त रूप से है। इसके अलावा, TerminateProcess के परिणामस्वरूप एक साफ निकास नहीं होता है।

GenerateConsoleCtrlEvent अच्छा लगता है, और जब भी सबकुछ कंसोल में चल रहा है, तो काम कर सकता है, लेकिन प्रलेखन कहता है कि आप केवल अपने कंसोल पर CTRL + C भेज सकते हैं, और अगर कोई विंडो में चल रहा है तो इससे मदद नहीं मिलेगी।

क्या विंडोज़ पर सिगिनट के बराबर कोई समतुल्य है? मुझे इस तरह का एक लेख ढूंढना अच्छा लगेगा: http://www.cons.org/cracauer/sigint.html विंडोज के लिए।

+1

+1 अच्छे प्रश्न के लिए। मजेदार वहाँ कोई जवाब नहीं दिया गया है ... मैं Win32 में सिग्नल की तरह तंत्र के बारे में पता नहीं हूँ। जब मुझे बाल प्रक्रियाओं को सूचित करने की आवश्यकता होती है तो मैंने GUI ऐप्स पर एक WM_CLOSE संदेश पोस्ट किया। कंसोल अनुप्रयोगों के लिए मैंने मुख्य एप्लिकेशन में इनपुट और आउटपुट स्ट्रीम को जोड़कर उन्हें बनाया और जब मैं उन्हें समाप्त करना चाहता था तो मैंने इनपुट स्ट्रीम को बंद कर दिया। बच्चों के बच्चों के लिए, मैंने अपने प्रत्यक्ष बच्चों पर निर्भरता को साफ करने के लिए भरोसा किया :)। –

उत्तर

9

मुझे लगता है कि मैं इस प्रश्न पर थोड़ा देर हो चुकी हूं लेकिन किसी भी समस्या के लिए मैं कुछ भी लिखूंगा।

मेरी समस्या यह है कि मैं अपने आवेदन को जीयूआई एप्लीकेशन बनना चाहता हूं लेकिन निष्पादित प्रक्रियाओं को बिना किसी इंटरैक्टिव कंसोल विंडो के पृष्ठभूमि में चलाया जाना चाहिए।

मैं GenerateConsoleCtrlEvent() का उपयोग करके इसे हल करने में कामयाब रहा। मुश्किल हिस्सा यह है कि दस्तावेज़ीकरण वास्तव में स्पष्ट नहीं है कि इसका उपयोग कैसे किया जा सकता है और इसके साथ नुकसान।

मेरा समाधान here का वर्णन करने पर आधारित है। लेकिन इससे वास्तव में सभी विवरणों को समझाया नहीं गया था, इसलिए यहां काम करने के तरीके के बारे में विवरण दिया गया है।

  1. एक नया सहायक एप्लिकेशन "Helper.exe" बनाएं। यह एप्लिकेशन आपके एप्लिकेशन (अभिभावक) और उस बच्चे की प्रक्रिया के बीच बैठेगा जिसे आप बंद करना चाहते हैं। यह वास्तविक बाल प्रक्रिया भी बनाएगा। आपके पास यह "मध्य व्यक्ति" प्रक्रिया होनी चाहिए या जेनरेट कंसोलक्यूटरइवेंट() विफल हो जाएगी।

  2. अभिभावक से सहायक प्रक्रिया में संवाद करने के लिए किसी प्रकार की आईपीसी तंत्र का उपयोग करें कि सहायक को बाल प्रक्रिया को बंद करना चाहिए। जब सहायक को यह ईवेंट मिलता है तो यह "GenerateConsoleCtrlEvent (CTRL_BREAK, 0)" कहता है जो स्वयं और बच्चे की प्रक्रिया को बंद कर देता है। मैंने इस घटना के लिए एक इवेंट ऑब्जेक्ट का इस्तेमाल किया जो माता-पिता को पूरा करता है जब वह बाल प्रक्रिया को रद्द करना चाहता है।

अपने Helper.exe को बनाने के लिए इसे CREATE_NO_WINDOW और CREATE_NEW_PROCESS_GROUP के साथ बनाएं। और जब बच्चे की प्रक्रिया बनाते हैं तो इसे कोई झंडे (0) के साथ बनाते हैं जिसका अर्थ है कि यह कंसोल को अपने माता-पिता से प्राप्त करेगा। ऐसा करने में विफल होने से यह घटना को अनदेखा कर देगा।

यह बहुत महत्वपूर्ण है कि प्रत्येक चरण इस तरह किया जाता है। मैं सभी अलग-अलग प्रकार के संयोजनों की कोशिश कर रहा हूं लेकिन यह संयोजन एकमात्र ऐसा काम करता है जो काम करता है। आप CTRL_C ईवेंट नहीं भेज सकते हैं।यह सफलता वापस कर देगा लेकिन प्रक्रिया से अनदेखा कर दिया जाएगा। CTRL_BREAK एकमात्र ऐसा काम करता है जो काम करता है। वास्तव में कोई फर्क नहीं पड़ता क्योंकि वे दोनों अंत में ExitProcess() को कॉल करेंगे।

आप जेनरेट कंसोलकूटइवेंट() को बाल प्रक्रिया आईडी की एक प्रक्रिया समूह आईडी के साथ भी कॉल नहीं कर सकते हैं, जिससे सहायक प्रक्रिया को सीधे जारी रखने की इजाजत मिलती है। यह भी असफल हो जाएगा।

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

+3

ध्यान दें कि कोई गारंटी नहीं है कि प्रक्रिया बी या सी Ctrl + C की प्राप्ति पर स्पष्ट रूप से बाहर निकल जाएगी। –

+0

हालांकि कोई गारंटी नहीं है कि एक अनुकरणीय एप्लिकेशन Ctrl + C का जवाब देगा, अगर यह दिया जाता है कि लक्षित एप्लिकेशन वास्तव में ctrl + c के जवाब में स्पष्ट रूप से समाप्त करने के लिए जाना जाता है, तो इस विधि के बारे में जानना महत्वपूर्ण है, जो कारण हो सकता है इस तरह के ज्ञात आवेदन को साफ करने के लिए। – Triynko

+0

स्वीकृत उत्तर @KindDragon –

8

जैसा कि @ शक्ता ने कहा GenerateConsoleCtrlEvent() बहुत मुश्किल है, लेकिन आप बिना किसी प्रक्रिया के Ctrl + C भेज सकते हैं।

void SendControlC(int pid) 
{ 
    AttachConsole(pid); // attach to process console 
    SetConsoleCtrlHandler(NULL, TRUE); // disable Control+C handling for our app 
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); // generate Control+C event 
} 
+0

से एक होना चाहिए यह बहुत उपयोगी था! केवल एक चीज गायब है - आपको अटैचकंसोल का उपयोग करने से पहले फ्रीकंसोल को कॉल करना होगा, अन्यथा आपको ERROR_ACCESS_DENIED (5) मिल जाएगा क्योंकि कॉलिंग प्रक्रिया पहले से ही कंसोल से जुड़ी है। – Yael

+0

यह एक दर्जन प्रश्नों में से एकमात्र उत्तर है जिसने मेरे लिए कोई सफलता प्राप्त की है, धन्यवाद! –

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