Chcę uruchomić kod, zanim okno PowerShell 2.0 zostanie zamknięte. Do tego próbowałem:Jak obsługiwać zdarzenie close okna PowerShell, jeśli użytkownik kliknie przycisk Zamknij ("X")
PS> register-engineevent PowerShell.Exiting -action {get-process | out-file c: \ work \ powershellexiteventcalled.txt}
Działa poprawnie jeśli użytkownik zamyka okno PowerShell za pomocą polecenia exit (tzn. exit). Ale to nie działa, jeśli użytkownik zamyka go, klikając przycisk Zamknij ("X") w prawym górnym rogu.
Nie mogłem znaleźć żadnego sposobu, aby sobie z tym poradzić. Próbowałem też zrobić to w następujący sposób, ale to też nie działa:
PS> $ query = "Wybierz * z __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}
Proszę wskazać, w jaki sposób mogę osiągnąć to zadanie.
UPDATE: Z jakiegoś użytecznego wkładu ze strony pomocnego profesjonalnego Online Próbowałem również:
$ appCurrentDomain = [System.AppDomain] :: currentDomain Rejestracja-ObjectEvent -action {korzystać z telefonu proces | out-file C: \ praca \ powershellexiteventcalled.txt} -InputObject $ appCurrentDomain -EventName DomainUnload
Ale znowu, to nie działa. Jak na Microsoft "Zdarzenie DomainUnload występuje, gdy AppDomain ma zostać rozładowany.". Ale to nie działa, gdy zamykam okno (lub nawet wpisuję wyjście).
UPDATE:
Z pomocą innych specjalistów w Internecie & trochę wysiłku mogę osiągnąć z następującego kodu.
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()
ale tam problem jestem stoi .... Jeśli mogę uruchomić żadnej komandletu na konsoli po rejestracji tej obsługi (np uzyskać aktualne, Get-Process). Następnie aplikacja zostanie zawieszona po wystąpieniu zdarzenia (np. Ctrl + C, zamknij). Czy ktoś mógłby mi z tym pomóc?
z pomocą innych specjalistów online i trochę wysiłku mogłem osiągnąć dzięki poniższemu kodowi. – JST
PS v3 zahaczył o przycisk zamykania okna aż do zdarzenia wyjściowego. – Timbo