Как обрабатывать событие закрытия окна PowerShell, если пользователь нажимает кнопку «Закрыть» ('X')

Я хочу запустить некоторый код до закрытия окна PowerShell 2.0. Для этого я попробовал:

PS> register-engineevent PowerShell.Exiting -action {get-process | out-file c: \ work \ powershellexiteventcalled.txt}

Он отлично работает, если пользователь закрывает окно PowerShell с помощью команды выхода (т.е. выхода). Но это не сработает, если пользователь закроет его, нажав кнопку «Закрыть» ('X') в правом верхнем углу.

Я не мог найти способ справиться с этим. Я также пытался сделать это следующим образом, но это тоже не сработало:

PS> $ query = "Select * from __InstanceDeletionEvent ВНУТРИ 5 ГДЕ TargetInstance ISA 'Win32_Process' И TargetInstance.Name = 'powershell.exe'"

​​PS> Register-WmiEvent -Query $ query -Action {get-process | out-file c: \ work \ powershellexiteventcalled.txt}

Пожалуйста, расскажите, как я могу выполнить эту задачу.


ОБНОВЛЕНИЕ: Благодаря полезной информации от полезного профессионала в Интернете я также попробовал следующее:

$ appCurrentDomain = [System.AppDomain] :: CurrentDomain Register-ObjectEvent -Action {get-process | исходящий файл c: \ work \ powershellexiteventcalled.txt} -InputObject $ appCurrentDomain -EventName DomainUnload

Но опять же, это не работает. Согласно Microsoft «событие DomainUnload происходит, когда AppDomain вот-вот будет выгружен». Но это не работает, когда я закрываю окно (или даже набираю exit, если на то пошло).

ОБНОВЛЕНИЕ:

С некоторой помощью других онлайн-профессионалов и небольшими усилиями я смог добиться этого с помощью следующего кода.

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()      

НО ЕСТЬ ВОПРОС, КОТОРЫЙ МНЕ ПРЕДНАЗНАЧЕН .... Если я запускаю какой-либо командлет на консоли после регистрации этого обработчика (например, get-date, get-process). Тогда приложение выйдет из строя всякий раз, когда произойдет событие (например, Ctrl + C, закрыть). Может кто-нибудь помочь мне с этим?

8
задан JST 9 December 2011 в 10:37
поделиться