Quiero ejecutar algún código antes de que se cierre la ventana de PowerShell 2.0. Para esto probé:Cómo gestionar el evento cerrado de la ventana de PowerShell si el usuario hace clic en el botón Cerrar ('X')
PS> register-engineevent PowerShell.Exiting -action {get-process | archivo externo c: \ work \ powershellexiteventcalled.txt}
Funciona bien si el usuario cierra la ventana de PowerShell con el comando de salida (es decir, sale). Pero no funciona si el usuario lo cierra haciendo clic en el botón Cerrar ('X') en la esquina superior derecha.
No he podido encontrar ninguna manera de manejar esto. También traté de hacerlo de la siguiente manera, pero esto tampoco funciona:
PS> $ query = "Seleccionar * de __InstanceDeletionEvent DENTRO DE 5 WHERE TargetInstance ISA 'Win32_Process' Y TargetInstance.Name = 'powershell.exe'"
PS> Register-WmiEvent -Query $ query -Action {get-process | out-file c: \ work \ powershellexiteventcalled.txt}
Por favor, indique cómo puedo lograr esta tarea.
ACTUALIZACIÓN: Con un poco de entrada útil a partir de un útil en línea profesional que también trató el siguiente:
$ appCurrentDomain = [System.AppDomain] :: CurrentDomain Register-ObjectEvent -Action {Get- proceso | out-file c: \ work \ powershellexiteventcalled.txt} -InputObject $ appCurrentDomain -EventName DomainUnload
Pero, de nuevo, no funciona. Según Microsoft, el evento "DomainUnload ocurre cuando un AppDomain está a punto de descargarse". Pero no funciona cuando cierro la ventana (o incluso escribo exit para ese asunto).
ACTUALIZACIÓN:
Con la ayuda de otros profesionales en línea & un poco de esfuerzo que podría lograr esto con el código siguiente.
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()
PERO Theres un tema que estoy frente a .... Si me quedo cualquier cmdlet en la consola después de registrar este controlador (por ejemplo get-date, get-process). Luego, la aplicación se bloqueará cada vez que ocurra un evento (por ejemplo, Ctrl + C, cierre). ¿Puede alguien ayudarme con esto?
con la ayuda de otros profesionales en línea y un poco de esfuerzo que podría lograr esto con el código siguiente. – JST
PS v3 enganchó el botón de cerrar la ventana hasta el evento de salida – Timbo