Is Process Running

By | 2002-06-01

This is do determine if any exe is already running. This handles the multithreading issues of NT, and it works on 95,98,NT. I got most of this straight from Microsoft, but have wrapped and cleaned it up alot.

Original Author: James N. Wink

Inputs

Pass it the EXE Name you want to know if it is running

Assumptions

Test it with Notepad.exe or something first, and keep in mind that if you are debugging the application you want to use this with, that VB6.EXE is the process you are running, and until you compile and run your exe it will not see the app you are using.

Returns

True if process is running, else false.

API Declarations

Option Explicit
‘Used to determine Process Information
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
Public Const PROCESS_ALL_ACCESS = &H1F0FFF
Public Const TH32CS_SNAPPROCESS = &H2&
Public Const hNull = 0
Public Const WIN95_System_Found = 1
Public Const WINNT_System_Found = 2
Public Const Default_Log_Size = 10000000
Public Const Default_Log_Days = 0
‘Types Used by Win API’s
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
‘Used to determine process information
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

Code

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' IsProcessRunning
'
' Date: 07/13/1999
' Comapany: WEI
' Web Site: http://www.winkenterprises.com
' Author: James N.Wink
' Email: james@winkenterprises.com
'
' Description: Used to determine if a process is running.
'
' Input: EXEName - String  EXE name of the Process
'
' Output: IsProcessRunning - Boolean Returns True if running
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function IsProcessRunning(ByVal EXEName As String) As Boolean
'Used if Win 95 is detected
Dim booResult As Boolean
Dim lngLength As Long
Dim lngProcessID As Long
Dim strProcessName As String
Dim lngSnapHwnd As Long
Dim udtProcEntry As PROCESSENTRY32
'Used if NT is detected
Dim lngCBSize As Long 'Specifies the size, in bytes, of the lpidProcess array
Dim lngCBSizeReturned As Long 'Receives the number of bytes returned
Dim lngNumElements As Long
Dim lngProcessIDs() As Long
Dim lngCBSize2 As Long
Dim lngModules(1 To 200) As Long
Dim lngReturn As Long
Dim strModuleName As String
Dim lngSize As Long
Dim lngHwndProcess As Long
Dim lngLoop As Long
'Turn on Error handler
On Error GoTo IsProcessRunning_Error

booResult = False

EXEName = UCase$(Trim$(EXEName))
lngLength = Len(EXEName)

Select Case getVersion()
  Case WIN95_System_Found 'Windows 95/98
  'Get SnapShot of Threads
  lngSnapHwnd = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  'Check to see if SnapShot was made
  If lngSnapHwnd = hNull Then GoTo IsProcessRunning_Exit
  'Set Size in UDT, must be done, prior to calling API
  udtProcEntry.dwSize = Len(udtProcEntry)
  ' Get First Process
  lngProcessID = Process32First(lngSnapHwnd, udtProcEntry)
  Do While lngProcessID
   'Get Full Path Process Name
   strProcessName = StrZToStr(udtProcEntry.szExeFile)
   'Check for Matching Upper case result
  
   strProcessName = Ucase$(Trim$(strProcessName))
   If Right$(strProcessName, lngLength) = EXEName Then
    'Found
    booResult = True
    GoTo IsProcessRunning_Exit
   End If
   'Not found, get next Process
   lngProcessID = Process32Next(lngSnapHwnd, udtProcEntry)
  Loop
  Case WINNT_System_Found 'Windows NT
  'Get the array containing the process id's for each process objec
  '  t
  'Set Default Size
  lngCBSize = 8 ' Really needs to be 16, but Loop will increment prior to calling API
  lngCBSizeReturned = 96
  'Check to see if Process ID's were returned
  Do While lngCBSize <= lngCBSizeReturned
   'Increment Size
   lngCBSize = lngCBSize * 2
   'Allocate Memory for Array
   ReDim lngProcessIDs(lngCBSize / 4) As Long
   'Get Process ID's
   lngReturn = EnumProcesses(lngProcessIDs(1), lngCBSize, lngCBSizeReturned)
  Loop
  'Count number of processes returned
  lngNumElements = lngCBSizeReturned / 4
  'Loop thru each process
  For lngLoop = 1 To lngNumElements
   'Get a handle to the Process and Open
   lngHwndProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
   Or PROCESS_VM_READ, 0, lngProcessIDs(lngLoop))
   'Check to see if Process handle was returned
   If lngHwndProcess <> 0 Then
    'Get an array of the module handles for the specified process
    lngReturn = EnumProcessModules(lngHwndProcess, lngModules(1), 200, lngCBSize2)
    'If the Module Array is retrieved, Get the ModuleFileName
    If lngReturn <> 0 Then
     'Buffer with spaces first to allocate memory for byte array
     strModuleName = Space(MAX_PATH)
     'Must be set prior to calling API
     lngSize = 500
     'Get Process Name
     lngReturn = GetModuleFileNameExA(lngHwndProcess, lngModules(1), _
     strModuleName, lngSize)
     'Remove trailing spaces
     strProcessName = Left(strModuleName, lngReturn)
     'Check for Matching Upper case result
     strProcessName = UCase$(Trim$(strProcessName))
     If Right$(strProcessName, lngLength) = EXEName Then
      'Found
      booResult = True
      GoTo IsProcessRunning_Exit
     End If
    End If
   End If
   'Close the handle to this process
   lngReturn = CloseHandle(lngHwndProcess)
  Next
End Select
GoTo IsProcessRunning_Exit
IsProcessRunning_Error:
Err.Clear
booResult = False
IsProcessRunning_Exit:
'Turn off Error handler
On Error GoTo 0
IsProcessRunning = booResult
End Function
Private 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
Private Function StrZToStr(s As String) As String
StrZToStr = Left$(s, Len(s) - 1)
End Function

Author: dwirch

Derek Wirch is a seasoned IT professional with an impressive career dating back to 1986. He brings a wealth of knowledge and hands-on experience that is invaluable to those embarking on their journey in the tech industry.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.