如果用户单击"关闭"("X")按钮,如何处理PowerShell窗口的关闭事件

JST*_*JST 8 powershell

我想在PowerShell 2.0窗口关闭之前运行一些代码.为此,我试过:

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

如果用户使用exit命令关闭PowerShell窗口(即退出),它可以正常工作.但是如果用户通过点击右上角的关闭('X')按钮关闭它,它就不起作用.

我找不到办法解决这个问题.我也尝试过以下方式,但这也不起作用:

PS> $ query ="选择*来自__InstanceDeletionEvent WITHIN 5 WHERE TargetInstance ISA'Win32_Process'AND 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 | out-file c:\ work\powershellexiteventcalled.txt} -InputObject $ appCurrentDomain -EventName DomainUnload

但同样,它不起作用.根据Microsoft"当AppDomain即将被卸载时发生DomainUnload事件." 但是当我关闭窗口时它不起作用(或者甚至键入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()      
Run Code Online (Sandbox Code Playgroud)

但是我遇到了一个问题......如果我在注册这个处理程序后在控制台上运行任何cmdlet(例如get-date,get-process).然后,只要发生事件,应用程序就会崩溃(例如Ctrl + C,关闭).有人可以帮我这个吗?

Aar*_*sen 2

不幸的是,你不能这样做。唯一一次调用退出事件是在 PowerShell 提示符下键入“exit”。

这就是我连接退出事件的方式:

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

  • PS v3 将窗口关闭按钮挂接到退出事件 (2认同)