是否可以通过名称来pipe理JobObjects,而不必保持打开的HANDLE?

通过进程,我可以做到以下几点:

int pid; ::CreateProcess(NULL, cmd, ..., &pi); pid = pi.dwProcessId; ::CloseHandle(pi.hProcess); // then later... HANDLE proc = ::OpenProcess(PROCESS_TERMINATE, FALSE, pid); ::TerminateProcess(proc, 1); ::CloseHandle(proc); 

用这种方式,我可以通过pid来pipe理windows进程,这对于多平台代码来说是很好的。

我想将这种模式扩展到工作对象:

 HANDLE job = ::CreateJobObject(NULL, name); ::AssignProcessToJobObject(job, proc); // proc from above ::CloseHandle(job); // then later... job = ::OpenJobObject(JOB_OBJECT_TERMINATE, FALSE, name); ::TerminateJobObject(job, 1); 

要清楚,我不是在工作,但我的孩子的过程是。 MSDN说: “当它的最后一个句柄已经closures并且所有相关的进程已经退出时,作业被销毁”。 在这种情况下,我的主要过程已经closures了他的最后一个句柄,但是小孩还在跑步,仍然有句柄。 调用IsProcessInJob(proc, NULL, &isit)确认作业仍然存在。 但是,我打开作业的调用返回NULL,错误代码是ERROR_FILE_NOT_FOUND。

所以问题是:我的主stream程在closures之后是否有办法处理这个工作?

这是NT对象管理器的工作原理。 几乎所有对象都是“临时的”,这意味着当不再有对它们的引用(内核模式指针引用或句柄)时,它们将被删除。 您应该能够通过调用作业对象上的NtMakePermanentObject来更改此行为。 我从来没有尝试过,但之前。

对的,这是可能的。 但是,请注意:

 // This example will fail to reopen and terminate the job. // Processes cmd and ping stay running STARTUPINFO si; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(PROCESS_INFORMATION)); // BEGIN BLOCK A ::CreateProcess(NULL, "cmd /c ping 127.0.0.1 -n 10 > nul", NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, ".", &si, &pi); HANDLE job = ::CeateJobObject(NULL, "myjob"); ::AssignProcessToJobObject(job, pi.hProcess); // END BLOCK A ::ResumeThread(pi.hThread); ::CloseHandle(pi.hProcess); ::CloseHandle(pi.hThread); ::CloseHandle(job); HANDLE reopenJob = ::OpenJobObject(JOB_OBJECT_TERMINATE, FALSE, "myjob"); if(reopenJob != NULL) ::TerminateJobObject(reopenJob, 1); 

在这种情况下重新打开的作业是NULL,错误代码是ERROR_FILE_NOT_FOUND。

这个工作必须在这个过程之前被创造出来,并被继承下来,这个工作才能被重新开放。

 // NEW BLOCK A HANDLE job = ::CreateJobObject(NULL, "myjob"); ::SetHandleInformation(job, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); ::CreateProcess(NULL, "cmd /c ping 127.0.0.1 -n 10 > nul", NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, ".", &si, &pi); ::AssignProcessToJobObject(job, pi.hProcess); 

如果您的目标是使用PID来命名作业,请注意,此创建顺序会阻止这样的约定。 这仍然意味着除了PID之外还必须跟踪一些信息以便重新开始工作。