Announcement

Collapse
No announcement yet.

Check whether Application is running.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Check whether Application is running.

    Hello Experts


    I would like to know whether one application(Exe) is running or not from another powerbasic program.

    Can any one help with this,any form of work is appreciated.




    Regards

    Govindaraj Saminathan.

  • #2
    There are many methods you can choose from, each with their own pros and cons... the most common are ...

    1. Check the list of running processes

    2. Check the list of running applications

    3. Use FindWindow/FindWindowEx to check if the programs main window exists

    4. Use a mutex

    -

    FindWindow is the easiest... this simple demo detects if the Calculator program (\windows\system32\calc.exe) is running:
    Code:
    #COMPILE EXE
    #INCLUDE "win32api.inc"
     
    FUNCTION PBMAIN () AS LONG
    DIM hWnd AS DWORD
    hWnd = FindWindow(BYVAL 0, "Calculator")
    IF hWnd <> 0 THEN ? "Program is running" ELSE ? "Program is not running"
    END FUNCTION
    This version enumerates the running process list to check that calc.exe exists:
    Code:
    #COMPILE EXE
    #INCLUDE "tlhelp32.inc"
    
    FUNCTION ProcExists(szExeName AS ASCIIZ) AS LONG
     LOCAL hSnap AS LONG, p AS LONG, Proc AS PROCESSENTRY32
     hSnap = CreateToolhelp32Snapshot (%TH32CS_SNAPPROCESS, 0&)
     IF hSnap = 0 THEN EXIT FUNCTION
     Proc.dwSize = SIZEOF(Proc)
     p = Process32First (hSnap, Proc)
     WHILE p
         IF LCASE$(Proc.szExefile) = LCASE$(szExeName) THEN
             FUNCTION = 1
             CloseHandle hSnap
             EXIT FUNCTION
         END IF
         p = Process32Next (hSnap, Proc)
     WEND
     CloseHandle hSnap
    END FUNCTION
     
    FUNCTION PBMAIN() AS LONG
     IF ProcExists("calc.exe") = 1 THEN ? "Calc is running" ELSE ? "Calc not running"
    END FUNCTION
    Last edited by Wayne Diamond; 19 Sep 2014, 05:33 AM.
    -

    Comment


    • #3
      Finding exe is running

      hi wayne


      Thanks a lot this is what am looking for.Actually i tried using findwindow since i have applied it in a wrong way because of my ignorance am unable to narrow down to it

      But you catched and left on right track



      Regards

      Govindaraj Saminathan

      Comment


      • #4
        >This version enumerates the running process list to check that calc.exe exists:

        On NT4/Windows2000/XP+ you can use EnumProcesses(). That can get you to the name of the primary executable module.

        But if this is a cooperating application nothing beats using a named memory object such as a mutex.

        Note that none of these techniques work across computers.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Michael yes, EnumProcesses like you mention is actually preferable on NT-based systems as its a lot easier to get at the full path instead of just the filename, but I used the toolhelp32 method to keep things simple for this demo as it's also Win9x-compatible
          -

          Comment


          • #6
            So to add to this discussion, is there any way to nuke another application that's running? In other words, after checking from within program1 if program2 is running, can program2 be closed by program1?

            Comment


            • #7
              Owen, of course ...

              In regards to the FindWindow method of detection, sometimes you can terminate it simply by sending a WM_CLOSE message to it, although that's very unreliable - give that route a miss

              There are literally dozens of ways to kill processes, but the usual (and effectively guaranteed, unless it has custom kernel-level protection) approach to forcefully terminate a process is simply 1) get the target process ID, 2) call OpenProcess with appropriate rights (ie %PROCESS_TERMINATE) to obtain a handle, then 3) call TerminateProcess
              Code:
              SUB KillProcess (BYVAL dwProcessID AS DWORD)
               LOCAL hProc AS LONG
               hProc = OpenProcess(BYVAL %PROCESS_TERMINATE, BYVAL 0, BYVAL dwProcessID)
               IF hProc <> %NULL THEN TerminateProcess BYVAL hProc, BYVAL %NULL
               CloseHandle hProc
              END SUB
              It never hurts trying to obtain SeDebugPrivilege beforehand, either!
              Last edited by Wayne Diamond; 20 Sep 2014, 08:39 PM.
              -

              Comment


              • #8
                So to add to this discussion, is there any way to nuke another application that's running?
                Safely?

                With a cooperating application, yes. You signal that application to end, using any one of multiple techniques: Sending a message or signalling an event come to mind. The cooperating application then shuts itself down in an orderly fashion.

                With a non-cooperating application? Well, you can try the TerminateProcess() technique demonstrated by Mr. Diamond. If you can obtain a handle with PROCESS_TERMINATE permission (and you likely will), that will, I think, literally "nuke" the process. However, none of the "end of program" logic in that application will be executed and that application may leave undone that which needs doing to maintain the integrity of the application data.

                MCM
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Hi
                  I combined the above to identify and terminate a running process:

                  Code:
                  SUB Terminate_Program(a$)
                  
                      DIM program AS ASCIIZ * (len(a$) + 1): program = a$
                      LOCAL Proc AS PROCESSENTRY32: DIM Process_ID AS DWORD
                  
                      hSnap = CreateToolhelp32Snapshot(%TH32CS_SNAPPROCESS, 0&)
                      IF hSnap = 0 THEN EXIT SUB
                  
                      Proc.dwSize = SIZEOF(Proc)
                      p = Process32First(hSnap, Proc)
                  
                      WHILE p
                          IF LCASE$(Proc.szExefile) = LCASE$(program) THEN
                              CloseHandle hSnap: Process_ID = Proc.th32ProcessID
                              GOTO 10
                          END IF
                  
                          p = Process32Next (hSnap, Proc)
                      WEND
                      CloseHandle hSnap
                      EXIT SUB
                  
                  10  REM Terminate process?
                      hProc = OpenProcess(BYVAL %PROCESS_TERMINATE, BYVAL 0, BYVAL Process_ID)
                  MSGBOX STR$(Process_ID) + STR$(hProc)
                      IF hProc <> %NULL THEN TerminateProcess BYVAL Process_ID, BYVAL %NULL
                      CloseHandle hProc
                  END SUB
                  The Process ID number retrieved is correct and a handle number is returned from OpenProcess, but alas the TerminateProcess function fails to close the process. I guess that the calling program may not have rights for terminating the target program. Any ideas?

                  Thank in advance

                  Comment


                  • #10
                    Originally posted by Peter Simmonds View Post
                    I guess that the calling program may not have rights for terminating the target program. Any ideas?
                    try SeDebugPrivilege http://forum.powerbasic.com/forum/us...lavors?t=55239
                    -

                    Comment


                    • #11
                      |hi

                      T|hanks, I saw your comment anout that, but I'm really not all certain how to run that and whether it would have other effects on the calling program. Any help appreciated.

                      Comment


                      • #12
                        Originally posted by Peter Simmonds View Post
                        T|hanks, I saw your comment anout that, but I'm really not all certain how to run that
                        Code:
                        %SE_DEBUG_PRIVILEGE = 20
                        IF RtlAdjustPrivilege (BYVAL %SE_DEBUG_PRIVILEGE, BYVAL 1, BYVAL 0, bIncBufSize) = 0 THEN Msgbox "Success"
                        I can't really make it any simpler
                        and whether it would have other effects on the calling program. Any help appreciated.
                        it simply elevates the privilege level of your process, have a read of the MSDN page
                        -

                        Comment


                        • #13
                          This might also be of interest, there is a C example at the end...

                          MSDN: How To Terminate an Application "Cleanly" in Win32

                          Pierre

                          Comment


                          • #14
                            yus, but that code will still fail on some conditions where SeDebugPrivilege will be required as it seems is Peter's case, and as i've often encountered. btw Peter it goes without saying but always worth repeating - when it comes to privileges you should save the existing privilege level and revert back afterwards when done, as you dont want to retain a higher privilege level than needed or you can open your process up as an attack vector. Also, another of my demos in that thread is disabling SeDebugPrivilege.
                            -

                            Comment


                            • #15
                              Gday Guru Wayne,

                              How do we detect a debugger process and then terminate it or stop part of its process ?
                              As you see the codes that you presented above relies on a name of the program called "calc.exe"

                              How do we determine that a program is a debugger ? What are the characteristics of a typical debugging program
                              that we need to check and / or to guess that a particular process is a debugger, and subsequently terminate this process.

                              Thank you for your advice.

                              Comment


                              • #16
                                Wayne, sorry to be a bit dense, but I still cannot see how to use this. If I modify the program to this, it won't compile:

                                Code:
                                #iINCLUDE Win32API.INC
                                #INCLUDE "tlhelp32.inc"
                                
                                DEFLNG a-z
                                
                                %SE_DEBUG_PRIVILEGE = 20
                                DECLARE FUNCTION RtlAdjustPrivilege (BYVAL lPrivilege AS LONG, BYVAL bEnable AS LONG, BYVAL bCurrentThread  AS LONG, AlreadyEnabled AS LONG) AS LONG
                                
                                #COMPILE EXE
                                
                                FUNCTION PBMAIN () AS LONG
                                    a$ = "Calculator.EXE": CALL Terminate_Program(a$)
                                END FUNCTION
                                
                                SUB Terminate_Program(a$)
                                
                                    DIM program AS ASCIIZ * (LEN(a$) + 1): program = a$
                                
                                    DIM program AS ASCIIZ * 30: program = "Calculator.EXE"
                                    LOCAL Proc AS PROCESSENTRY32: DIM Process_ID AS DWORD
                                
                                    hSnap = CreateToolhelp32Snapshot(%TH32CS_SNAPPROCESS, 0&)
                                    IF hSnap = 0 THEN EXIT SUB
                                
                                    Proc.dwSize = SIZEOF(Proc)
                                    p = Process32First(hSnap, Proc)
                                
                                    WHILE p
                                        IF LCASE$(Proc.szExefile) = LCASE$(program) THEN
                                            CloseHandle hSnap: Process_ID = Proc.th32ProcessID
                                            GOTO 10
                                        END IF
                                
                                        p = Process32Next (hSnap, Proc)
                                    WEND
                                    CloseHandle hSnap
                                MSGBOX "Process not found"
                                    EXIT SUB
                                
                                10  REM Terminate process?
                                    hProc = OpenProcess(BYVAL %PROCESS_TERMINATE, BYVAL 0, BYVAL Process_ID)
                                MSGBOX STR$(Process_ID) + STR$(hProc)
                                
                                    IF RtlAdjustPrivilege(BYVAL %SE_DEBUG_PRIVILEGE, BYVAL 1, BYVAL 0, bIncBufSize) = 0 THEN MSGBOX "Success"
                                
                                    IF hProc <> %NULL THEN TerminateProcess BYVAL Process_ID, BYVAL %NULL
                                    CloseHandle hProc
                                END SUB
                                This reports "Undefined Function" for RtlAdjustPrivilege. Howvwr, I can't see it defined in any of the functions/Subs on that webpage Wayne mentioned. Where is it?

                                Comment


                                • #17
                                  Originally posted by paul yuen View Post
                                  Gday Wayne,
                                  How do we detect a debugger process and then terminate it or stop part of its process ?
                                  As you see the codes that you presented above relies on a name of the program called "calc.exe"
                                  Terminating a debugger is no different to terminating any other process (although of course if there's a debuggee process it's also terminated). In regards to detecting a debugger, just use poffs to search the Source Code forum for subjects with "debug", then sort by author and look at my ones (or here's the forum search you might find interesting). That's a separate question though - just to clarify, in regards to Peter's question there's no need to do any debugger detection or anything debug-related, SeDebugPrivilege just happens to be the name of the privilege as it's typically only debuggers that use it (but not always, and it's not rule of law).

                                  Originally posted by Peter Simmonds View Post
                                  Wayne, sorry to be a bit dense, but I still cannot see how to use this. If I modify the program to this, it won't compile:
                                  This reports "Undefined Function" for RtlAdjustPrivilege. Howvwr, I can't see it defined in any of the functions/Subs on that webpage Wayne mentioned. Where is it?
                                  to use an API function it must be declared; RtlAdjustPrivilege isn't in win32api.inc as it's from ntdll, which i don't think has any that made it into win32api.inc (an ntdll.inc would be great!). If you ever find yourself in this situation again simply search the forum for "DECLARE FUNCTION <name>":
                                  Code:
                                  DECLARE FUNCTION RtlAdjustPrivilege LIB "ntdll.dll" ALIAS "RtlAdjustPrivilege" (BYVAL lPrivilege AS LONG, BYVAL bEnable AS LONG, BYVAL bCurrentThread AS LONG, AlreadyEnabled AS LONG) AS LONG
                                  but yes i should've included it with the call demo, apologies
                                  Last edited by Wayne Diamond; 19 Feb 2016, 08:03 PM.
                                  -

                                  Comment


                                  • #18
                                    I guess it could look a little like this...

                                    Pierre
                                    Code:
                                    #COMPILE EXE '#Win 8.04#
                                    #DIM ALL
                                    #INCLUDE "Win32Api.inc"
                                    #INCLUDE "TlHelp32.inc"
                                     
                                    $AppName = "TerminateProcess"
                                     
                                    %SE_DEBUG_PRIVILEGE = 20
                                     
                                    DECLARE FUNCTION RtlAdjustPrivilege LIB "NtDll.dll" ALIAS "RtlAdjustPrivilege" _
                                    (BYVAL PrivilegeIndex AS DWORD, BYVAL EnableIfTrueElseDisable AS LONG, _
                                     BYVAL ThreadIfTrueElseProcess AS DWORD, BYREF WasAlreadyEnableIfTrue AS LONG) AS LONG
                                    '_____________________________________________________________________________
                                     
                                    FUNCTION TerminateProc(zFileName AS ASCIIZ) AS LONG
                                     LOCAL ProcEntry AS PROCESSENTRY32
                                     LOCAL hSnapshot AS DWORD
                                     LOCAL hProc     AS DWORD
                                     
                                     hSnapshot        = CreateToolhelp32Snapshot(%TH32CS_SNAPPROCESS, %NULL)
                                     ProcEntry.dwSize = SIZEOF(PROCESSENTRY32)
                                     IF Process32First(hSnapshot, ProcEntry) THEN
                                       DO
                                         IF LCASE$(ProcEntry.szExefile) = LCASE$(zFileName) THEN
                                           hProc = OpenProcess(%PROCESS_TERMINATE, %FALSE, ProcEntry.th32ProcessID)
                                           IF hProc THEN
                                             IF MessageBox(%HWND_DESKTOP, ProcEntry.szExefile & " pid is 0x" & HEX$(ProcEntry.th32ProcessID) & _
                                                           " ("& FORMAT$(ProcEntry.th32ProcessID) & "), " & $CRLF & _
                                                           "process handle is 0x" & HEX$(hProc) & " ("& FORMAT$(hProc) & ")" & $CRLF & "Terminate it ?", _
                                                           $AppName, %MB_YESNO OR %MB_TOPMOST) = %IDYES THEN
                                               'TerminateProcess unconditionally force a process to exit, use with caution.
                                               IF TerminateProcess(hProc, BYVAL %NULL) THEN
                                                 FUNCTION = %TRUE 'Success
                                               ELSE
                                                 CloseHandle(hProc) 'Not terminated, do clean up
                                               END IF
                                             END IF
                                           END IF
                                           EXIT DO
                                         END IF
                                       LOOP WHILE Process32Next(hSnapshot, ProcEntry)
                                     END IF
                                     CloseHandle(hSnapshot)
                                     
                                    END FUNCTION
                                    '_____________________________________________________________________________
                                     
                                    FUNCTION PBMAIN() AS LONG
                                     LOCAL zFileName               AS ASCIIZ * %MAX_PATH
                                     LOCAL PrivilegeIndex          AS DWORD
                                     LOCAL ThreadIfTrueElseProcess AS DWORD
                                     LOCAL EnableIfTrueElseDisable AS LONG
                                     LOCAL WasAlreadyEnableIfTrue  AS LONG
                                     LOCAL ProcessId               AS LONG
                                     
                                     zFileName = "NotePad.exe" 'The editor
                                     ProcessId = SHELL(zFileName) 'Start the exe
                                     
                                     IF MessageBox(%HWND_DESKTOP, "Try without RtlAdjustPrivilege ?", $AppName, %MB_YESNO OR %MB_TOPMOST) = %IDYES THEN
                                       TerminateProc(zFileName) 'Terminate exe
                                     ELSE
                                       PrivilegeIndex          = %SE_DEBUG_PRIVILEGE
                                       EnableIfTrueElseDisable = %TRUE
                                       ThreadIfTrueElseProcess = %FALSE
                                       IF RtlAdjustPrivilege(PrivilegeIndex, EnableIfTrueElseDisable, _
                                                             ThreadIfTrueElseProcess, WasAlreadyEnableIfTrue) = 0 THEN 'Privilege granted
                                         TerminateProc(zFileName) 'Terminate exe
                                         EnableIfTrueElseDisable = %FALSE 'To release privilege
                                         RtlAdjustPrivilege(PrivilegeIndex, EnableIfTrueElseDisable, _ 'No more need for privilege
                                                            ThreadIfTrueElseProcess, WasAlreadyEnableIfTrue)
                                       ELSE
                                         MessageBox(%HWND_DESKTOP, "Run As Administrator", $AppName, %MB_OK OR %MB_TOPMOST)
                                       END IF
                                     END IF
                                     
                                    END FUNCTION
                                    '____________________________________________________________________________
                                    '
                                    Last edited by Pierre Bellisle; 18 May 2021, 09:03 PM.

                                    Comment


                                    • #19
                                      and restored privs afterwards, bewtiful
                                      -

                                      Comment


                                      • #20
                                        Pierre, Beautiful code, especially compared to my "home-brew" effort!! Thanks

                                        It does not however, seem to address the original problem at least on my computer. As suggested by your last message "Run as adminstrator", it seems that the problem is not about Priveleges, but more about whether the program is run as an Administrator or not. In fact, running either with or without priveleges can terminate "Calculator.EXE" as an administrator, but both methods fail when run normally (I'm running this under Windows 10).

                                        Comment

                                        Working...
                                        X