下面的代码添加到控制台应用程序:
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,它由IDE通过调用VCSPAWN.EXE
产生;在Visual Studio 2010中,您的应用程序使用下面的命令行运行时不开始调试:
“%COMSPEC%”/ C “” 你的应用程序文件名 “&暂停”
所以不可能在完全管理的方式达到目标;因为它是在应用程序域下的NOT。
在这里我们使用的WMI
的管理方式来枚举进程,并封装非托管WINAPI
s到终止ProcessThread
S,因为ProcessThread
不应该是正常中止;它提供了一些用于只读的东西。
如上所述,应用程序是由特定的命令行产生的;它会有单线程创建单个进程签名,所以我们使用Single()
方法检索该线程并终止它。
当我们在现有的命令提示符下启动应用程序时,它与开始时没有调试一样。此外,当开始调试时,申请过程由devenv.exe
创建。它有很多线程,我们知道并且不会中止任何线程,只是提示并等待按键。这种情况类似于通过双击或从上下文菜单开始应用程序。这样,应用程序进程由系统shell创建,通常为Explorer.exe
,并且它也有很多线程。
事实上,如果我们可以成功地中止线程,那意味着我们有权杀死父进程。但我们做不需要需要。我们只需要中止唯一的线程,当没有更多的线程时,进程会自动终止进程。通过识别调用进程是否为%comspec%
来杀死父进程是另一种做同样事情的方式,但这是一个危险的过程。因为生成应用程序的进程可能会有其他线程,它们具有任意数量的线程,所以创建的进程匹配%comspec%
。你可能会粗心大意地杀死一个关键流程的工作,或者增加检查流程是否可以被杀死的复杂性。所以我认为单线程创建单个进程作为我们的父进程的签名是安全的杀/中止。
WMI
是现代的,一些WINAPI
可能会在将来被弃用。但是这种构图的真正原因在于其简单性。旧的Tool Help Library
像将ProcessThread
转换为System.Threading.Thread
那样复杂。使用LINQ和扩展方法,我们可以使代码更简单,更具语义。
看起来很有希望。在分配奖金后会接受一段时间。 –
啊..谢谢。赏金是由我开始的,只能奖给别人,我正在寻找更好的答案。 –
@ MerlynMorgan-Graham:我错过了宽限期.. –