怎样判断一个EXE文件是否已经执行?

DawnPine 2003-11-07 06:16:10
怎样判断一个EXE文件是否已经执行?
...全文
16 点赞 收藏 6
写回复
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
DawnPine 2003-11-08
再一次谢谢 rainstormmaster
回复
xzp1030 2003-11-08
How can I detect whether my program is already running?

Visual Basic has a function called 'PrevInstance'. If the same program is started twice, this Boolean will have the value 'True'. If the program has only been started once, this Boolean will have the value 'False'. If you want your program to end, if the same program has already been loaded, just add this line to your program:

Private Sub Form_Load()
If App.PrevInstance Then End
End Sub



回复
rainstormmaster 2003-11-08
模块:
Option Explicit
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 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 MAX_PATH = 260
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const SYNCHRONIZE = &H100000
'STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
Public Const PROCESS_ALL_ACCESS = &H1F0FFF
Public Const TH32CS_SNAPPROCESS = &H2&
Public Const hNull = 0

Function StrZToStr(s As String) As String
StrZToStr = Left$(s, Len(s) - 1)
End Function

Public Function getVersion() As Long
Dim osinfo As OSVERSIONINFO
Dim retvalue As Integer
osinfo.dwOSVersionInfoSize = 148
osinfo.szCSDVersion = Space$(128)
retvalue = GetVersionExA(osinfo)
getVersion = osinfo.dwPlatformId
End Function

窗体:一个listbox,一个按钮
Option Explicit

Private Sub Command1_Click()
List1.Clear
Select Case getVersion()

Case 1 'Windows 95/98

Dim f As Long, sname As String
Dim hSnap As Long, proc As PROCESSENTRY32
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
If hSnap = hNull Then Exit Sub
proc.dwSize = Len(proc)
' Iterate through the processes
f = Process32First(hSnap, proc)
Do While f
sname = StrZToStr(proc.szExeFile)
List1.AddItem sname
f = Process32Next(hSnap, proc)
Loop

Case 2 'Windows NT

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
'Get the array containing the process id's for each process object
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
'Get a handle to the Process
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
Or PROCESS_VM_READ, 0, ProcessIDs(i))
'Got a Process handle
If hProcess <> 0 Then
'Get an array of the module handles for the specified
'process
lRet = EnumProcessModules(hProcess, Modules(1), 200, _
cbNeeded2)
'If the Module Array is retrieved, Get the ModuleFileName
If lRet <> 0 Then
ModuleName = Space(MAX_PATH)
nSize = 500
lRet = GetModuleFileNameExA(hProcess, Modules(1), _
ModuleName, nSize)
List1.AddItem Left(ModuleName, lRet)
End If
End If
'Close the handle to the process
lRet = CloseHandle(hProcess)
Next

End Select
MsgBox IsRun("C:\WINDOWS\rUNDLL32.EXE")
End Sub

Private Function IsRun(ByVal filename As String) As Boolean
Dim i As Long
IsRun = False
For i = 1 To List1.ListCount
Debug.Print List1.List(i)
If List1.List(i) = UCase(filename) Then

IsRun = True
Exit Function
End If
Next

End Function


回复
DawnPine 2003-11-08
谢谢rainstormmaster的答案。
不过,如果在执行到Kill filename这句时出了点问题,比如断电、死机什么的,对于用户来说,这个可执行文件就不存在了,需要人工干预进行维护(从BAK恢复)。尽管这种概率很低,可一旦发生会让用户感到很不爽。
另一个缺憾是,如果当前用户仅有读、执行权限而没有写权限时,这个方法就不灵了。
你说到的枚举法是怎么回事?
有无现成的API能解决此类问题?或者哪位大侠有更好的见解?

另:谢谢聪慧的参与。我题目里没说清楚,我要的是通过VB编程实现。
回复
conghui 2003-11-07

<状态栏>上右击,选择<任务管理器>
在打开的画面中选择<进程>,在此就可以看到你所运行的程序.(.exe文件)
回复
rainstormmaster 2003-11-07
用错误陷阱实现的,通常的做法是枚举正在运行的程序
Option Explicit

Private Function IsRun(ByVal filename As String) As Boolean
On Error GoTo myerr
Dim mytempfile As String
mytempfile = App.Path + "\mytemp.bak"
FileCopy filename, mytempfile
Kill filename
IsRun = False
FileCopy mytempfile, filename
Kill mytempfile
Exit Function
myerr:
Select Case Err.Number
Case 75
Kill mytempfile
IsRun = True
Exit Function
Case Else
MsgBox Err.Description

End Select
End Function
'调用
Private Sub Command1_Click()
MsgBox IsRun("d:\mc\Duba_CodeBlue1.EXE")
End Sub
回复
发动态
发帖子
VB基础类
创建于2007-09-28

7449

社区成员

VB 基础类
申请成为版主
社区公告
暂无公告