2011-12-02 17 views
7

पर क्लिक करता है तो PowerShell विंडो की बंद घटना को कैसे प्रबंधित करें Power Powerhell 2.0 विंडो बंद होने से पहले मैं कुछ कोड चलाने के लिए चाहता हूं। इसके लिए मैंने कोशिश की:यदि उपयोगकर्ता बंद ('एक्स') बटन

पीएस> रजिस्टर-इंजीनियरवे पावरशेल.एक्सिटिंग-एक्शन {get-process | आउट-फाइल c: \ work \ powershellexiteventcalled.txt}

अगर उपयोगकर्ता बाहर निकलने के आदेश (यानी बाहर निकलने) का उपयोग कर PowerShell विंडो बंद करता है तो यह ठीक काम करता है। लेकिन अगर उपयोगकर्ता शीर्ष पर दाएं ('एक्स') बटन पर क्लिक करके इसे बंद कर देता है तो यह काम नहीं करता है।

मुझे इसे संभालने का कोई तरीका नहीं मिला। मैंने इसे निम्न तरीके से करने की भी कोशिश की, लेकिन यह या तो काम नहीं करता है:

पीएस> $ क्वेरी = "__InstanceDeletionEvent से चुनें * 5 में लक्ष्यइंस्टेंस आईएसए 'Win32_Process' और TargetInstance.Name = 'powershell.exe'"

पीएस> रजिस्टर-WmiEvent -Query $ क्वेरी -एक्शन {get-process | आउट-फाइल c: \ work \ powershellexiteventcalled.txt}

कृपया मार्गदर्शन करें कि मैं यह कार्य कैसे प्राप्त कर सकता हूं।


अद्यतन: एक उपयोगी पेशेवर ऑनलाइन से कुछ उपयोगी इनपुट के साथ मैं भी करने की कोशिश की है:

$ appCurrentDomain = [System.AppDomain] :: CurrentDomain रजिस्टर-ObjectEvent कार्रवाई के {मिल- प्रक्रिया | बाहर फ़ाइल c: \ काम \ powershellexiteventcalled.txt} -InputObject $ appCurrentDomain -EventName DomainUnload

लेकिन फिर, यह काम नहीं करता। माइक्रोसॉफ्ट के अनुसार "DomainUnload ईवेंट तब होता है जब कोई ऐपडोमेन अनलोड हो रहा है।"। लेकिन जब मैं खिड़की बंद करता हूं (या उस मामले के लिए बाहर निकलने का भी प्रकार टाइप करता है) यह काम नहीं करता है।

अद्यतन:

अन्य पेशेवरों से कुछ मदद के साथ

ऑनलाइन & एक छोटे से प्रयास मैं इस कोड को निम्न से प्राप्त कर सकते थे।

PS..> $code = @" 

     using System; 
     using System.Runtime.InteropServices; 
     using System.Management.Automation; 
     using System.Management.Automation.Runspaces; 

     namespace MyNamespace 
     { 
      public static class MyClass 
      { 
       public static void SetHandler() 
       { 
        SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true); 
       } 

       private static bool ConsoleCtrlCheck(CtrlTypes ctrlType) 
       { 
        switch (ctrlType) 
        { 
         case CtrlTypes.CTRL_C_EVENT: 
          Console.WriteLine("CTRL+C received!"); 
          return false; 

         case CtrlTypes.CTRL_CLOSE_EVENT: 
          Console.WriteLine("CTRL_CLOSE_EVENT received!"); 
          return true; 

         case CtrlTypes.CTRL_BREAK_EVENT: 
          Console.WriteLine("CTRL+BREAK received!"); 
          return false; 

         case CtrlTypes.CTRL_LOGOFF_EVENT: 
          Console.WriteLine("User is logging off!"); 
          return false; 

         case CtrlTypes.CTRL_SHUTDOWN_EVENT: 
          Console.WriteLine("User is shutting down!"); 
          return false; 
        } 
        return false; 
       } 

       [DllImport("Kernel32")] 
       public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add); 

       // A delegate type to be used as the handler routine 
       // for SetConsoleCtrlHandler. 
       public delegate bool HandlerRoutine(CtrlTypes CtrlType); 

       // An enumerated type for the control messages 
       // sent to the handler routine. 
       public enum CtrlTypes 
       { 
        CTRL_C_EVENT = 0, 
        CTRL_BREAK_EVENT, 
        CTRL_CLOSE_EVENT, 
        CTRL_LOGOFF_EVENT = 5, 
        CTRL_SHUTDOWN_EVENT 
       } 
      } 
     }"@ 

PS..> $text = Add-Type -TypeDefinition $code -Language CSharp 
PS..> $rs = [System.Management.Automation.Runspaces.Runspace]::DefaultRunspace 
PS..> [MyNamespace.MyClass]::SetHandler()  

लेकिन एक मुद्दा मैं का सामना करना पड़ रहा हूँ थेरेस .... यदि मैं यह हैंडलर पंजीकृत करने के बाद कंसोल पर किसी भी cmdlet चलाने (जैसे प्राप्त की तारीख, मिल-प्रक्रिया)। फिर जब भी कोई ईवेंट होता है तो एप्लिकेशन क्रैश हो जाएगा (उदा। Ctrl + C, बंद करें)। क्या कोई भी मेरी इस के साथ मदद कर सकता है?

उत्तर

2

दुर्भाग्य से, आप यह नहीं कर सकते हैं। एक बाहरी घटना को कॉल करने का एकमात्र समय यह होगा कि यदि आप PowerShell प्रॉम्प्ट पर "बाहर निकलें" टाइप करते हैं।

यह कैसे मैं अपने बाहर निकलने घटना ऊपर हुक है:

$null = Register-EngineEvent -SourceIdentifier ` 
    ([System.Management.Automation.PsEngineEvent]::Exiting) -Action { # Put code to run here } 
+0

अन्य पेशेवरों से कुछ मदद के साथ ऑनलाइन और थोड़ा प्रयास मैं निम्नलिखित कोड के साथ इसे प्राप्त कर सकता हूं। – JST

+1

पीएस v3 ने बाहरी घटना – Timbo

0

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

+0

तक विंडो बंद बटन को हुक किया है, मुझे लगता है कि आप इसे कंसोल एप्लिकेशन के साथ बिल्कुल भी संभाल नहीं सकते हैं। तकनीकी रूप से मुझे लगता है कि आप कॉन्होस्ट बंद कर रहे हैं जो उस होस्ट को समाप्त कर देता है जो होस्ट हो रहा है (जो PowerShell होस्ट कर रहा है)। – Joey

1

अनचाहे अपवाद होता है क्योंकि अप्रबंधित विधि के समय तक कचरा संग्रह पहले से ही आपके हैंडलर का निपटारा कर चुका है। आप इसे स्थिर क्षेत्र में संग्रहीत करके प्राप्त कर सकते हैं:

private static HandlerRoutine s_rou; 

public static void SetHandler() 
{ 
    if (s_rou == null) 
    { 
     s_rou = new HandlerRoutine(ConsoleCtrlCheck); 
     SetConsoleCtrlHandler(s_rou, true); 
    } 
} 
संबंधित मुद्दे