Archive: Getting to know if a process is running or not using the application name


Getting to know if a process is running or not using the application name
  Hello,

I have a case where I am running some exe in silent mode so basically I do not have a UI but it will show up under Applications tab in Task manager. Is there a way to know if that process is running or is it completed using this Application name.

I found so many answers reagrding using Process name to check if it is still running or not. But in my case the process name is not unique and I may end up checking any other process with the same name, which is not correct.

I know the application what I will be running, hence wanted to use the same to check if it is running.

P.S: Here application name is nothing but the executable exe name.

How this can be accomplished?


Easy solution: Rename your exe to something unique, before you execute it.


A unique name is not such an easy thing to create - what if the user runs the setup two times (back to back or simultaneously)?

Maybe prakashjv can get the process id since he says he is running the process. That will be unique, and can be checked later to see if it is still running.


Originally posted by demiller9
A unique name is not such an easy thing to create - what if the user runs the setup two times (back to back or simultaneously)?
what's wrong with GetTempFileName or even CreateGUID?

Tempfilenames are unique within a particular directory, not necessarily unique on the whole system. Running the installer twice might be done from different directories, and could theoretically result in identical filenames.

GUIDs are system unique, but won't necessarily give a unique process name; on Windows 2000 the process names are 15 characters or shorter. Longer names (like a GUID) are truncated.


I made some functions for that..

If the exe in question is made with nsis, you can use the mutex method to prevent multiple instances, by puting this in it:

;; return: 0=succes, 183=failed to create handle (mutex already exists)

!define CreateMutex "!insertmacro _CreateMutex"
>!macro _CreateMutex _RetVal_ _MutexName_
System::Call /nounload 'kernel32::CreateMutexA(i 0, i 0, t "${_MutexName_}") ?e'
Pop ${_RetVal_}
!macroend
>
Example:

OnInit

${CreateMutex} $0 "SomeUniqueMutexName"
IntCmp $0 0 +2
Quit

>/* some code... */

>FunctionEnd
>

...Or, if you execute the exe file from a nsis script, and you need to keep track of it, you can use this:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Gets the parent folder
>;; P1 :out: Folder containing file or dir (parent folder)
;;P2 :in: File/Dir
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!
define PathPath "!insertmacro _PathPath"
>!macro _PathPath _RetVal_ _Path_
Push "${_Path_}"
Call PathPath
Pop "${_RetVal_}"
>!macroend
>Function PathPath
Exch$0 ;; Path
Push$1 ;; Strlen / Counter
Push$2 ;; Curchar

StrLen$1 '$0'
IntCmp $1 0 +6
IntOp$1 $1 - 1
StrCpy$2 "$0" 1 $1
StrCmp "$2" "\" +3
StrCmp "$2" ":" 0 -4
IntOp $1 $1 + 1

StrCpy $0 "$0" $1 0

Pop $2
Pop $1
Exch $0
FunctionEnd

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Executes files with ShellExecuteEx Api
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; P1 :out: Return value, depends on the mode (P5)
;; P2 :in: Verb. if="" then open with default associated app
;; P3 :in: File
;; P4 :in: File parameters
;; P5 :in: Working directory. if="" then its set to the same dir as the file
;; P6 :in: Show flag. if="" then SH_SHOW is used (see http://msdn.microsoft.com/en-us/library/bb762153(v=VS.85).aspx )
;; P7 :in: Mode: 1=Nowait, Returns Process Id
;; 2=Nowait, Returns Process Handle (must close the handle yourself)
;; 3=Wait, Returns Process Exit Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!define ShellExecEx "!insertmacro _ShellExecEx"
!macro _ShellExecEx _RetVal_ _Verb_ _File_ _Params_ _WorkDir_ _Show_ _Mode_
Push `${_Mode_}`
Push `${_Show_}`
Push `${_WorkDir_}`
Push `${_Params_}`
Push `${_File_}`
Push `${_Verb_}`
Call ShellExecEx
Pop ${_RetVal_}
!macroend
Function ShellExecEx
Exch $0
Exch
Exch $1
Exch 2
Exch $2
Exch 3
Exch $3
Exch 4
Exch $4
Exch 5
Exch $5
Push "$9"

StrCmpS "" "$3" 0 wdok
${PathPath} $3 "$3"
wdok:
StrCmpS "" "$4" 0 +2 ;; if show mode is undefined, then
StrCpy $4 0x05 ; = SH_SHOW
System::Call /nounload '*(&i60) i .r9' ;; allocate the structure
System::Call /nounload '*$9(i 60, i 0x140, i $HWNDPARENT, t r0, t r1, t r2, t r3, i r4) i .r9' ;; assign the values to the struct
System::Call /nounload 'Shell32::ShellExecuteEx(i r9) i .r1' ;; execute the file
StrCmpS 0 $1 0 +4 ;; if there was errors, then
StrCpy $3 0 ; set return value to 0 and set the error flag
SetErrors
Goto end

System::Call /nounload '*$9(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i .r2)'

IntCmp $5 2 +4 0 +6 ;; 1:nowait-pid, 2:nowait-handle, 3:wait-exitcode
System::Call /nounload 'kernel32::GetProcessId(i r2) i .r4'
System::Call /nounload 'kernel32::CloseHandle(i r2)'
Goto end
; hmode:
StrCpy $4 "$2"
Goto end
; wmode:
System::Call /nounload 'kernel32::WaitForSingleObject(i r2, i -1)'
System::Call /nounload 'kernel32::GetExitCodeProcess(i r2,*i .r4)'
System::Call /nounload 'kernel32::CloseHandle(i r2)'

end:
System::Free /nounload $9
Pop $9
Pop $5
Pop $0
Pop $1
Pop $2
Pop $3
Exch $4
FunctionEnd
>
and use a macro like this to determine if a specific instance of an executable is still running (with ShellExecEx mode 2):

still exists

>!define IfProcExistsH "!insertmacro _IfProcExistsH"
>!macro _IfProcExistsH _ProcHandle_ _GotoIfTrue_ _GotoIfFalse_
Push "$0"
ClearErrors
System
::Call /nounload 'kernel32::WaitForSingleObject(i ${_ProcHandle_}, i 0) i .r0'
IntCmp $0 0 +3
System::Call /nounload 'kernel32::CloseHandle(i ${_ProcHandle_})'
SetErrors
Pop$0
IfErrors${_GotoIfTrue_} ${_GotoIfFalse_}
!macroend
>
Example:

2

loop:
>/* some code here.. */
>${IfProcExistsH} $0 0 +3
MessageBox MB_OK "The process still exists."
Goto loop
MessageBox MB_OK "The process doesn't exists anymore!"
And ShellExecEx is usefull for so much more than checking the presence of a process..

Have a good day. ;)