上编文章已经说明如果,子进程不加入到作业中需要设置进程的flag字段为CREATE_BREAKAWAY_FROM_JOB
在创建进程的flag字段中找到CREATE_BREAKAWAY_FROM_JOB,其描述中说明如果进程关联了job,子进程不想关联就必须设置JOB_OBJECT_LIMIT_BREAKAWAY_OK。
JOBOBJECT_LIMIT_BREAKAWAY_OK 位于JOBOBJECT_BASIC_LIMIT_INFORMATION_结构体中
typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION {LARGE_INTEGER PerProcessUserTimeLimit;LARGE_INTEGER PerJobUserTimeLimit;DWORD LimitFlags;SIZE_T MinimumWorkingSetSize;SIZE_T MaximumWorkingSetSize;DWORD ActiveProcessLimit;ULONG_PTR Affinity;DWORD PriorityClass;DWORD SchedulingClass;} JOBOBJECT_BASIC_LIMIT_INFORMATION, *PJOBOBJECT_BASIC_LIMIT_INFORMATION;
如果要使用jobobject_limit_breakaway标记必须使用[**_JOBOBJECT_EXTENDED_LIMIT_INFORMATION**](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_extended_limit_information)结构体
结构体如下:
typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION {JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;IO_COUNTERS IoInfo;SIZE_T ProcessMemoryLimit;SIZE_T JobMemoryLimit;SIZE_T PeakProcessMemoryUsed;SIZE_T PeakJobMemoryUsed;} JOBOBJECT_EXTENDED_LIMIT_INFORMATION, *PJOBOBJECT_EXTENDED_LIMIT_INFORMATION;
因此要使子进程不加入到作业中需要如下的代码设置
DWORD re;BOOL Result;HANDLE hJob1=CreateJobObject(NULL,L"hello");_tprintf(L"hJob1 = %X GetLastError = %d\n",hJob1,GetLastError());//创建对象JOBOBJECT_EXTENDED_LIMIT_INFORMATION info={0};//设置为JOB_OBJECT_LIMIT_BREAKAWAY_OKinfo.BasicLimitInformation.LimitFlags=JOB_OBJECT_LIMIT_BREAKAWAY_OK;//查询作业对象的信息re =SetInformationJobObject(hJob1,JobObjectExtendedLimitInformation,(PVOID)&info,sizeof(info));
完整的代码
#include<Windows.h>#include<tchar.h>int _tmain(){/*判断一个进程是否已经加入了一个作业的函数是:IsProcessInJob;BOOL WINAPI IsProcessInJob(__in HANDLE ProcessHandle,__in_opt HANDLE JobHandle,__out PBOOL Result);ProcessHandle: 要判断的进程句柄;JobHandle: 看看进程是否加入到JobHandle这个作业中;Result: 判断结果。*/DWORD re;BOOL Result;HANDLE hJob1=CreateJobObject(NULL,L"hello");_tprintf(L"hJob1 = %X GetLastError = %d\n",hJob1,GetLastError());JOBOBJECT_EXTENDED_LIMIT_INFORMATION info={0};info.BasicLimitInformation.LimitFlags=JOB_OBJECT_LIMIT_BREAKAWAY_OK;re =SetInformationJobObject(hJob1,JobObjectExtendedLimitInformation,(PVOID)&info,sizeof(info));/*BOOL WINAPI IsProcessInJob(__in HANDLE ProcessHandle,__in_opt HANDLE JobHandle,__out PBOOL Result);ProcessHandle 需要检查确认的进程句柄 A。JobHandle 作业句柄 BResult 检查结果,如果是1,那么说明进程A已经被放入做也B,否则进程A没有被放到作业B中。Return 成功,返回1,否则返回1*/re = IsProcessInJob(GetCurrentProcess(),NULL,&Result);_tprintf(L" re = %d Result = %d\n",re,Result);/////////////////////////////////////////////////////////STARTUPINFO si;PROCESS_INFORMATION pi;ZeroMemory( &si, sizeof(si) );si.cb = sizeof(si);ZeroMemory( &pi, sizeof(pi) );/*BOOL WINAPI AssignProcessToJobObject(__in HANDLE hJob,__in HANDLE hProcess);hJob: 要将进程hProcess加入的那个作业的句柄Process: 要加入到作业中的进程句柄return: 成功返回1,否则返回0*/re=AssignProcessToJobObject(hJob1,GetCurrentProcess());_tprintf(L" re = %d \n",re);re = IsProcessInJob(GetCurrentProcess(),NULL,&Result);_tprintf(L" re = %d currentProcess__Result = %d\n",re,Result);// Start the child process.if( !CreateProcess(L"Reloz.exe", // No module name (use command line)NULL, // Command lineNULL, // Process handle not inheritableNULL, // Thread handle not inheritableNULL, // Set handle inheritance to FALSECREATE_BREAKAWAY_FROM_JOB, // No creation flagsNULL, // Use parent's environment blockNULL, // Use parent's starting directory&si, // Pointer to STARTUPINFO structure&pi ) // Pointer to PROCESS_INFORMATION structure){_tprintf(L"CreateProcess failed (%d).\n", GetLastError() );return 0;}/////////////////////////////////////////re = IsProcessInJob(pi.hProcess,hJob1,&Result);_tprintf(L" re = %d pi.hProcess 子进程Result = %d\n",re,Result);_gettchar();CloseHandle(hJob1);CloseHandle(pi.hProcess);CloseHandle(pi.hThread);return 0;}
