int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine,int){
// Check if we are not already associated with a job.
// If this is the case, there is no way to switch to
// another job.
BOOL bInJob = FALSE;
IsProcessInJob(GetCurrentProcess(), NULL,&bInJob);//首先检测进程是否已经在一个job中
if(bInJob){//在就退出
MessageBox(NULL, TEXT("Process already in a job"),
TEXT(""), MB_ICONINFORMATION | MB_OK);
return(-1);
}
// Create the completion port that receives job notifications
g_hIOCP =CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL,0,0);//IO接口信息
// Create a thread that waits on the completion port
g_hThreadIOCP = chBEGINTHREADEX(NULL,0,JobNotify, NULL,0, NULL);//创建接受io接口信息的线程
// Create the job object
g_job.Create(NULL, TEXT("JobLab"));
g_job.SetEndOfJobInfo(JOB_OBJECT_POST_AT_END_OF_JOB);
g_job.AssociateCompletionPort(g_hIOCP, COMPKEY_JOBOBJECT);
DialogBox(hinstExe, MAKEINTRESOURCE(IDD_JOBLAB), NULL,Dlg_Proc);//建立对话框
/*INT_PTR DialogBox( HINSTANCE hInstance , // 进程句柄 LPCTSTR lpTemplate , // 对话框资源 HWND hWndParent , // handle to owner window DLGPROC lpDialogFunc // 对话框消息处理程序 );PostQueuedCompletionStatus(g_hIOCP,0, COMPKEY_TERMINATE, NULL);
// Wait for the completion port thread to terminate
WaitForSingleObject(g_hThreadIOCP, INFINITE);
// Clean up everything properly
CloseHandle(g_hIOCP);
CloseHandle(g_hThreadIOCP);
// NOTE: The job is closed when the g_job's destructor is called.
return(0);
}
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
switch(uMsg){//将消息传给不同的函数处理
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG,Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_TIMER,Dlg_OnTimer);
chHANDLE_DLGMSG(hwnd, WM_COMMAND,Dlg_OnCommand);
}
return(FALSE);
}
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam){
chSETDLGICONS(hwnd, IDI_JOBLAB);//设置对话框图标
// Save our window handle so that the completion port thread can access it
g_hwnd = hwnd;
HWND hwndPriorityClass =GetDlgItem(hwnd, IDC_PRIORITYCLASS);//设置comboBox
ComboBox_AddString(hwndPriorityClass, TEXT("No limit"));
ComboBox_AddString(hwndPriorityClass, TEXT("Idle"));
ComboBox_AddString(hwndPriorityClass, TEXT("Below normal"));
ComboBox_AddString(hwndPriorityClass, TEXT("Normal"));
ComboBox_AddString(hwndPriorityClass, TEXT("Above normal"));
ComboBox_AddString(hwndPriorityClass, TEXT("High"));
ComboBox_AddString(hwndPriorityClass, TEXT("Realtime"));
ComboBox_SetCurSel(hwndPriorityClass,0);// Default to "No Limit"
HWND hwndSchedulingClass =GetDlgItem(hwnd, IDC_SCHEDULINGCLASS);
ComboBox_AddString(hwndSchedulingClass, TEXT("No limit"));
for(int n =0; n <=9; n++){
TCHAR szSchedulingClass[2];
StringCchPrintf(szSchedulingClass, _countof(szSchedulingClass),
TEXT("%u"), n);
ComboBox_AddString(hwndSchedulingClass, szSchedulingClass);
}
ComboBox_SetCurSel(hwndSchedulingClass,0);// Default to "No Limit"
SetTimer(hwnd,1,10000, NULL);// 10 second accounting update
return(TRUE);
}
voidDlg_OnCommand(HWND hwnd,int id, HWND hwndCtl, UINT codeNotify){
switch(id){//命令的处理
case IDCANCEL:
// User is terminating our app, kill the job too.
KillTimer(hwnd,1);
g_job.Terminate(0);
EndDialog(hwnd, id);
break;
case IDC_PERJOBUSERTIMELIMIT:
{
// The job time must be reset if setting a job time limit
BOOL f;
GetDlgItemInt(hwnd, IDC_PERJOBUSERTIMELIMIT,&f, FALSE);
EnableWindow(
GetDlgItem(hwnd, IDC_PRESERVEJOBTIMEWHENAPPLYINGLIMITS),!f);
}
break;
case IDC_APPLYLIMITS:
Dlg_ApplyLimits(hwnd);
PostQueuedCompletionStatus(g_hIOCP,0, COMPKEY_STATUS, NULL);
break;
case IDC_TERMINATE:
g_job.Terminate(0);
PostQueuedCompletionStatus(g_hIOCP,0, COMPKEY_STATUS, NULL);
break;
case IDC_SPAWNCMDINJOB:
{
// Spawn a command shell and place it in the job
STARTUPINFO si ={sizeof(si)};
PROCESS_INFORMATION pi;
TCHAR sz[]= TEXT("CMD");
CreateProcess(NULL, sz, NULL, NULL,
FALSE, CREATE_SUSPENDED, NULL, NULL,&si,&pi);
g_job.AssignProcess(pi.hProcess);
ResumeThread(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
PostQueuedCompletionStatus(g_hIOCP,0, COMPKEY_STATUS, NULL);
break;
case IDC_ASSIGNPROCESSTOJOB:
{
DWORD dwProcessId =GetDlgItemInt(hwnd, IDC_PROCESSID, NULL, FALSE);
HANDLE hProcess =OpenProcess(
PROCESS_SET_QUOTA | PROCESS_TERMINATE, FALSE, dwProcessId);
if(hProcess != NULL){
chVERIFY(g_job.AssignProcess(hProcess));
CloseHandle(hProcess);
}else chMB("Could not assign process to job.");
}
PostQueuedCompletionStatus(g_hIOCP,0, COMPKEY_STATUS, NULL);
break;
}
}
void WINAPI Dlg_OnTimer(HWND hwnd, UINT id){
PostQueuedCompletionStatus(g_hIOCP,0, COMPKEY_STATUS, NULL);
}