2009-05-08 12 views
9

की अंतिम प्रक्रिया को संभालना क्या एक ही विंडोज़ एप्लिकेशन के भीतर विंडोज़ एप्लिकेशन की टास्क मैनेजर एंड प्रक्रिया को कैप्चर करना संभव है? मैं एक सी # 2.0 जीत ऐप का उपयोग कर रहा हूं और मैं कुछ डेटाबेस प्रोसेसिंग करना चाहता हूं (डीबी में 'वाई' से 'एन' तक एक ध्वज बदलें) जब एक अंत प्रक्रिया होती है।विंडोज ऐप

उत्तर

10

नहीं, प्रक्रिया को समाप्त करने के लिए ऑपरेटिंग सिस्टम के निर्णय को हुक करना संभव नहीं है। ध्यान दें, यह कार्य प्रबंधक द्वारा नहीं किया जाता है, एक प्रक्रिया समाप्त करना कर्नेल की ज़िम्मेदारी है।

आप यहाँ दो काम करने की आवश्यकता होगी: सामान्य यूजर इंटरफेस संदेशों कि बाहर निकलने के लिए एक आवेदन बताने के लिए

  1. कनेक्ट ईवेंट हैंडलर्स। डेटा, मुक्त संसाधनों को जारी रखने के लिए इन घटनाओं का उपयोग करें, और अन्यथा साफ से बाहर निकलें।
  2. त्रुटियों को पकड़ने के लिए उपयुक्त अपवाद को संभालें और यदि संभव हो तो डेटा को साफ़ करें और सहेजें।

रेमंड के ब्लॉग के तीन लिंक यहां बताते हैं कि आप जो भी पूछ रहे हैं वह क्यों नहीं कर सकते हैं।

इसके अलावा, मैं एक ऐसी ही StackOverflow सवाल here को संबोधित किया।

+0

हां, मैं ईवेंट हैंडलिंग कर सकता हूं। हालांकि, यदि उपयोगकर्ता कार्य प्रबंधक से अंत प्रक्रिया करता है, तो उसे अभी भी डेटाबेस में "लॉग इन" के रूप में फ़्लैग किया जाएगा और जब वह फिर से लॉगिन करने का प्रयास करेगा, तो उसे अनुमति नहीं दी जाएगी। अब मुझे पता है कि अंत प्रक्रिया संदेश कहता है कि 'आप किसी भी सहेजे गए डेटा को सहेज नहीं सकते ... आदि) –

+0

दाएं - यह डिज़ाइन द्वारा है। कल्पना कीजिए कि क्या विंडोज़ ऐप को टर्मिनेट प्रोसेस() पर कॉल को हुक करने देता है, जो कि कार्य प्रबंधक है उपयोग करता है। कार्य शेड्यूलर को सामान्य प्रक्रिया के लिए सामान्य रूप से उपयोग करने के लिए डिज़ाइन नहीं किया गया है - इसकी एक बंदूक - यह प्रक्रियाओं को मारने का इरादा है, उन्हें व्यवस्थित तरीके से समाप्त नहीं करती है। आपका इरादा महान है! सभी प्रक्रियाओं को साफ करने की कोशिश करनी चाहिए और डेटा को विश्वसनीय रूप से जारी रखें, लेकिन यदि उपयोगकर्ता आपकी प्रक्रिया को रोकना चाहता है, तो TerminateProcess() ठीक उसी समय और वहां करेगा। – Foredecker

+0

यह सब रश्मी पी जैसे पेड़ से जंगल नहीं देखता है। डीबी कनेक्शन को समय-समय पर सर्वर-साइड की आवश्यकता होती है। नई प्रक्रिया नए कनेक्शन का निर्माण करेगी, ergo no problem-o। – GregC

1

आप क्या कर सकते हैं प्रक्रिया आईडी प्राप्त करें और प्रक्रिया की निगरानी करें और आप यह जांचने के लिए HasExited संपत्ति का उपयोग कर सकते हैं कि प्रक्रिया समाप्त हो गई है या नहीं। नीचे एक त्वरित VB कोड (मुझे माफ करना मैं अब वी.एस. नहीं है। यह एक और मंच में मेरे द्वारा लिखा गया था)

Public Class Form1 
    Dim p As ProcessStartInfo 
    Dim process As Process 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     p = New ProcessStartInfo("iexplore.exe") 
     process = process.Start(p) 
    End Sub 

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click 
     MsgBox(process.Id) 
     If process.HasExited Then 
      MsgBox("yes") 
     Else 
      MsgBox("no") 
     End If 
    End Sub 
End Class 

कोड से ऊपर InternetExplorer और बटन की जाँच करता प्रक्रिया अंत नहीं है या नहीं शुरू होता है। आप सभी चल रही प्रक्रिया को प्राप्त करने और processID का उपयोग करने के लिए एक समान प्रक्रिया का उपयोग कर सकते हैं।

+0

हे Shoban, मैं एक बाहरी अनुप्रयोग अंत प्रक्रिया (iexplorem नोटपैड, आदि) का उपयोग कर सकते हैं पर कब्जा तुम्हारा कोड।लेकिन मुझे उसी ऐप पर अंतिम कार्य को कैप्चर करने के लिए क्या करना चाहिए (उसमें एक उपरोक्त यूआर कोड में फॉर्म 1 है) –

+0

उन्होंने कहा, "उसी विंडोज़ एप्लिकेशन के भीतर ही"। –

+1

आप इसे एक ही ऐप में नहीं कर सकते हैं, इसलिए शोबन का विचार उतना करीब है जितना आप प्राप्त कर सकते हैं। – RichieHindle

1

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

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

3

कैसे एक अलग दृष्टिकोण के बारे में:

आपके आवेदन उदाहरण, एक दिनांक समय क्षेत्र अद्यतन है LastPollDate प्रत्येक बार चलते समय अक्सर, और एक अलग फ़ील्ड उदा। "AppTerminatedNormally" जिसे आपने एन पर सेट किया है, और यदि आप एक फॉर्म बंद ईवेंट प्राप्त करते हैं तो वाई में बदलें।

यदि कार्य प्रबंधक के माध्यम से ऐप मारा जाता है, तो तिथि अब और अपडेट नहीं की जाएगी, और आपका ऐपटार्मिनेटेड सामान्य रूप से अभी भी नहीं होगा।

इस तरह आप एक ऐसी क्वेरी चला सकते हैं जो सभी पंक्तियों को पाता है जहां LastPollDate 10 मिनट से अधिक पुराना है और AppTerminated सामान्य रूप से एन है, और आपके पास असामान्य रूप से समाप्त होने वाले सभी सत्र होंगे।

+0

यह जाने का अच्छा तरीका है। धन्यवाद – Sakthivel

2

आप सभी इस पोस्ट पर थूकने वाले हैं, लेकिन यहां जाता है ...

आप गलत स्तर पर समस्या को हल करने का प्रयास कर रहे हैं (यानी आपके ऐप में कोड चलाना जब कर्नल ऐप को मार रहा हो)। वास्तविक समस्या यह सुनिश्चित करने के बारे में है कि डेटाबेस सही ढंग से इसके क्लाइंट एप्लिकेशन की उपस्थिति (या अनुपस्थिति) को प्रतिबिंबित करता है।

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

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

यदि आप पूरी तरह से बाहर निकलें (जो पता लगाने के लिए एक उपयोगकर्ता में हो या ना किया गया है या नहीं इस्तेमाल किया एक पैटर्न के विशिष्ट लगता है) पर डेटाबेस में एक झंडा स्थापित करने के लिए है, तो निम्न विकल्पों में से किसी पर विचार करें:

  1. समय-समय पर (शायद हर 30 सेकंड में) डेटाबेस में टाइमस्टैम्प-जैसी फ़ील्ड डालें/अपडेट करें, यह इंगित करने के लिए कि हाल ही में एक एप्लिकेशन ऑनलाइन कैसे था। अन्य एप्लिकेशन यह निर्धारित करने के लिए इन टाइमस्टैम्प का निरीक्षण कर सकते हैं कि हाल ही में एक और एप्लिकेशन ऑनलाइन कैसे था ... यदि मान पिछले 30 सेकंड के भीतर है, तो अन्य ऐप अभी भी opnline है।

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

ध्यान दें कि उपरोक्त सुझावों के दोनों वास्तविक समस्या का समाधान (का पता लगाने के अनुप्रयोगों डेटाबेस तक पहुँच रहे हैं या नहीं) कभी एक "incongruent राज्य" में डेटाबेस से बाहर निकले बिना (ऊपर उल्लिखित झंडा है "Y" जब अनुप्रयोग है वास्तव में मृत और ध्वज "एन" होना चाहिए)।

2

आप Windows Vista (या ऊपर) आप RegisterApplicationRecoveryCallback एपीआई में रुचि हो सकती लक्षित कर रहे हैं ...

http://msdn.microsoft.com/en-us/library/aa373345.aspx

यह आप अपने एप्लिकेशन में एक कॉलबैक दिनचर्या है कि सक्रिय किया जाएगा निर्दिष्ट कर सकते हैं जब प्रक्रिया दुर्घटनाग्रस्त हो रही है। N.B. यह केवल दुर्घटनाओं के लिए है, और प्रक्रिया को जानबूझ कर मारने पर स्वचालित रूप से नहीं बुलाया जाएगा।

आप इस एपीआई को सी # (मैंने इसे किया है) से पी/इनका कर सकते हैं, लेकिन ध्यान रखें कि जब आपका कॉलबैक लागू होता है तो आपका ऐप पहले से ही बहुत खराब स्थिति में है, और आप इसके बारे में बहुत कम धारणाएं बना सकते हैं आपकी याददाश्त की स्थिति यदि आपके पास इस दिनचर्या में कोई भी मेमोरी डेटा है जिसका उपयोग आप करना चाहते हैं, तो मैं इसे एक सामान्य सामान्य दायरे में स्थिर रखूंगा ताकि आपके पास कॉलबैक रूटीन होने पर "tidied" न होने का सबसे अच्छा मौका हो रन।

कुछ अन्य दिलचस्प एपीआई, इससे संबंधित, आदि है कि आप स्वचालित रूप से एक विफलता के बाद अपने एप्लिकेशन को पुनः प्रारंभ अनुमति देते हैं

+0

हे मार्टिन धन्यवाद ... मैं इस में एक नज़र रखना होगा :) –

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