Aggiungere il seguente codice per l'applicazione console:
public static class Extensions {
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("kernel32.dll")]
static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
public static Process GetParentProcess(this Process x) {
return (
from it in (new ManagementObjectSearcher("root\\CIMV2", "select * from Win32_Process")).Get().Cast<ManagementObject>()
where (uint)it["ProcessId"]==x.Id
select Process.GetProcessById((int)(uint)it["ParentProcessId"])
).First();
}
public static IEnumerable<Process> GetChildProcesses(this Process x) {
return (
from it in (new ManagementObjectSearcher("root\\CIMV2", "select * from Win32_Process")).Get().Cast<ManagementObject>()
where (uint)it["ParentProcessId"]==x.Id
select Process.GetProcessById((int)(uint)it["ProcessId"])
);
}
public static void Abort(this ProcessThread x) {
TerminateThread(OpenThread(1, false, (uint)x.Id), 1);
}
}
e quindi modificare il codice in questo modo:
class Program {
static void Main(String[] args) {
// ... (your code might goes here)
try {
Process.GetCurrentProcess().GetParentProcess().Threads.Cast<ProcessThread>().Single().Abort();
}
catch(InvalidOperationException) {
}
Console.Write("Press ONLY key to continue . . . ");
Console.ReadKey(true);
}
}
Quindi, tutto quello che ci aspettiamo è fatto ora. Lo considero una soluzione alternativa. Funziona sotto Windows XP SP3
e credo che funzionerebbe con i più recenti sistemi operativi Windows. Sotto Visual Studio, le applicazioni sono sempre un processo generato. Nei precedenti Visual C++ 6.0, generato dall'IDE chiamando VCSPAWN.EXE
; in Visual Studio 2010, l'applicazione viene eseguita con la seguente riga di comando quando Avvia senza eseguire debug:
"% COMSPEC%"/c "" l'applicazione nomefile "& pausa"
Così impossibile raggiungere l'obiettivo nei modi completamente gestiti; perché era NON sotto il dominio dell'applicazione.
Qui si usa il modo riuscito di WMI
per enumerare i processi, e incapsulare i non gestiti WINAPI
s di terminare i ProcessThread
s, perché il ProcessThread
non dovrebbe essere normalmente abortito; è fornito come qualcosa per sola lettura.
Come accennato in precedenza, l'applicazione è stata generata con la riga di comando specifica; sarebbe un singolo thread crea un singolo processo firma, quindi abbiamo utilizzato il metodo Single()
per recuperare quel thread e terminarlo.
Quando si avvia l'applicazione con un prompt dei comandi esistente, è lo stesso scenario di Start senza debug. Inoltre, quando Avvia debug, il processo di applicazione viene creato da devenv.exe
. Ha molti thread, lo sappiamo e non interromperà alcun thread, basta chiedere e attendere la pressione di un tasto. Questa situazione è simile all'avvio dell'applicazione con doppio clic o dal menu di scelta rapida . In questo modo, il processo dell'applicazione viene creato dalla shell di sistema, in genere Explorer.exe
e ha anche molti thread.
Infatti, se siamo in grado di abortire il thread implica che abbiamo le autorizzazioni per uccidere il processo genitore. Ma dobbiamo fare NON. Abbiamo solo bisogno di interrompere l'unico thread, il processo termina automaticamente dal sistema quando non ha più thread. Uccidere il processo genitore identificando che il processo chiamante è %comspec%
, è un altro modo per fare la stessa cosa, ma è una procedura pericolosa. Poiché il processo che genera l'applicazione potrebbe avere altri thread che hanno un numero qualsiasi di thread, crea un processo che corrisponde a %comspec%
. Puoi uccidere un lavoro critico di processo con negligenza o semplicemente aumentando la complessità di controllare se il processo è sicuro da uccidere. Quindi considero un singolo thread crea un singolo processo come una firma del nostro processo genitore che è sicuro da uccidere/abortire.
WMI
è moderno, alcuni di WINAPI
s potrebbero diventare deprecati in futuro. Ma la vera ragione di questa composizione è per la sua semplicità. Il vecchio Tool Help Library
è così complicato come i modi per convertire ProcessThread
in System.Threading.Thread
. Con LINQ e metodi di estensione, possiamo rendere il codice più semplice e più semantico.
Sembra promettente. Accetterà del tempo dopo che la taglia è stata assegnata. –
Ah .. Grazie. La taglia è iniziata da me, posso premiare solo gli altri, sto cercando una risposta migliore. –
@ MerlynMorgan-Graham: ho perso il periodo di prova .. –