我有一个 Windows 服务(在 WinXP SP2 下),在 LocalSystem 帐户下运行,该服务使用 CreateProcessWithLogonW 启动进程。为了清理子进程,我尝试使用作业对象和 TerminateJobObject。
MSDN 规定作业句柄必须具有 JOB_OBJECT_ASSIGN_PROCESS 访问权限,自从通过 CreateJobObject 创建以来它就具有该访问权限。进程句柄必须具有 PROCESS_SET_QUOTA 和 PROCESS_TERMINATE 权限。我认为它有它们,因为 TerminateProcess 和 SetProcessWorkingSetSize 都返回且没有错误。
但是,AssignProcessToJobObject 失败并显示 errno 5(访问被拒绝)。如果我用简单的 CreateProcess 替换 CreateProcessWithLogonW ,一切都会正常。
我错过了什么还是我想做的事情是不可能的?
编辑:看起来 svchost.exe(在使用 CreateProcessWithLogonW 时实际创建进程)已经将该进程分配给匿名作业。此函数忽略 CREATE_CREAKAWAY_FROM_JOB 标志。所以真正的问题是:有没有办法阻止 svnhost 将进程分配给作业?
最佳答案
来自Jeff Lawson在 MSDN 上:
Interactions with Win32 Job Objects
CreateProcessWithLogonW executes the new process as a child of the Secondary Logon service, which has the outcome of making the process escape any Job Object membership/restrictions even if the Job Object did not allow breakaway.
Furthermore, the Secondary Logon service automatically creates its own new Job Object and assigns the new process into it. As such, it is not possible for the caller to explicitly assign the new process to any other Job Object (since a process may only be assigned to one Job Object, and can never be removed from a Job Object once it has been assigned to one).
每个新进程都需要不同的登录吗?否则,您可以使用新登录创建单个进程,并使用 CreateProcess 生成新进程,然后将其与作业对象关联。
关于CreateProcessWithLogonW 和AssignProcessToJobObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1287620/