https://github.com/gongluck/Windows-Core-Program.gitc++
//第5章 做業.cpp: 定義應用程序的入口點。 // #include "stdafx.h" #include "第5章 做業.h" int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { //在調試一個做業(Job)程序時發現,以下代碼老是返回TRUE,不管是從VS中啓動調試仍是從資源管理器中啓動。 //原來,從資源管理器或者VS中啓動程序時,系統會自動把該進程放到一個做業(Job)中。知道了這一點,要想讓這段代碼返回FALSE,只要從CMD中啓動該程序便可。 BOOL bInJob; IsProcessInJob(GetCurrentProcess(), NULL, &bInJob); if (bInJob) MessageBox(nullptr, TEXT("process already in a job"), TEXT("info"), MB_OK); else MessageBox(nullptr, TEXT("process not in a job"), TEXT("info"), MB_OK); BOOL bret; HANDLE hJob = CreateJobObject(nullptr, TEXT("第5章 做業")); JOBOBJECT_BASIC_LIMIT_INFORMATION basiclimit = { 0 }; //做業(進程沙盒)限制 //JobObjectBasicLimitInformation、JobObjectExtendedLimitInformation、JobObjectBasicUIRestrictions、JobObjectSecurityLimitInformation //UserHandleGrantAccess授予或禁止一個Job中的進程訪問施加了UI限制的用戶對象的句柄的權限.當授予了訪問權限,全部相關聯的進程均可以在隨後識別和使用這個句柄.當訪問被拒絕,該進程不能在使用該句柄. basiclimit.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS | JOB_OBJECT_LIMIT_JOB_TIME; basiclimit.PriorityClass = IDLE_PRIORITY_CLASS;//指定關聯進程的優先級類 basiclimit.PerJobUserTimeLimit.QuadPart = 100000;//分配給進程的最大用戶模式時間(100納秒) bret = SetInformationJobObject(hJob, JobObjectBasicLimitInformation, &basiclimit, sizeof(basiclimit)); bret = QueryInformationJobObject(hJob, JobObjectBasicLimitInformation, &basiclimit, sizeof(basiclimit), nullptr); JOBOBJECT_END_OF_JOB_TIME_INFORMATION endoftime; endoftime.EndOfJobTimeAction = JOB_OBJECT_POST_AT_END_OF_JOB;//到期不終止進程(If no completion port is associated with the job when the time limit has been exceeded, the action taken is the same as for JOB_OBJECT_TERMINATE_AT_END_OF_JOB。)JOB_OBJECT_TERMINATE_AT_END_OF_JOB(到期終止進程) bret = SetInformationJobObject(hJob, JobObjectEndOfJobTimeInformation, &endoftime, sizeof(endoftime)); bret = QueryInformationJobObject(hJob, JobObjectEndOfJobTimeInformation, &endoftime, sizeof(endoftime), nullptr); //將進程放入做業中,只能添加未運行的「無業」進程 STARTUPINFO si = { 0 }; si.cb = sizeof(si); PROCESS_INFORMATION pi = { 0 }; bret = CreateProcess(TEXT("C:\\WINDOWS\\SYSTEM32\\NOTEPAD.EXE"), nullptr, nullptr, nullptr, FALSE, CREATE_SUSPENDED, nullptr, nullptr, &si, &pi); bret = AssignProcessToJobObject(hJob, pi.hProcess); ResumeThread(pi.hThread); //查詢做業(進程)統計信息 JOBOBJECT_BASIC_ACCOUNTING_INFORMATION accountinfo = { 0 }; bret = QueryInformationJobObject(hJob, JobObjectBasicAccountingInformation, &accountinfo, sizeof(accountinfo), nullptr); FILETIME c, e, k, u; bret = GetProcessTimes(pi.hProcess, &c, &e, &k, &u); JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION ioaccountinfo = { 0 }; bret = QueryInformationJobObject(hJob, JobObjectBasicAndIoAccountingInformation, &ioaccountinfo, sizeof(ioaccountinfo), nullptr); IO_COUNTERS ioconters; bret = GetProcessIoCounters(pi.hProcess, &ioconters); //查詢做業內進程 const int max = 10; DWORD cb = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + (max - 1) * sizeof(ULONG_PTR); PJOBOBJECT_BASIC_PROCESS_ID_LIST pidlist = (PJOBOBJECT_BASIC_PROCESS_ID_LIST)malloc(cb); pidlist->NumberOfAssignedProcesses = max; bret = QueryInformationJobObject(hJob, JobObjectBasicProcessIdList, pidlist, cb, &cb); for (int i = 0; i < pidlist->NumberOfProcessIdsInList; ++i) { pidlist->ProcessIdList[i]; } free(pidlist); pidlist = nullptr; //已分配的CPU時間到期時,做業狀態變成已觸發 WaitForSingleObject(hJob, INFINITE); system("pause"); //終止做業中全部的進程 bret = TerminateJobObject(hJob, 0); CloseHandle(pi.hProcess); pi.hProcess = nullptr; CloseHandle(pi.hThread); pi.hThread = nullptr; system("pause"); return 0; }