FindProcess: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(corrected error (wouldn't work for a single process), added example)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This function was written with inspiration of [[Get_a_list_of_running_processes]], which pops up a message box for each running process. This function returns a boolean (0/1) if any of the processes in the input parameter are running.
{{PageAuthor|demiller9}}This function was written with inspiration of [[Get a list of running processes]], which pops up a message box for each running process. This function returns a boolean (0/1) if any of the processes in the input parameter are running.


Save this script as FindProcess.nsh and include it in your script. Call it like this:
Save this script as FindProcess.nsh and include it in your script. Call it like this:
  !include FindProcess.nsh
<highlight-nsis>!include FindProcess.nsh
    
    
  ${FindProcess} "Calc.exe,Firefox.exe" $0
${FindProcess} "Calc.exe,Firefox.exe" $0
  ${If} $0 <> 0
${If} $0 <> 0
    MessageBox MB_OK "Found at least one process"
  MessageBox MB_OK "Found at least one process"
  ${Else}
${Else}
    MessageBox MB_OK "Neither process found"
  MessageBox MB_OK "Neither process found"
  ${EndIf}
${EndIf}</highlight-nsis>


or in a loop like this:
or in a loop like this:
  ${Do}
<highlight-nsis>${Do}
    ${FindProcess} "Notepad.exe" $0
  ${FindProcess} "Notepad.exe" $0
    Sleep 500
  Sleep 500
  ${LoopWhile} $0 <> 0
${LoopWhile} $0 <> 0</highlight-nsis>


== FindProcess.nsh ==
== FindProcess.nsh ==


  /*  FindProcess.nsh
<highlight-nsis>/*  FindProcess.nsh
  *   
*   
  *  written by Donald Miller
*  written by Donald Miller
  *  Mar 7, 2007
*  Mar 7, 2007
   *   
   */
*/
   
!include LogicLib.nsh
!include WordFunc.nsh
!insertmacro WordFind
   
!ifndef FindProcess
!define FindProcess        '!insertmacro FindProcess'
   
!macro FindProcess ProcessList BoolReturn
    Push '${ProcessList}'
    Call FindProcess
    Pop ${BoolReturn}
!macroend
 
Function FindProcess
  # return True if any process in ProcessList is active
  Exch $0    ; get ProcessList, save $0
  Push $1
  Push $2
  Push $R0
  Push $R1
  Push $R2
 
  StrCpy $2 "$0,"                ; $2 = ProcessList
 
  Push 0                          ; set return value = False
 
  # method based upon one by Phoenix1701@gmail.com  1/27/07
 
  System::Alloc 1024
  Pop $R0                        ; process list buffer
 
  # get an array of all process ids
   System::Call "Psapi::EnumProcesses(i R0, i 1024, *i .R1)i .r0"
   ${Unless} $0 = 0
    
      IntOp $R1 $R1 / 4          ; Divide by sizeof(DWORD) to get $R1 process count
      IntOp $R1 $R1 - 1          ; decr for 0 base loop
     
      ClearErrors
      ${For} $R2 0 $R1
          # get a PID from the array
          IntOp $0 $R2 << 2
          IntOp $0 $0 + $R0          ; buffer.dword[i]
          System::Call "*$0(i .r0)"  ; Get next PID
         
          ${Unless} $0 = 0
              Push $0
              Call GetProcessName
              Pop $1
             
              # is this process one we are looking for?
              ${WordFind} '$2' ',' 'E/$1' $0
              ${Unless} ${Errors}
                  # yes, change return value
                  Pop $0          ; discard old result
                  Push 1          ; set return True
                 
                  # exit the loop
                  ${Break}
              ${EndUnless}
          ${EndUnless}
      ${Next}
     
  ${EndUnless}
 
  System::Free $R0
 
  Pop $0              ; get return value
  Pop $R2            ; restore registers
  Pop $R1
  Pop $R0
  Pop $2
  Pop $1
  Exch $0
FunctionEnd
 
Function GetProcessName
  # ( Pid -- ProcessName )
  Exch $2                    ; get Pid, save $2
  Push $0
  Push $1
  Push $3
  Push $R0
 
  System::Call "Kernel32::OpenProcess(i 1040, i 0, i r2)i .r3"
 
  StrCpy $2 "<unknown>"      ; set return value
 
  ${Unless} $3 = 0            ; $3 is hProcess
      # get hMod array
      System::Alloc 1024
      Pop $R0
        
        
  !include LogicLib.nsh
      # params: Pid, &hMod, sizeof(hMod), &cb
  !include WordFunc.nsh
      System::Call "Psapi::EnumProcessModules(i r3, i R0, i 1024, *i .r1)i .r0"
  !insertmacro WordFind
        
        
  !ifndef FindProcess
      ${Unless} $0 = 0
  !define FindProcess        '!insertmacro FindProcess'
          # get first hMod
          System::Call "*$R0(i .r0)"
         
          # get BaseName; params: Pid, hMod, szBuffer, sizeof(szBuffer)
          System::Call "Psapi::GetModuleBaseName(i r3, i r0, t .r2, i 256)i .r0"
      ${EndUnless}
        
        
  !macro FindProcess ProcessList BoolReturn
       System::Free $R0
      Push ${ProcessList}
       System::Call "kernel32::CloseHandle(i r3)"
       Call FindProcess
  ${EndUnless}
      Pop ${BoolReturn}
 
  !macroend
  Pop $R0                    ; restore registers
   
  Pop $3
  Function FindProcess
  Pop $1
    # return True if any process in ProcessList is active
  Pop $0
    Exch $0    ; get ProcessList, save $0
  Exch $2                    ; save process name
    Push $1
FunctionEnd
    Push $2
!endif</highlight-nsis>
    Push $R0
 
    Push $R1
[[Category:Process Functions]]
    Push $R2
   
    StrCpy $2 "$0,"                ; $2 = ProcessList
   
    Push 0                          ; set return value = False
   
    # method based upon one by Phoenix1701@gmail.com  1/27/07
   
    System::Alloc 1024
    Pop $R0                        ; process list buffer
   
    # get an array of all process ids
    System::Call "Psapi::EnumProcesses(i R0, i 1024, *i .R1)i .r0"
    ${Unless} $0 = 0
   
        IntOp $R1 $R1 / 4          ; Divide by sizeof(DWORD) to get $R1 process count
        IntOp $R1 $R1 - 1          ; decr for 0 base loop
       
        ClearErrors
        ${For} $R2 0 $R1
            # get a PID from the array
            IntOp $0 $R2 << 2
            IntOp $0 $0 + $R0          ; buffer.dword[i]
            System::Call "*$0(i .r0)"  ; Get next PID
           
            ${Unless} $0 = 0
                Push $0
                Call GetProcessName
                Pop $1
               
                # is this process one we are looking for?
                ${WordFind} '$2' ',' 'E/$1' $0
                ${Unless} ${Errors}
                    # yes, change return value
                    Pop $0          ; discard old result
                    Push 1          ; set return True
                   
                    # exit the loop
                    ${Break}
                ${EndUnless}
            ${EndUnless}
        ${Next}
       
    ${EndUnless}
   
    System::Free $R0
   
    Pop $0              ; get return value
    Pop $R2            ; restore registers
    Pop $R1
    Pop $R0
    Pop $2
    Pop $1
    Exch $0
  FunctionEnd
   
  Function GetProcessName
    # ( Pid -- ProcessName )
    Exch $2                    ; get Pid, save $2
    Push $0
    Push $1
    Push $3
    Push $R0
   
    System::Call "Kernel32::OpenProcess(i 1040, i 0, i r2)i .r3"
   
    StrCpy $2 "<unknown>"       ; set return value
   
    ${Unless} $3 = 0            ; $3 is hProcess
        # get hMod array
        System::Alloc 1024
        Pop $R0
       
        # params: Pid, &hMod, sizeof(hMod), &cb
        System::Call "Psapi::EnumProcessModules(i r3, i R0, i 1024, *i .r1)i .r0"
       
        ${Unless} $0 = 0
            # get first hMod
            System::Call "*$R0(i .r0)"
           
            # get BaseName; params: Pid, hMod, szBuffer, sizeof(szBuffer)
            System::Call "Psapi::GetModuleBaseName(i r3, i r0, t .r2, i 256)i .r0"
        ${EndUnless}
       
        System::Free $R0
        System::Call "kernel32::CloseHandle(i r3)"
    ${EndUnless}
   
    Pop $R0                    ; restore registers
    Pop $3
    Pop $1
    Pop $0
    Exch $2                    ; save process name
  FunctionEnd
  !endif

Latest revision as of 13:35, 1 December 2009

Author: demiller9 (talk, contrib)


This function was written with inspiration of Get a list of running processes, which pops up a message box for each running process. This function returns a boolean (0/1) if any of the processes in the input parameter are running.

Save this script as FindProcess.nsh and include it in your script. Call it like this:

!include FindProcess.nsh
 
${FindProcess} "Calc.exe,Firefox.exe" $0
${If} $0 <> 0
  MessageBox MB_OK "Found at least one process"
${Else}
  MessageBox MB_OK "Neither process found"
${EndIf}

or in a loop like this:

${Do}
  ${FindProcess} "Notepad.exe" $0
  Sleep 500
${LoopWhile} $0 <> 0

FindProcess.nsh

/*  FindProcess.nsh
*   
*   written by Donald Miller
*   Mar 7, 2007
*   
*/
 
!include LogicLib.nsh
!include WordFunc.nsh
!insertmacro WordFind
 
!ifndef FindProcess
!define FindProcess         '!insertmacro FindProcess'
 
!macro FindProcess ProcessList BoolReturn
    Push '${ProcessList}'
    Call FindProcess
    Pop ${BoolReturn}
!macroend
 
Function FindProcess
  # return True if any process in ProcessList is active
  Exch $0     ; get ProcessList, save $0
  Push $1
  Push $2
  Push $R0
  Push $R1
  Push $R2
 
  StrCpy $2 "$0,"                 ; $2 = ProcessList
 
  Push 0                          ; set return value = False
 
  # method based upon one by Phoenix1701@gmail.com  1/27/07
 
  System::Alloc 1024
  Pop $R0                         ; process list buffer
 
  # get an array of all process ids
  System::Call "Psapi::EnumProcesses(i R0, i 1024, *i .R1)i .r0"
  ${Unless} $0 = 0
 
      IntOp $R1 $R1 / 4           ; Divide by sizeof(DWORD) to get $R1 process count
      IntOp $R1 $R1 - 1           ; decr for 0 base loop
 
      ClearErrors
      ${For} $R2 0 $R1
          # get a PID from the array
          IntOp $0 $R2 << 2
          IntOp $0 $0 + $R0           ; buffer.dword[i]
          System::Call "*$0(i .r0)"   ; Get next PID
 
          ${Unless} $0 = 0
              Push $0
              Call GetProcessName
              Pop $1
 
              # is this process one we are looking for?
              ${WordFind} '$2' ',' 'E/$1' $0
              ${Unless} ${Errors}
                  # yes, change return value
                  Pop $0          ; discard old result
                  Push 1          ; set return True
 
                  # exit the loop
                  ${Break}
              ${EndUnless}
          ${EndUnless}
      ${Next}
 
  ${EndUnless}
 
  System::Free $R0
 
  Pop $0              ; get return value
  Pop $R2             ; restore registers
  Pop $R1
  Pop $R0
  Pop $2
  Pop $1
  Exch $0
FunctionEnd
 
Function GetProcessName
  # ( Pid -- ProcessName )
  Exch $2                     ; get Pid, save $2
  Push $0
  Push $1
  Push $3
  Push $R0
 
  System::Call "Kernel32::OpenProcess(i 1040, i 0, i r2)i .r3"
 
  StrCpy $2 "<unknown>"       ; set return value
 
  ${Unless} $3 = 0            ; $3 is hProcess
      # get hMod array
      System::Alloc 1024
      Pop $R0
 
      # params: Pid, &hMod, sizeof(hMod), &cb
      System::Call "Psapi::EnumProcessModules(i r3, i R0, i 1024, *i .r1)i .r0"
 
      ${Unless} $0 = 0
          # get first hMod
          System::Call "*$R0(i .r0)"
 
          # get BaseName; params: Pid, hMod, szBuffer, sizeof(szBuffer)
          System::Call "Psapi::GetModuleBaseName(i r3, i r0, t .r2, i 256)i .r0"
      ${EndUnless}
 
      System::Free $R0
      System::Call "kernel32::CloseHandle(i r3)"
  ${EndUnless}
 
  Pop $R0                     ; restore registers
  Pop $3
  Pop $1
  Pop $0
  Exch $2                     ; save process name
FunctionEnd
!endif