念已经不再被采用,所以总是设置为NULL。
·lpCmdLine指定用于应用程序的命令行,可以通过它将文件在程序启动时载入内存。 ·nShowCmd指定该应用程序在运行时以何种方式显示(正常、最大化和最小化中选一)。 为了进一步理解应用程序的构造,下面给出一个简单的GUI应用程序。 例2-1 GUI应用程序。 #include
//告诉连接器,与包括MessageBox()API函数的user32库进行连接 #pragma comment(lib,\
//这是一个可以弹出信息框然后退出的简单的应用程序
int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPSTR,int) {
MessageBox(
NULL, //没有父窗口
\,Windows 2000\, //消息框中的文本信息 \, //消息框标题 MB_OK); //消息框中有一个OK按钮
return 0; //返回0以便通知系统不进入消息循环 }
在GUI应用程序中,首先需要Windows.h头文件,它向WinMain()和MessageBox()API函数提供所需的数据类型定义。
然后,pragma指令指示编译器/连接器找到user32.lib库文件并将其与产生的EXE文件连接起来。如果没有pragma指令,则MessageBox()API函数就成为未定义的了。这一指令是Visual Studio C++编译器特有的。
接下来是WinMain()方法。其中有4个由实际的低级入口点传递来的参数。hInstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用GetModuleHandle()API函数将这些资源提取出来。系统利用实例句柄来指明代码和初始的数据装在内存的何处。句柄的实际数值是EXE文件映像的基地址,通常为0x00400000。下一个参数hPreInstance是为向下兼容而设的,现在系统将其设为NULL。应用程序的命令行(不包括程序的名称)是lpCmdLine参数。另外,系统利用nCmdShow参数告诉应用程序如何显示它的主窗口(选项包括最小化、最大化和正常)。
最后,程序调用MessageBox()API函数,之后退出。如果在进入消息循环之前就结束运行的话,最后必须返回0。
2.进程对象
操作系统将当前运行的应用程序看作是进程对象。利用系统提供的惟一的称为句柄(handle)的标识,就可与进程对象交互。这一标识只对当前进程有效,因此正在系统中运行的任何进程都可调用GetCurrentProcess()API函数,返回进程本身的句柄。
相关API函数说明 (1) GetModuleHandle
函数功能:该函数用来获得一个应用程序或动态链接库的模块句柄。 函数格式:
HMODULE GetModulehandle(LPCTSTR lpModuleName);
参数:lpModuleName指定的模块名,通常是与模块的文件名相同的一个名字。 返回值:若函数调用成功,返回值为模块句柄;否则返回值为0。 (2)GetCurrentProcess
函数功能:该函数返回当前进程的句柄。 函数格式:
HANDLE GetCurrentProcess(void); 参数:无。
返回值:若函数调用成功,返回值为当前进程的句柄。 (3)GetPriorityClass
函数功能:该函数用来获得进程的基准优先级。 函数格式:
DWORD GetPriorityClass(HANDLE); 参数:HANDLE指定进程句柄。
返回值:若函数调用成功,返回值为指定进程的基准优先级;若函数调用失败,返回值为0。
备注:如果要了解进程的返回代码,就需要有PROCESS_QUERY_INFORMATION的访问权限。 (4)CreateToolhelp32Snapshot
函数功能:该函数获得系统中当前进程的快照。 函数格式:
HANDLE CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);
参数:dwFlags指定快照中包括系统线程的情况;th32ProcessID指定进程的标志符。 返回值:若函数调用成功,则返回值为进程快照的句柄。
备注:若参数dwFlags为TH32CS_SNAPPROCESS,则表明快照包括系统中的所有线程,且th32ProcessID为包含在快照中进程的进程标志符。
(5)ZeroMemory
函数功能:该函数用来分配存储空间,并将其清零。 函数格式:
VOID ZeroMemory(PVOID Destination,SIZE_T Length);
参数:Destination指向分配空间的起始地址;Length分配空间字节长度。 返回值:该函数没有返回值。 (6)Process32First
函数功能:该函数用来获得系统快照中的第一个进程信息。 函数格式:
BOOL Process32First(HANDLE hSnapshot,LPPROCESSENTRY32 lppe); 参数:hSnapshot指定快照句柄;Lppe指向PROCESSENTRY32结构指针。
返回值:如果返回值为真,则将系统快照中的第一个进程信息复制到缓冲区,否则不做任何操作。
(7)OpenProcess
函数功能:该函数用来获得一个已经存在的进程对象的句柄。 函数格式:
HANDLE OpcnProcess(DWORD dwDesiredAccess,BOOL bInheritHandle, DWORD dwProcessId);
参数:
·dwDesiredAccess指定进程对象的访问权限。此参数可以是下列值的一个或几个的组合:
◇PROCESS_ALL_ACCESS指定对象无限制的访问。 ◇PROCESS_CREATE_PROCESS内部使用。
◇PROCESS_CREATE_THREAD使用函数CreateRemoteThread中的句柄在进程中创建一个线程。
◇PROCESS_DUP_HANDLE允许在函数DuplicateHandle中使用进程对象。
◇PROCESS_QUERY_INFORMATION 允许GetExitCodeClass和GetPriority等函数获得关于进程的信息。
◇PROCESS_SET_QUOTA 允许使用AssignProcessToJobObject和 SetProcessWorkingSetSize等函数中的句柄来设置内存限制。
◇PROCESS_SET_INFORMATION 允许使用函数SetPriorityClass来设置有关进程的信息。
◇PROCESS_TERMINATE 允许使用函数TerminateProcess中的进程句柄来终止进程。 ◇PROCESS_VM_OPERATION 允许使用函数VirtualProtectEx和WriteProcessMemory中的进程句柄来改变进程的虚拟内存。
◇PROCESS_VM_READ允许使用函数ReadProcessMemory中的进程句柄从虚拟内存中读出数据。
◇PROCESS_VM_WRITE 允许使用函数WriteProcessMemory中的进程句柄向虚拟内存中写人数据。
◇SYNCHRONIZE允许使用任何等待函数中的进程句柄来等待进程的终止。
·bInheritHandle若要子进程获得对该对象的访问权限,应设置为TRUE,否则设为FALSE。
·dwProcessId指定系统范围内的进程标志符。
返回值:若函数调用成功,则返回进程对象的句柄;否则返回FALSE。 (8)GetProcessTimes
函数功能:该函数用来获得与进程有关的时间信息。 函数格式:
BOOL GetProcessTimes( HANDLE hProcess, LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime); 参数:
·hProcess一个进程句柄。
·lpcreationTime 指定一个FILETIME结构,在其中含有进程的创建时间。 ·lpExitTime 指定一个FILETIME结构,在其中含有进程的中止时间。
·lpKernelTime 指定一个FILETIME结构,在其中含有进程在核心态运行时所消耗的时间。
·lpUserTime指定一个FILETIME结构,在其中含有进程在用户态运行时所消耗的时间。 返回值:如果函数调用成功,返回非零值;如果函数调用失败,返回值为0。 (9)CloseHandle
函数功能:该函数关闭一个打开的对象句柄。其作用为释放动态申请的内存空间,这样可以保证系统资源不会泄漏,程序可以在安全的状态下运行。
函数格式:
BOOL CloseHandle(HANDLE hObject); 参数:hObject打开对象的句柄。
返回值:如果函数调用成功,返回非零值;否则返回值为0。
备注:该函数可以关闭下列对象的句柄:通信设备、控制台输入、控制台屏幕缓冲区、事件、文件、文件映射、作业、邮件槽、临界区、命名管道、进程、信息量、套接字、线程、令牌。
CloseHandle函数使指定的对象句柄无效,减少对象的句柄数,并进行对象的保留检查,当一个对象的最后一个句柄被关闭后,该对象就从系统中被删除掉。
关闭一个线程的句柄并终止相关的线程,要删除一个线程对象,必须先终止该线程,并关闭该线程的所有句柄。
(10)Process32Next
函数功能:该函数用来获得系统快照中下一个进程的信息。 函数格式:
BOOL Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe); 参数:hSnapshot指定快照句柄;lppe指定一个PROCESSENTRY32结构。 返回值:如果进程列表的下一人口点被复制到缓冲区,返回TRUE。 为了理解进程句柄的应用,下面给出一个简单的获得句柄的方法。 例2-2获得和使用进程句柄,确定自身优先权的一个简单应用程序。 #include
HANDLE hProcessThis=GetCurrentProcess(); //从当前进程中提取句柄 //请求内核提供该进程所属的优先权类
DWORD dwPriority=GetPriorityClass(hProcessThis); //发出消息,为用户描述该类
printf(\:\switch(dwPriority) {
case HIGH_PRIORITY_CLASS: printf(\; break;
case NORMAL_PRIORITY_CLASS: printf(\; break;
case IDLE_PRIORITY_CLASS: printf(\ break;
//case REAL_TIME_ PRIORITY_CLASS: // printf(\; // break; default: printf(\ break; }}
为了进一步掌握进程句柄的应用,下面给出一个利用句柄获得进程详细信息的方法。
例2-3利用进程句柄获得进程详细信息, 应用程序显示当前运行进程名字以及在核心态下占用时间的百分比。
#include
#pragma comment(lib,\//当在用户态及核心态下都提供所耗时间时,计算在核心态下所消耗的时间(64位表示) DWORD GetKernelModePercentage(const FILETIME &ftKernel,const FILETIME &ftUser) {
//将FILETIME结构转化为64位整数
ULONGLONG qwKernel=(((ULONGLONG)ftKernel.dwHighDateTime) <<32)+ftKernel.dwLowDateTime;
ULONGLONG qwUser=(((ULONGLONG)ftUser.dwHighDateTime) <<32)+ftUser.dwLOWDateTime;
// 将消耗时间相加,然后计算消耗在核心状态下的时间百分比 ULONGLONG qwTotal=qwKernel+qwUser;
DWORD dwPct=(DWORD)(((ULONGLONG)100*qwKernel)/qwTotal); return(dwPct); } //
int main() {
//获得系统中当前进程的快照
HANDLE hSnapshot=CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, //获得当前进程 0); //如果是当前进程,就将其忽略 //初始化过程入口
PROCESSENTRY32 pe; //描述进程入口的PROCESSENTRY32结构 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) {//找出进程的时间
FILETIME ftCreation,ftKernelMode,ftUserMode,ftExit; GetProcessTimes(
hProcess, //所感兴趣的进程 &ftCreation, //进程的启动时间
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库14-15(2)实验指导书(3)在线全文阅读。
相关推荐: