VB.NET實現超級ptm查看器
2024-07-10 13:00:35
供稿:網友
首先對文章名做一個解示,p是代表process,即進程,t是代表thread,即線程,m是代表module,即模塊。
在win nt,win 2000,win xp中都有一個性能查看器,我們可以用它來查看計算機上正在運行的程序,獲得與程序相關的主窗口名,和查看cpu和內存,虛擬頁面的使用情況。但是對于更高要求的計算機使用人員來說,這些是不夠的,特別是一些diy的發燒友,他們希望自己可以隨時對自己的計算機進行查看,了解更多的信息從而可以知道自己的計算機是否應該升級了,是否該對虛擬頁面做出調整,是否該換cpu,還是增加內存。
由于以上情況,所以我們完全有理由做一個更好的查看器。在進行編寫代碼以前我們還需要知道一些基本知識,即proccess,thread,module。現在我們先來學習一下proecss的基本知識。
1.proccss的概念
用最簡短的話來說,進程就是當前運行的應用程序。運行的應用程序包括exe,dll這兩種文件。文件和進程的差別在與,文件是保存在磁盤上的,是靜止的,計算機不會去調用文件,而進程是非靜止的,正是由于著個原因,所以計算機每調用一個進程就需要一定的資源。這些資源包括內存,虛擬頁面,句柄,gdi……
在.net中我門可以用process 類,(他位于system.diagnostics空間中)提供對正在計算機上運行的進程的訪問。使用 process類,可以獲取當前運行的進程的列表,或者啟動新的進程。process 類用于訪問系統進程。初始化 process類后,可使用該類來獲取有關當前運行的進程的信息。此類信息包括線程集、加載的模塊(.dll 和 .exe 文件)和性能信息(如進程當前使用的內存量)。
系統進程在系統上由其進程標識符唯一標識。與許多 windows 資源一樣,進程也由其句柄標識,而句柄在計算機上可能不唯一。句柄是表示資源標識符的一般術語。即使進程已退出,操作系統仍保持進程句柄,該句柄通過 process 組件的 handle 屬性訪問。因此,可以獲取進程的管理信息,如 exitcode(通常,或者為零表示成功,或者為非零錯誤代碼)和 exittime。句柄是非常有價值的資源。
2. thread的概念
進程由一個或多個線程組成。換句話說線程是將進程分成了多個小的部分.每個線程都有優先級,在較高優先級的線程完成任務的時候,較低優先級的線程可能會被迫等待。在多處理器計算機上,將多個線程移到不同的處理器上,從而對 cpu 負荷進行平衡。每個進程啟動時都具有一個線程,該線程稱為主線程。任何線程都可創建其他線程。進程中的所有線程共享該進程的地址空間。
在.net中可以用system.diagnostics的processthread類來與進程獲相關的線程信息.用system.threading的thread類來創建新線程.請注意thread類不可以用來訪問其他進程的線程,他只可以用來創建一個線程而已,一定要記住這點。如果你還想對線程進行更多的操作,可以用system.diagnostics.processthread類中返回的id,通過它作為api函數的參數來操作線程。
3. module的概念
模塊指的是可執行文件或動態鏈接庫 (dll)。每個進程包含一個或多個模塊。可以使用system.diagnostics的processmodule類來獲得有關模塊的信息,這個類中有一個很有用的屬性entrypointaddress他可以返回獲取在系統加載和運行模塊時運行的函數的內存地址。然后用visual studio6.0中的工具,查看該地址就可以知道是什么函數!然后根據函數名查看相關的資料,就可以知道這個應用程序的基本編程思路,這個功能對程序員很有用。
了解了基本知識,現在就就可以編程了。首先建立一個窗口,在窗口上加上一個tabcontrol分頁控件,在第一頁加上label1,label2,listbox1,listbox2,button1。在第二頁上加上label4,label6,listbox3,listbox4,在第三頁上加上label5,label7,listbox5,listbox6。將所有的listbox控件的horizontalscrollbar屬性設置為true
然后添加如下代碼(vb.net編寫)
public class form1
inherits system.windows.forms.form
public zj
public myprocesses() as process
public myprocess as process
private sub button1_click(byval sender as system.object, byval e as system.eventargs) handles button1.click
listbox1.items.clear()
myprocesses = process.getprocesses()
for each myprocess in myprocesses
listbox1.items.add(myprocess.processname)
next
label1.text = ""
label1.text = "本機共有" & listbox1.items.count & "個進程在運行"
end sub
private sub listbox1_doubleclick(byval sender as system.object, byval e as system.eventargs) handles listbox1.doubleclick
dim i : dim f as integer : dim h as integer
listbox2.items.clear()
zj = listbox1.selectedindex
label2.text = "進程" & listbox1.items.item(zj) & "的相關信息"
with listbox2.items
if myprocesses(zj).mainwindowtitle = "" then
.add("無相關主窗口")
else
.add(myprocesses(zj).mainwindowtitle)
end if
.add(myprocesses(zj).basepriority & "進程的基本優先級")
.add(myprocesses(zj).handle.tostring & "進程的本機句柄")
.add(myprocesses(zj).handlecount & "進程打開的句柄數")
.add(myprocesses(zj).id & "進程的唯一標識符")
.add(myprocesses(zj).machinename & "進程正在其上運行的計算機的名稱")
.add(myprocesses(zj).mainmodule.tostring & "進程的主模塊")
.add(myprocesses(zj).mainwindowhandle.tostring & "進程主窗口的句柄")
'.add(myprocesses(zj).modules & "")
.add(myprocesses(zj).nonpagedsystemmemorysize & "分配給此進程的未分頁的系統內存大小")
.add(myprocesses(zj).pagedmemorysize & "分頁的內存大小")
.add(myprocesses(zj).pagedsystemmemorysize & "分頁的系統內存大小")
.add(myprocesses(zj).peakpagedmemorysize & "峰值分頁內存大小")
.add(myprocesses(zj).peakvirtualmemorysize & "峰值虛擬內存大小")
.add(myprocesses(zj).privatememorysize & "專用內存大小")
.add(myprocesses(zj).starttime & "進程啟動的時間")
.add(myprocesses(zj).totalprocessortime.seconds & "進程的總的處理器時間")
.add(myprocesses(zj).userprocessortime.seconds & "進程的用戶處理器時間")
.add(myprocesses(zj).virtualmemorysize & "進程的虛擬內存大小")
end with
listbox3.items.clear()
tabpage1.text = "進程" & listbox1.items.item(zj) & "的基本信息"
tabpage2.text = "進程" & listbox1.items.item(zj) & "相關的線程信息"
tabpage3.text = "進程" & listbox1.items.item(zj) & "相關的模塊信息"
'/////////////////////////////////////////////
f = myprocesses(zj).threads.count
label4.text = "進程" & listbox1.items.item(zj) & "共有" & f & "個相關的線程,線程id信息如下:"
dim int, pk, m, n
for n = 0 to f - 1
listbox3.items.add(myprocesses(zj).threads(n).id)
next
'///////////////////////////////////////
listbox5.items.clear()
dim zha, kl
zha = myprocesses(zj).modules.count
label5.text = "與進程" & listbox1.items.item(zj) & "共有" & zha & "個相關的模塊,模塊位置信息如下:"
for kl = 0 to zha - 1
listbox5.items.add(myprocesses(zj).modules(kl).filename)
next
end sub
private sub listbox3_doubleclick(byval sender as object, byval e as system.eventargs) handles listbox3.doubleclick
listbox4.items.clear()
dim f, n
f = myprocesses(zj).threads.count
n = listbox3.selectedindex
label6.text = "線程" & listbox3.items.item(n) & "相關信息"
with listbox4.items‘與進程相關的線程信息見system.diagnostics.processthread類。因為processes.threads屬性是返回thread對象數組而thread對象數組的實例是由processthread類來創建,thread對象數組的信息是包含在system.diagnostics. processthread類中。
.add(myprocesses(zj).threads(n).basepriority)
.add(myprocesses(zj).threads(n).currentpriority)
.add(myprocesses(zj).threads(n).prioritylevel)
.add(myprocesses(zj).threads(n).privilegedprocessortime)
.add(myprocesses(zj).threads(n).starttime)
.add(myprocesses(zj).threads(n).threadstate.tostring)
.add(myprocesses(zj).threads(n).totalprocessortime.seconds)
.add(myprocesses(zj).threads(n).userprocessortime.seconds)
.add(myprocesses(zj).threads(n).waitreason.tostring)
end with
end sub
private sub listbox5_doubleclick(byval sender as object, byval e as system.eventargs) handles listbox5.doubleclick
listbox6.items.clear()
dim f, n, m
f = myprocesses(zj).modules.count
n = listbox5.selectedindex
label7.text = "模塊" & listbox5.items.item(n) & "相關信息"
with listbox6.items‘與進程相關的模塊信息見system.diagnostics. processmodule類,因為processes.modules屬性是返回modules對象數組而modules對象數組的實例是由processmodule類來創建,modules對象數組的信息是包含在system.diagnostics. processmodule類中。
m = hex(myprocesses(zj).modules(n).baseaddress.toint32)‘轉換成16進制
.add(m)
m = hex(myprocesses(zj).modules(n).entrypointaddress.toint32)
.add(m)
.add(myprocesses(zj).modules(n).fileversioninfo)
.add(myprocesses(zj).modules(n).modulememorysize)
.add(myprocesses(zj).modules(n).modulename)
end with
end sub
end class 這下就大工告成了,最后對程做一點補充說明,各位讀者,當你知道了如何編寫這個程序時,你可能會想如果只是寫一個單純的這個程序你可能會覺得沒什么意義,那如何才可以將這段程序發揮他更大的意義?就讓我來告訴你。其實這段代碼并不是我刻意編寫的,而是一個局域網中的遠程控制的一部分。掃描客戶機上運行的進程,查看客戶機的資源,將獲得的信息發個服務器,并可以通過processes類來關閉客戶機上的進程,以便管理者對客戶機進行管理。此外寫這篇文章的另一個目的是希望讀者更快的掌握.net中system.diagnostics.process,system.diagnostics.processthread,system.diagnostics. processmodule類。在vb.net和win2000通過 。