&ftExit, //结束时间(如果有的话) &ftKernelMode, //在核心状态下消耗的时问 &ftUserMode); //在用户状态下消耗的时间 //计算核心状态下消耗的时间百分比
DWORD dwPctKernel=GetKernelModePercentage( ftKernelMode,//在核心状态下消耗的时间 ftUserMode);//在用户状态下消耗的时间 //显示进程的某些信息
cout<<\:\ <<\,%in Kernel mode:\CloseHandle(hProcess);//关闭句柄 }
bMore=Process32Next(hSnapshot,&pe);//转向下一个进程 }}
四、 进程控制
Windows所创建的每个进程都从调用CreateProcess()API函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。每一进程都以调用ExitProcess()或TerminateProcess()API函数终止。通常应用程序的框架负责调用ExitProcess()函数。
对于C++运行库来说,这一调用发生在应用程序的main()函数返回之后(如果采用C运行库,则调用WinMain()函数)。
1.进程创建
基本的win32进程管理函数是CreateProcess,可以创建拥有单个线程的进程。因为进程需要代码,所以有必要指定可执行程序文件名作为CreateProcess调用的一部分。
CreateProcess有10个参数支持其灵活性和强大功能。该函数并不返回一个handle,而是在一个结构(在调用中指定)中返回两个表示进程和线程的句柄。
相关API函数说明如下: (1)CreateProcess
函数功能:该函数用来创建进程。 函数格式:
BOOL CreateProcess(
LPCTSTR lpApplicationName, LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory, LPSTARTUPINF0 lpStartupInfo,
LPPROCESS_INFORMATI0N lpProcessInformation); 参数:
·lpApplicationName和lpCommandLine指定新进程使用的可执行文件和传递给新进程的命令行字符串。
·lpszCommandLine 可以设定CreateProcess中用于创建新进程的命令行。 CreateProcess在解析lpCommandLine字符串的时候,先查看字符串中的第一个符号,如果是一个可执行文件名且不含有扩展名,就假定它的扩展名为EXE。
CreateProcess将按照以下顺序来搜索可执行文件: ①含有调用进程的EXE文件的目录; ②调用进程的当前目录;
③Windows系统目录,该目录由GetSystemDirectory函数得到; ④Windows目录,该目录由GetWindowsDirectory函数得到; ⑤列在PATH环境变量中的目录。
如果文件名中包含了完整的路径,系统就使用完整路径搜索可执行文件。如果系统找到了可执行文件,就创建一个新进程,并生成一个4GB的地址空间,从而使可执行文件的代码和数据映射到这个地址空间。
·lpProeessAllributes和lpThreadAllributes 是指向进程和线程安全属性结构的 指针。当用NULL表示时,则为默认的安全性。
·bInheritHandles表明新进程是否继承调用进程的打开句柄的副本。继承的句柄与原来的句柄具有相同属性。
·dwCreationFlags是几个标志的组合,其中包含以下几个标志:
◇CREATE_SUSPENDED指定新进程的主线程创建时处于挂起状态,直到调用ResumeThread函数时才能运行。
◇DETACHED_PROCESS和CREATE_NEW_CONSOLE 相互排斥;二者不能同时使用。第一个标志是创建没有控制台的进程,第二个标志是创建新的有控制台的进程。如果二者都没有设置,进程将继承父进程的控制台。
◇CREATE_NEW_PROCESS_GROUP 指定新进程是新进程组的根进程。如果组中所有的进程都共享同一控制台,则它们都将接收控制台的控制信号。
·lpVEnvironment指向新进程的环境块。如果此值为NULL,进程会使用父进程的环境块。环境块包含名称和值字符串,如搜索路径。
·lpCurrentDirectory指向新进程的驱动器和目录。若为NULL,将使用父进程的工作 目录。
·lpStartupInfo指向新进程的主窗口外观和标准设备句柄。使用GetStartupInfo 函数得到父进程信息。
· lpProcessInformation指向包含返回的进程、线程句柄和进程、线程标识符的PROCESS_INFORMATION结构。
返回值:如果进程和主线程创建成功,则返回TRUE。 (2)GetCurrentProcessId
函数功能:该函数用来获得当前进程的标识符。 函数格式:
DWORD GetCurrentProcessId (void): 参数:无。
返回值:返回当前进程的标识符。 (3)Sleep
函数功能:该函数以指定的时间间隔挂起当前的执行线程。 函数格式:
VOID Sleep(DWORD dwMilliseconds):
参数:dwMilliseconds.定义挂起执行线程的时间,以毫秒为单位。取值为O时,该线程将余下的时间片交给处于就绪状态的同一优先级的其他线程。若没有处于就绪状态的同一优先级的其他线程,则函数立即返回,该线程继续执行。若取值为INFINITE则造成无限延迟。
返回值:该函数没有返回值。 (4)GetModuleFileName
函数功能:该函数用来为含有指定模块的可执行文件检索全路径和文件名。 函数格式:
DWORD GetModuleFileName(HMODULE hModule,LPTSTR lpFilename,DWORD nSize); 参数:
·hModule指定所需模块的句柄,该模块的可执行文件名被请求,如果此参数为NULL,则函数返回用来创建调用进程的文件路径。
·lpFilename指向一个缓冲区指针,该缓冲区被给定模块的路径和文件名填充。
·nSize指定lpFilename缓冲区的容量,如果路径和文件名的长度超过此范围,则字符串被截断。
返回值:如果函数调用成功,返回值为复制到缓冲区的字符串长度;否则,返回值为0。 备注:如果一个模块被装载到两个进程,那么在一个进程中的模块文件与在另一个进程中的模块文件名不一样。
为了显示创建子进程的基本框架,下面给出一个例子。 例2-4 创建子进程。 #include
// 创建一个克隆的进程并赋予其ID值 void StartClone(int nCloneID) {
//获得用于当前可执行文件的文件名 TCHAR szFilename[MAX_PATH];
GetModuleFileName(NULL,szFilename,MAX_PATH);
//创建子进程命令行的格式化,获得应用程序的EXE文件名并克隆进程的ID值 TCHAR szCmdLine[MAX_PATH];
sprintf(szCmdLine,\,szFilename,nCloneID); STARTUPINFO si; //用于子进程的STARTUPINFO结构 ZeroMemory(reinterpret_cast
PROCESS_INFORMATION pi; //说明一个用于记录子进程的相关信息的结构变量 //利用同样的可执行文件和命令行创建进程 BOOL bCreateOK=CreateProcess(
szFilename, //可执行的应用程序的名称 szCmdLine, //指定创建一个子进程的符号标识 NULL, //默认的进程安全性 NULL, //默认的线程安全性
FALSE, //不继承打开文件的句柄
CREATE_NEW_CONSOLE, //使用新的控制台 NULL, //新的环境 NULL, //当前目录 &si, //启动信息 &pi); //返回进程和线程信息
// 运行结束,关闭进程和其线程的句柄 if(bCreateOK) {
CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } }
int main(int argc,char *argv[]) {
// 确定进程在列表中的位置 int nClone(0); if(argc>1) {
//从第二个参数中提取克隆ID
sscanf(argv[1],”%d”,&nClone); }
//显示进程位置
printf(“Process ID:%d,Clone ID:%d\\n”,GetCurrentProcessId(),nClone); //创建25个子进程
const int c_nCloneMax=25; if(nClone StartClone(++nClone); //发送新进程的命令行和克隆号 Sleep(1000); //暂停(1秒) } Sleep(500); //在终止之前暂停(1/2秒) return 0; } 2.运行进程 对于在系统中的每个进程,当至少拥有一个执行线程时就是运行的。通常情况下,进程使用其主线程作为其生命周期指示器。当主线程结束时,调用ExitPrcocess()API函数,通知系统终止自己所拥有的所有正在运行、准备运行或正在挂起的其他线程。当进程正在运行时,可以获得它的许多特性,其中少数特性也允许加以修改。 ·可利用GetCurrentProcessId()API函数来查看系统当前进程的标识符(pid),该 pid在整个系统中都可使用。 ·可利用GetCurrentProcess()API函数获得进程的句柄。 ·其他的可显示当前进程信息的API函数还有GetStartupInfo()和GetProcessShutdownParameters()等,其中GetStartupInfo()获得创建进程的启动信息, GetProcessShutdownParameters()能获得当前进程的终止信息,给出进程存活期内的配置详情。 通常,一个进程需要它的运行期环境的信息。例如GetModuleFileName()API函数和GetCommandLine(),可以给出用在CreateProcess()中的获得可运行应用程序名和创建进程的符号标识参数以启动应用程序。 另一个可用于查询进程运行的操作系统版本信息的API函数是GetProcessVersion()。 相关API函数说明如下: (1)GetStartupInfo 函数功能:该函数用来获得一个进程的启动信息。 函数格式:VOID GetStartupInfo(LPSTARTUPINF0 lpStartupInfo); 参数:lpStartupInfo指向STARTUPINFO结构,该结构用于最终载入进程的启动信息。 返回值:无。 (2)GetProcessShutdownParameters 函数功能:该函数用来获得系统关闭时一个指定的进程相对其他进程关闭的早迟情况。 函数格式: BOOL GetProcessShutdownParameters(LPDWORD lpdwLevel,LPDWORD lpdwFlags); 参数:lpdwLevel指定关闭优先级;lpdwFlags指定关闭标志,即SHUTDOWNNORETRY标志。 返回值:如果函数执行成功,返回非零值,否则返回值为0。 (3)GetCommandLine 函数功能:该函数用来获得当前命令行缓冲区的一个指针。 函数格式: LPTSTR GetCommandLine(void); 参数:无 返回值:如果函数执行成功,返回命令缓冲区在内存中的地址。 (4)GetProcessVersion 函数功能:该函数用来查询进程运行的操作系统版本信息。 函数格式: DWORD GetProcessVersion(DWORD Processld); 参数:Processld指定进程的标识符。 返回值:如果函数执行成功,返回值为系统版本信息。 (5)GetVersionEX 函数功能:该函数用来提取OSVERSIONINFOEX结构,该数据块中包括了平台和操作系统的版本信息。 函数格式: BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo); 参数:lpVersionInfo指向OSVERSIONINFOEX结构,该结构用于装载操作系统的版本信息。 返回值:如果函数执行成功,返回非零值,否则返回值为0。 (6)SetProcessPriorityBoost 函数功能:该函数用来关闭前台应用程序优先级的提升。 . 函数格式: BOOL SetProcessPriorityBoost(HANDLE hProcess, BOOL DisablePriorityBoost); 参数:hProcess指定进程的句柄;DisablePriorityBoost指定可否提升优先级的标志。 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库14-15(2)实验指导书(4)在线全文阅读。
相关推荐: