久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

用Win32 API枚舉應(yīng)用程序窗口和進程

 QomoIT 2014-02-28
    摘要

  我們在編寫程序時,常常遇到的一件事情就是要準(zhǔn)確列出系統(tǒng)中所有正在運行的程序或者進程,。Windows 任務(wù)管理器就是這樣的一個程序,。它既能列出運行的桌面應(yīng)用程序,又能列出系統(tǒng)中所有運行的進程,。那么,,我們在程序中如何實現(xiàn)這樣的任務(wù)呢?本文下面將詳細討論這個問題,。

  枚舉頂層(top-level)窗口

  枚舉桌面頂層窗口相對于枚舉進程來說可能要容易一些,。枚舉桌面頂層窗口的方法是用 EnumWindows() 函數(shù)。不要用 GetWindow()來創(chuàng)建窗口列表,,因為窗口之間復(fù)雜的父子及同胞關(guān)系(Z-Order)容易造成混亂而使得枚舉結(jié)果不準(zhǔn)確,。

  EnumWindows()有兩個參數(shù),一個是指向回調(diào)函數(shù)的指針,,一個是用戶定義的 LPARAM 值,, 針對每個桌面窗口(或者頂層窗口)它調(diào)用回調(diào)函數(shù)一次。然后回調(diào)函數(shù)用該窗口句柄做一些處理,,比如將它添加到列表中,。這個方法保證枚舉結(jié)果不會被窗口復(fù)雜的層次關(guān)系搞亂,,因此,一旦有了窗口句柄,,我們就可以通過 GetWindowText() 得到窗口標(biāo)題,。

  枚舉進程

  建立系統(tǒng)進程列表比枚舉窗口稍微復(fù)雜一些。這主要是因為所用的 API 函數(shù)對于不同的 Win32 操作系統(tǒng)有依賴性,。在 Windows 9x,、Windows Me、Windows 2000 Professional 以及 Windows XP 中,,我們可以用 ToolHelp32 庫中的 APIs 函數(shù),。但是在 Windows NT 里,我們必須用 PSAPI 庫中的 APIs 函數(shù),, PSAPI 庫是 SDK 的一部分,。本文我們將討論上述所有平臺中的實現(xiàn)。附帶的例子程序?qū)ι鲜鰩熘械?APIs 進行包裝,,以便包裝后的函數(shù)能支持所有 Win32 操作系統(tǒng),。

  使用 ToolHelp32 庫枚舉進程

  ToolHelp32 庫函數(shù)在 KERNEL32.dll 中,它們都是標(biāo)準(zhǔn)的 API 函數(shù),。但是 Windows NT 4.0 不提供這些函,。

  ToolHelp32 庫中有各種各樣的函數(shù)可以用來枚舉系統(tǒng)中的進程、線程以及獲取內(nèi)存和模塊信息,。其中枚舉進程 只需用如下三個的函數(shù):CreateToolhelp32Snapshot(),、Process32First()和 Process32Next()。

  使用 ToolHelp32 函數(shù)的第一步是用 CreateToolhelp32Snapshot() 函數(shù)創(chuàng)建系統(tǒng)信息“快照”,。這個函數(shù)可以讓你選擇存儲在快照中的信息類型,。如果你只是對進程信息感興趣,那么只要包含 TH32CS_SNAPPROCESS 標(biāo)志即可,。 CreateToolhelp32Snapshot() 函數(shù)返回一個 HANDLE,,完成調(diào)用之后,必須將此 HANDLE 傳給 CloseHandle(),。

  接下來是調(diào)用一次 Process32First 函數(shù),,從快照中獲取進程列表,然后重復(fù)調(diào)用 Process32Next,,直到函數(shù)返回 FALSE 為止,。這樣將遍歷快照中進程列表。這兩個函數(shù)都帶兩個參數(shù),,它們分別是快照句柄和一個   PROCESSENTRY32 結(jié)構(gòu),。

  調(diào)用完 Process32First 或 Process32Next 之后,PROCESSENTRY32 中將包含系統(tǒng)中某個進程的關(guān)鍵信息,。其中進程 ID 就存儲在此結(jié)構(gòu)的 th32ProcessID,。此 ID 可以被傳給 OpenProcess() API 以獲得該進程的句柄,。對應(yīng)的可執(zhí)行文件名及其存放路徑存放在 szExeFile  結(jié)構(gòu)成員中。在該結(jié)構(gòu)中還可以找到其它一些有用的信息,。

  注意:在調(diào)用 Process32First() 之前,,一定要記住將 PROCESSENTRY32  結(jié)構(gòu)的 dwSize 成員設(shè)置成 sizeof(PROCESSENTRY32)。

  使用 PSAPI 庫枚舉進程

  在 Windows NT 中,,創(chuàng)建進程列表使用 PSAPI 函數(shù),,這些函數(shù)在 PSAPI.DLL 中。這個文件是隨 Platform SDK 一起分發(fā)的,,最新版本的 Platform SDK 可以從這里下載

  使用這個庫所需的 PSAPI.h 和 PSAPI.lib 文件也在該 Platform SDK 中,。

  為了使用 PSAPI 庫中的函數(shù),需將 PSAPI.lib 添加到代碼項目中,,同時在所有調(diào)用 PSAPI API 的模塊中包含 PSAPI.h 文件,。記住一定要隨可執(zhí)行文件一起分發(fā) PSAPI.DLL,因為它不隨 Windows NT 一起分發(fā),。你可以點擊這里單獨下載 PSAPI.DLL 的可分發(fā)版本(不用完全下載 Platform SDK),。

  與 ToolHelp32 一樣,PSAPI 庫也包含各種各樣有用的函數(shù),。由于篇幅所限,本文只討論與枚舉進程有關(guān)函數(shù):EnumProcesses(),、EnumProcessModules(),、GetModuleFileNameEx()和 GetModuleBaseName()。

  創(chuàng)建進程列表的第一步是調(diào)用 EnumProcesses(),。該函數(shù)的聲明如下:

BOOL EnumProcesses( DWORD *lpidProcess, DWORD cb, DWORD *cbNeeded );
  EnumProcesses()帶三個參數(shù),,DWORD 類型的數(shù)組指針 lpidProcess;該數(shù)組的大小尺寸 cb,;以及一個指向 DWORD 的指針 cbNeeded,,它接收返回數(shù)據(jù)的長度。DWORD 數(shù)組用于保存當(dāng)前運行的進程 IDs,。cbNeeded 返回數(shù)組所用的內(nèi)存大小,。下面算式可以得出返回了多少進程:nReturned = cbNeeded / sizeof(DWORD)。

  注意:雖然文檔將返回的 DWORD 命名為“cbNeeded”,,實際上是沒有辦法知道到底要傳多大的數(shù)組的,。EnumProcesses()根本不會在 cbNeeded 中返回一個大于 cb 參數(shù)傳遞的數(shù)組值。結(jié)果,,唯一確保 EnumProcesses()函數(shù)成功的方法是分配一個 DWORD 數(shù)組,,并且,如果返回的 cbNeeded 等于 cb,,分配一個較大的數(shù)組,,并不停地嘗試直到 cbNeeded 小于 cb

  現(xiàn)在,,你獲得了一個數(shù)組,其元素保存著系統(tǒng)中每個進程的ID,。如果你要想獲取進程名,,那么你必須首先獲取一個句柄。要想從進程 ID 得到句柄,,就得調(diào)用 OpenProcess(),。

  一旦有了句柄,則需要得到該進程的第一個模塊,。為此調(diào)用 EnumProcessModules() API:
EnumProcessModules( hProcess, &hModule, sizeof(hModule), &cbReturned );
  調(diào)用之后,,hModule 變量中保存的將是進程中的第一個模塊。記住進程其實沒有名字,,但進程的第一個模塊既是該進程的可執(zhí)行模塊?,F(xiàn)在你可以用 hModule 中返回的模塊句柄調(diào)用 GetModuleFileNameEx() 或 GetModuleBaseName() API 函數(shù)獲取全路徑名,或者僅僅是進程可執(zhí)行模塊名,。兩個函數(shù)均帶四個參數(shù):進程句柄,,模塊句柄,返回名字的緩沖指針以及緩沖大小尺寸,。

  用 EnumProcesses() API 返回的每一個進程 ID 重復(fù)這個調(diào)用過程,,你便可以創(chuàng)建 Windows NT 的進程列表。

  16位進程的處理方法

  在 Windows 95,,Windows 98 和 Windows ME 中,,ToolHelp32 對待16位程序一視同仁,它們與 Win32 程序一樣有自己的進程IDs,。但是在 Windows NT,,Windows 2000 或 Windows XP 中情況并不是這樣。在這些操作系統(tǒng)中,,16位程序運行在所謂的 VDM 當(dāng)中(也就是DOS機),。

  為了在 Windows NT,Windows 2000 和 Windows XP 中枚舉16位程序,,你必須使用一個名為 VDMEnumTaskWOWEx()的函數(shù),。在源代碼模塊中必須包含 VDMDBG.h,并且 VDMDBG.lib 文件必須與項目鏈接,。這兩個文件都在 Platform SDK 中,。該函數(shù)的聲明如下:
INT WINAPI VDMEnumTaskWOWEx( DWORD dwProcessId, TASKENUMPROCEX fp,LPARAM lparam );

  此處 dwProcessId 是 NTVDM 中擬枚舉的16位任務(wù)進程標(biāo)示符。參數(shù) fp 是回調(diào)枚舉函數(shù)的指針,。參數(shù) lparam 是用戶定義的值,,它被傳遞到枚舉函數(shù)。枚舉函數(shù)應(yīng)該被定義成如下這樣:

BOOL WINAPI Enum16( DWORD dwThreadId,  
                    WORD hMod16,  
                    WORD hTask16,  
                    PSZ pszModName,  
                    PSZ pszFileName,  
                    LPARAM lpUserDefined );
  該函數(shù)針對每個運行在 NTVDM 進程中的16位任務(wù)調(diào)用一次,NTVDM 進程ID將被傳入 VDMEnumTaskWOWEx(),。如果想繼續(xù)枚舉則返回 FALSE,,終止枚舉則返回 TRUE。注意這是與 EnumWindows()相對的,。

  關(guān)于代碼

  本文附帶的代碼例子將 PSAPI 和 ToolHelp32 封裝到一個名為 EnumProcs() 的函數(shù)中,。該函數(shù)的工作原理類似 EnumWindows(),有一個指向回調(diào)函數(shù)的指針,,并要對該函數(shù)進行重復(fù)調(diào)用,,針對系統(tǒng)中的每個進程調(diào)用一次。另一個參數(shù)是用戶定義的 lParam,。下面是該函數(shù)的聲明:
BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam );

  使用該函數(shù)時,,要象下面這樣聲明回調(diào)函數(shù):

BOOL CALLBACK Proc( DWORD dw, WORD w16, LPCSTR lpstr, LPARAM lParam );

  參數(shù) dw 包含 ID,“w16”是16位任務(wù)的任務(wù)號,,如果為32位進程則為0(在 Windows 95 中總是0),,參數(shù)lpstr 指向文件名,lParam 是用戶定義的,,要被傳入 EnumProcs(),。

  EnumProcs() 函數(shù)通過顯示鏈接使用 ToolHelp32 和 PSAPI,而非通常所用的隱式鏈接,。之所以要這樣做,,主要是為了讓代碼能夠在二進制一級兼容,從可以在所有 Win32 操作系統(tǒng)平臺上運行,。

(作者:NorthTibet責(zé)任編輯:方舟)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多