は、コンソールアプリケーションに次のコードを追加します。
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);
}
}
をしてから、このようなあなたのコードを変更:だから
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);
}
}
、我々が期待しているすべてのものは、現在行われています。私はこれを回避策として考えています。それはWindows XP SP3
の下で動作し、私はそれが新しいWindowsオペレーティングシステムで動作すると思います。 Visual Studioの下では、アプリケーションは常にの生成プロセスです。古いバージョンVisual C++ 6。0、それはVCSPAWN.EXE
を呼び出してIDEによって生成されます。 のVisual Studio 2010で、あなたのアプリケーションがをデバッグなしで次のコマンドラインスタートで実行されます:
の "%COMSPEC%を"/C "" あなたのアプリケーションのファイル名 "&一時停止"
をので、完全に管理された方法での目標に達することは不可能です;アプリケーションドメインの下にでないためでした。
ここProcessThread
が正常に中止されることになっていないので、我々は、ProcessThread
Sを終了させるプロセスを列挙し、管理されていないWINAPI
Sをカプセル化するWMI
の管理方法を使用します。それは読み取り専用のもののように提供されています。
上記のとおり、アプリケーションは特定のコマンドラインで生成されました。 単一のスレッドが単一のプロセスの署名を作成するので、Single()
メソッドを使用して、そのスレッドを取り出して終了させました。
既存のコマンドプロンプトでアプリケーションを起動すると、開始なしデバッグなしの場合と同じです。また、デバッグ開始の場合、アプリケーションプロセスはdevenv.exe
で作成されます。スレッド数が多く、スレッドを中止することはありません。プロンプトが表示され、キーを押すのを待つだけです。このような状況は、ダブルクリックでアプリケーションを起動する場合や、コンテキストメニューから似ています。このようにして、アプリケーション・プロセスはシステム・シェルによって作成されます。通常はExplorer.exe
であり、多くのスレッドもあります。
実際、スレッドを正常に終了できる場合は、親プロセスを強制終了する権限があることを意味します。しかし、我々はをしないでくださいする必要があります。唯一のスレッドを中止する必要があります。スレッドがなくなると、プロセスは自動的に終了します。呼び出し元のプロセスが%comspec%
であることを確認して親プロセスを強制終了することは、同じことを行う別の方法ですが、危険な手順です。アプリケーションを起動するプロセスには、任意の数のスレッドを持つ他のスレッドがあるため、%comspec%
に一致するプロセスを作成する可能性があります。あなたは不注意でプロセスの重要な仕事を殺すか、プロセスが殺害するのが安全かどうかのチェックの複雑さを増やすことができます。だから私は単一のスレッドを作成するプロセスを作成する私たちの親プロセスの署名として殺す/中止することが安全です。
WMI
は現代的であり、将来的にはWINAPI
の一部が廃止される可能性があります。しかし、この構成の本当の理由は、その単純さのためです。古いTool Help Library
は、ProcessThread
をSystem.Threading.Thread
に変換する方法と同様に複雑です。 LINQと拡張メソッドを使用することで、コードをよりシンプルに、よりセマンティックにすることができます。ここ
有望そうです。賞金が授与されてからしばらくお待ちください。 –
ああ..ありがとう。恩恵は私によって開始され、他の人に賞を与えることができます、私はより良い答えを探しています。 –
@ MerlynMorgan-Graham:私は猶予期間を逃しました.. –