Desidero eseguire un codice prima che la finestra di PowerShell 2.0 venga chiusa. Per questo ho provato:Come gestire l'evento di chiusura della finestra di PowerShell se l'utente fa clic sul pulsante Chiudi ('X')
PS> register-engineevent PowerShell.Exiting -action {get-process | out-file c: \ work \ powershellexiteventcalled.txt}
Funziona correttamente se l'utente chiude la finestra di PowerShell utilizzando il comando exit (es. uscita). Ma non funziona se l'utente lo chiude facendo clic sul pulsante Chiudi ('X') in alto a destra.
Non ho trovato alcun modo per gestire questo. Ho anche provato a farlo nel seguente modo, ma questo non funziona neanche:
PS> $ query = "Seleziona * da __InstanceDeletionEvent ENTRO 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}
Per favore, guida come posso ottenere questo compito.
UPDATE: Con qualche utile contributo da una linea professionale utile Ho anche provato il seguente:
$ appCurrentDomain = [System.AppDomain] :: CurrentDomain Register-ObjectEvent -Action {get processo | out-file C: \ lavoro \ powershellexiteventcalled.txt} -InputObject $ appCurrentDomain -EventName DomainUnload
Ma ancora una volta, non funziona. Come da Microsoft "l'evento DomainUnload si verifica quando un AppDomain sta per essere scaricato". Ma non funziona quando chiudo la finestra (o anche scrivo exit per quella materia).
UPDATE:
con qualche aiuto da altri professionisti in linea & un piccolo sforzo ho potuto raggiungere questo obiettivo con codice seguente.
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()
ma c'è una questione che sto affrontando .... Se eseguo qualsiasi cmdlet su console dopo aver registrato questo gestore (ad esempio get-date, get-processo). Quindi l'applicazione si blocca ogni volta che si verifica un evento (ad esempio Ctrl + C, chiuso). Qualcuno può aiutarmi per favore con questo?
con qualche aiuto da altri professionisti in linea e un piccolo sforzo che potrebbe raggiungere questo obiettivo con codice seguente. – JST
PS v3 ha agganciato il pulsante di chiusura della finestra fino all'evento in uscita – Timbo