当前位置:首页 > 实验2:Windows应用程序基础和进程控制
}
ZeroMemory(&pe, sizeof(pe) );// 为pe分配存储空间,并将其清0 pe.dwSize = sizeof(pe);
BOOL bMore = Process32First(hSnapshot, &pe); // 获得系统快照中的第一个进程信息 while(bMore) { }
// 打开用于读取的进程
HANDLE hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION, // 指明要得到信息 FALSE,
// 不必继承这一句柄 // 要打开的进程
pe.th32ProcessID);
if(hProcess != NULL) { }
// 转向下一个进程
bMore = Process32Next(hSnapshot, &pe);
// 找出进程的时间
FILETIME ftCreation, ftKernelMode, ftUserMode, ftExit; GetProcessTimes(
hProcess, &ftExit,
// 所感兴趣的进程
&ftCreation, // 进程的启动时间
// 结束时间
&ftKernelMode, // 在核心态下消耗的时间 &ftUserMode); // 在用户态下消耗的时间
// 计算核心态下消耗的时间百分比
DWORD dwPctKernel = GetKernelModePercentage(ftKernelMode, ftUserMode); // 向用户显示进程的某些信息
cout << \ << pe.th32ProcessID
<< \ << pe.szExeFile
<< \ << dwPctKernel << endl;
// 关闭句柄
CloseHandle(hProcess);
该程序首先利用Windows系统的新特性(即工具帮助库),来获得当前运行的所有进程的快
照。然后应用程序进入快照中的每一个进程,得到其以PROCESSENTRY32结构表示的属性,这一结构用来向OpenProcess()函数提供进程的ID。Windows跟踪每一个进程的有关时间,本例是通过打开的进程句柄和GetProcessTimes()函数来直接得到有关时间,接下来计算进程在核心态下消耗的时间占总时间的百分比。程序的其余部分比较简单,只是将有关信息显示给用户,关闭进程句柄,然后继续循环,直到所有进程都计算完为止。
2.3 运行进程
对于在系统中的每个进程来说,当它至少拥有一个执行线程时就是运行的。通常情况下,进程使用主线程作为其生命周期指示器。当主线程结束时,调用ExitProcess() API函数,通知系统终止它所拥有的所有正在运行、准备运行或正在挂起的其他线程。当进程正在进行时,通过下面一些API,可以获得它的许多特性。
2.3.1 获得一个进程的启动信息GetStartupInfo()函数 函数格式:
VOID GetStartupInfo(LPSTARTUPINFO lpStartupInfo);
参数:lpStartupInf为STARTUPINFO结构,该结构用于最终载入进程的启动信息。 返回值:无。
2.3.2 获得系统关闭时当前进程与其他进程关闭的迟早情况 GetProcessShutdownParameters()函数 函数格式:
BOOL GetProcessShutdownParameters(LPDWORD lpdwLevel, LPDWORD lpdwFlags);
参数:lpdwLevel为指定关闭优先级;lpdwFlags为指定关闭标志,若指定为SHUTDOWN-NORETRY标志,如关闭一个进程超时,会出现一个重试对话框。通过设置这个标志,就可以禁止那个对话框显示出来,并直接关闭进程。 返回值:如果函数执行成功,返回值为非0,否则返回值为0。
2.3.3 系统关闭时指定当前进程与其他进程关闭的顺序SetProcessShutdownParameters()函数
函数格式:
BOOL SetProcessShutdownParameters(DWORD dwlevel, DWORD dwFlags);
参数:dwLevel指向进程关闭优先级,系统按照从高到低优先级关闭进程;dwFlags可以为SHUTDOWN_NORETRY值,当系统关闭进程时不出现RETRY对话框。 返回值:函数成功调用,返回值为非0,否则返回值为0。
2.3.4 获得当前命令行缓冲区的一个指针GetCommandLine()函数 函数格式:
LPTSTR GetCommandLine(void); 参数:无
返回值:如果函数执行成功,返回命令缓冲区在内存中的地址。 2.3.5 查询进程进行的操作系统版本信息GetProcessVersion()函数 函数格式:
DWORD GetProcessVersion(DWORD processId) 参数:ProcessId为指定进程的标识符
返回值:如果函数执行成功,返值为系统版本信息。
2.3.6 提取与平台和操作系统的版本相关的信息GetVersionEx()函数 函数格式:
BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo);
参数:lpVersionInfo为指向OSVERSIONINFOEX结构,该结构用于装载操作系统的版本信息。 返回值:如果函数执行成功,返回值为非0,否则返回值为0。 2.3.7 关闭前台应用程序优先级的提升SetProcessPriorityBoost()函数 函数格式:
BOOL SetProcessPriorityBoost(HANDLE hProcess, BOOL DisablePriorityBoost);
参数:hProcess为指定进程的句柄,DisablePriorityBoost为指定可否提升优先级的标志。
返回值:如果函数执行成功,返回值为非0,否则返回值为0。
2.3.8 设置进程可用的最大和最小工作集SetProcessWorkingSet()函数 函数格式:
BOOL SetProcessWorkingSet(HANDLE hProcess, SIZE_T dwMinimumWorkingSetSize,
SIZE_T dwMaximumWorkingSetSize);
参数:hProcess为指定进程的句柄,dwMinimumWorkingSetSize为进程最小工作区域的字节数,dwMaximumWorkingSetSize为进程最大工作区域的字节数。 返回值:如果函数执行成功,返回值为非0,否则返回值为0。 2.3.9 获取运行进程操作系统版本号的程序示例 例4:获得运行进程的操作系统版本号。
// 获取运行进程操作系统版本号的程序version.cpp
#include
using namespace std;
// 利用进程和操作系统的版本信息的简单示例 void main() {
// 提取版本信息和报告
GetVersionEx(reinterpret_cast
printf(\, osvix.dwMajorVersion, osvix.dwMinorVersion); // 如果是Windows NT5(windows 2000)系统,那么将其提升为高优先权
if(osvix.dwPlatformId == VER_PLATFORM_WIN32_NT && osvix.dwMajorVersion >= 5) {
// 改变当前运行进程的优先级为高 SetPriorityClass(
GetCurrentProcess(), // 得到该进程的ID HIGH_PRIORITY_CLASS);// 改变为high
printf(\, dwIdThis, wMajorReq, wMinorReq); // 设置版本信息的数据结构,以便保存操作系统的版本信息 OSVERSIONINFOEX osvix;
ZeroMemory(&osvix, sizeof(osvix));
osvix.dwOSVersionInfoSize = sizeof(osvix);
DWORD dwIdThis = GetCurrentProcessId();// 获得进程的ID号
DWORD dwVerReq = GetProcessVersion(dwIdThis);// 获得进程和报告使用的操作系统版本 WORD wMajorReq = (WORD)(dwVerReq > 16);// 获得操作系统的主版本号 WORD wMinorReq = (WORD)(dwVerReq & 0xffff);// 获得操作系统的次版本号
// 报告给用户
printf(\); printf(\);
}
}
该程序展示了如何获得当前进程标识符PID和进程运行的操作系统的版本信息。为了运行这一程序,系统处理了所有的版本不兼容问题。接着,程序演示了如何使用GetVersionEx()函数来提取OSVERSIONINFOEX结构。该结构中包括了操作系统的版本信息,Window 2000/XP在此数据块内是以Windows NT 5.1表示的。
程序的最后一段利用了操作系统的版本信息,以确认运行的是Windows 2000还是Windows XP。代码接着将当前进程的优先级提升到高优先级。在Windows2000/XP中增加了ABOVE_NORMAL_PRIORITY_CLASS级别,它介于NORMAL_PRIORITY_CLASS和HIGH_PRIORITY_CLASS之间。当右击该进程名以改变其优先级时,任务管理器”应用程序应该立即反映这个变化。
2.4 进程终止和进程同步等待
所有进程都是以调用ExitProcess()或TerminateProcess()函数结束的。前者是在进程完成了它的所有的关闭“职责”之后以正常的终止方法来调用的,而后者是外部进程发生故障后终止进程时调用的,由于关闭时的途径不太正常,有可能引起错误的行为。
只要用PROCESS_TERMINATE访问权打开一个进程对象,TerminateProcess()函数就可以终止该进程,并向系统返回指定的终止码。这是一种“野蛮”的终止进程的方式,但是有时却是需要的。
进程同步是指一个进程或线程可以通过调用系统的相应函数等待一个或多个内核对象变为有信号状态,来实现进程或线程与这些内核对象的同步。能够作为同步对象的有进程、线程、文件、事件、互斥体、信号量等。这里主要介绍等待一个或多个内核对象WaitForsingleObject()或WaitForMultipleObjects()函数。 2.4.1 进程终止
1)进程正常终止ExitProcess()函数 函数格式:
VOID ExitProcess(UINT uExitCode);
参数:uExitCode为终止进程的退出码。 返回值:无。
2)中止指定句柄的进程TerminateProcess()函数 函数格式:
BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);
参数:hProcess为指定要中断的那个进程的句柄,uExitCode为进程的一个退出码。 返回值:函数成功调用,返回值为非0,否则返回值为0。
2.4.2 获取指定句柄的已终止进程的退出码 GetExitCodeProcess()函数 函数格式:
BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode);
参数:hProcess为指定终止的那个进程的句柄;uExitCode为用于获得进程退出码的一个整数变量。
返回值:函数成功调用,返回值为非0,否则返回值为0。
2.4.3 等待一个同步对象WaitForsingleObject()函数 函数格式:
共分享92篇相关文档