(Post 21/05/2009) Trong khi lập trình các ứng
dụng, một số bạn sẽ gặp phải yêu cầu kiểm tra hệ thống và liệt kê tất
cả ứng dụng đang chạy (như tiện ích "Task Manager") và trong
một số trường hợp còn cần đến cách thức để "kill" các ứng dụng
đó. Bài viết sẽ trình bày cách hiện thực các yêu cầu này bằng VB6.
Một chương trình được kích hoạt từ 1 tập tin (file) khả
thi *.exe nằm ở vị trí xác định trên đĩa cứng. Khi chương trình chạy,
nó trở thành tiến trình (process) trong máy, mỗi process sẽ được nhận
dạng bằng 1 tên nhận dạng (ID) ở dạng số nguyên. Một file khả thi có thể
được kích hoạt chạy nhiều lần để trở thành nhiều process khác nhau. Do
đó, để nhận dạng process, HĐH dùng định danh riêng (ID) của process. Tuy
nhiên, người dùng thường nhận dạng process bằng tên file khả thi của chương
trình (nên dùng đường dẫn tuyệt đối của file khả thi để tránh nhầm lẫn
giữa các file chương trình nằm ở các thư mục khác nhau nhưng có cùng tên
file).
Nếu đang lập trình trên HĐH tương thích với WinNT (NT,
2000, XP, Vista...), bạn có thể dùng thư viện quản lý process có tên là
PSAPI của Microsoft để duyệt các process đang chạy (thông qua các hàm
EnumProcesses, EnumProcessModule, OpenProcess, GetModuleFileNameEx...)
và xóa process theo yêu cầu. Sau đây là qui trình điển hình để viết 1
ứng dụng VB đơn giản giải quyết các yêu cầu của bạn:
1. Chạy VB 6.0,
tạo project loại "Standard EXE". Sau khi Form trống hiển thị,
hãy thiết kế Form có dạng sau:
Trong đó button "List Process" có tên là btnList,
button "Kill Process" có tên là btnKill, textbox nhập ID có
tên là txtProcessID, listbox để chứa danh sách các process có tên là lbProcesses.
2. Nhấn đúp chuột
vào button ListProcess để tạo thủ tục xử lý sự kiện click chuột trên button
này rồi viết code như sau:
'code cho Form ứng dụng
Option Explicit
'thủ tục xóa 1 process
Private Sub btnKill_Click()
Dim hProcess As Long
Dim retval As Long
'lấy handle của Process xác định bởi người dùng
hProcess = OpenProcess(SYNCHRONIZE Or PROCESS_TERMINATE, 0, CLng( txtProcessID.Text))
If hProcess <> 0 Then
'xóa process tương ứng
retval=TerminateProcess(hProcess, 0)
End If
End Sub
'thủ tục hiển thị danh sách process
'mỗi process hiển thị 2 thông tin: ID và đường dẫn file khả thi
Private Sub btnList_Click()
Dim cb As Long
Dim cbNeeded As Long
Dim NumElements As Long
Dim ProcessIDs() As Long
Dim cbNeeded2 As Long
Dim NumElements2 As Long
Dim Modules(1 To 200) As Long
Dim lRet As Long
Dim ModuleName As String
Dim nSize As Long
Dim hProcess As Long
Dim i As Long
lbProcesses.Clear
'tạo array chứa ID của các process
cb = 8
cbNeeded = 96
Do While cb <= cbNeeded
cb = cb * 2
ReDim ProcessIDs(cb / 4) As Long
lRet = EnumProcesses(ProcessIDs(1), cb, cbNeeded)
Loop
NumElements = cbNeeded / 4
For i = 1 To NumElements
'lấy handle của Process thứ i
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0,
ProcessIDs(i))
'kiểm tra handle
If hProcess <> 0 Then
'lấy danh sách các module handles thuộc process
lRet=EnumProcessModules(hProcess, Modules(1), 200, cbNeeded2)
'nếu có, lấy tên file khả thi tương ứng
If lRet <> 0 Then
ModuleName = Space(MAX_PATH)
nSize = 500
lRet = GetModuleFileNameExA(hProcess, Modules(1), ModuleName, nSize)
'hiển thị thông tin lên listbox
lbProcesses.AddItem Format(ProcessIDs(i), "000000") & ":
" & Left(ModuleName, lRet)
End If
End If
'Close the handle to the process
lRet = CloseHandle(hProcess)
Next
End Sub
3. Dời chuột về
cửa sổ Process, nhấn phải chuột trên phần tử gốc, chọn menu Add.Module
để tạo 1 module mới (tên mặc định là Module1) rồi viết đoạn code VB sau
đây vào module mới này:
'khai báo các hàm API cần gọi
Public Declare Function Process32First Lib "kernel32" (ByVal
hSnapshot As Long, lppe As PROCESSENTRY32) As Long
Public Declare Function Process32Next Lib "kernel32" (ByVal
hSnapshot As Long, lppe As PROCESSENTRY32) As Long
Public Declare Function CloseHandle Lib "Kernel32.dll" (ByVal
Handle As Long) As Long
Public Declare Function OpenProcess Lib "Kernel32.dll" (ByVal
dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId
As Long) As Long
Public Declare Function EnumProcesses Lib "psapi.dll" (ByRef
lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function GetModuleFileNameExA Lib "psapi.dll"
(ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String,
ByVal nSize As Long) As Long
Public Declare Function EnumProcessModules Lib "psapi.dll" (ByVal
hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded
As Long) As Long
Public Declare Function CreateToolhelp32Snapshot Lib "kernel32"
(ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Public Declare Function GetVersionExA Lib "kernel32" (lpVersionInformation
As OSVERSIONINFO) As Integer
Public Declare Function TerminateProcess Lib "kernel32" (ByVal
hProcess As Long, ByVal uExitCode As Long) As Long
'khai báo kiểu dữ liệu cần dùng
Public Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long ' This process
th32DefaultHeapID As Long
th32ModuleID As Long
' Associated exe
cntThreads As Long
th32ParentProcessID As Long
' This process's parent process
pcPriClassBase As Long
' Base priority of process threads
dwFlags As Long
szExeFile As String * 260 ' MAX_PATH
End Type
Public Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
'1 = Windows 95, 2 = Windows NT
szCSDVersion As String * 128
End Type
Public Const PROCESS_QUERY_INFORMATION = 1024
Public Const PROCESS_VM_READ = 16
Public Const PROCESS_TERMINATE = 1
Public Const MAX_PATH = 260
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const SYNCHRONIZE = &H100000
Public Const PROCESS_ALL_ACCESS = &H1F0FFF
Public Const TH32CS_SNAPPROCESS = &H2&
Public Const hNull = 0
4. Chọn menu Run.Start
để chạy thử ứng dụng, nhấn button List Process để xem danh sách các process,
nhập ID process cần xóa rồi ấn nút Kill Process để xóa process theo yêu
cầu.
Chúc các bạn thành công.
Nguyễn Văn Hiệp
(theo PC World VN) |