Windows下让新创建的进程随当前进程退出

有时候,我们需要创建一个新进程来执行一些额外的事情,同时还需要确保新进程随当前进程一起退出。我们可以用Windows提供的作业对象来完成这件事。

首先我们创建一个作业对象,然后设置JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE这个flag,然后把新创建进程关联到这个作业对象就可以了。这个flag的含义是让作业里的进程在作业对象关闭后就退出,当当前进程退出了,这个对象的句柄就被关闭了,从而实现当前进程退出后,新创建的进程退出的效果。

通过C#进程P/Invoke调用的代码如下:

var job = CreateJobObject(NullRef<SECURITY_ATTRIBUTES>(), null);
var s = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
s.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
SetInformationJobObject(job, JobObjectExtendedLimitInformation, AsPointer(ref s), Marshal.SizeOf<JOBOBJECT_EXTENDED_LIMIT_INFORMATION>());
var process = Process.Start("notepad.exe");
AssignProcessToJobObject(job, process.Handle);

通过上面这个代码启动的记事本就会在当前进程退出后退出。

另外还要注意的是,在Windows7之前的系统中,一个进程只能和一个作业关联,如果父进程已经已经和某个作业关联,通过Process.Start创建的子进程也会和该作业关联,从而导致AssignProcessToJobObject失败。这种情况下,要在创建进程时附加CREATE_BREAKAWAY_FROM_JOB参数,防止新创建的子进程和父进程原本关联的作业关联。

PS:通过Visual Studio调试时,创建出来的进程就会和一个作业关联,同时其创建出来的进程会在被调试进程退出时退出。

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据