Announcement

Collapse
No announcement yet.

Paul's test if an app is running

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

  • Paul's test if an app is running

    Paul
    Had a very similar problem, a program in a terminal services environment that needed to be a single instance (ie only one user running it), was going to use a named mutex but MSDN recommended a very simple trick. Open a dummy locked file in general disk space (not a user area) as soon as the program starts and don’t close it till the program ends. If you get an error while opening then another instance exists.
    John

  • #2
    I don't like the idea of keeping a file open just to signal that your program is running ... it requires that the program gracefully shuts down so that it can close the handle to and delete that file. But ... what if the app crashes or is prematurely terminated or theres a power blackout and the program doesn't get that chance?

    To check if a program is running i normally just check the running process list ...

    Code:
    #COMPILE EXE
    #INCLUDE "tlhelp32.inc"
    
    FUNCTION IsProcessRunning(sExe AS STRING) 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$(sExe) = LCASE$(Proc.szExefile) THEN
             FUNCTION = 1: EXIT
         END IF
         p = Process32Next (hSnap, Proc)
     WEND
     CloseHandle hSnap
    END FUNCTION
    
    FUNCTION PBMAIN()
    IF IsProcessRunning("calc.exe") = 1 THEN
        STDOUT "Yes, process is running"
    ELSE
        STDOUT "No, process isn't running"
    END IF
    WAITKEY$
    END FUNCTION
    btw, Paul you're using EnumWindows with a callback function to check for the existance of a window, but seeing as you're just looking for one window you can just call FindWindow or FindWindowEx
    Last edited by Wayne Diamond; 6 Jul 2008, 01:11 PM.
    -

    Comment


    • #3
      Hi guys,

      thanks for posting

      Wayne thanks for reminding me about the findwindow.

      John, i have used that technique before, but i mainly needed something for batch files and that method maybe a little more harder to implement.

      in a batch job you could also create a file used as a flag, much the same way as John's suggested and have the batch job or any program to see if that file exist or not to determine what logic the batch job should flow.
      the problem with using a file in this manner is if something goes wrong and the job never completes and the file never gets deleted.

      If you have a list of many process that must take place and you can put those processes into a compiled program, John's suggestion would be great.
      You could even put the steps(programs to be run) in a file to be called by the main program and in many different patterns of scenarios that would be perfect. the file used for a flag could be on a server for other clients to use or not a server for just the client workstation to use.

      i do not believe one way will serve best for all situations, but you can count on one thing for sure.
      There is not like having alternatives to know about and use. there are many good things to say about different approaches. Just a few days ago, a end of the month backup failed, why, ran out of disk space on back up device. i was glad we had a file being used as a flag, because until the problem was solved, and i deleted the file used as a flag, no other action could take place.


      i do not think the findwindow function would work for me, because i am using it in a batch file and the name of the application being placed on a command tail could easily be typed wrong(spaces and case of letters).
      in my program, the searched for application and applications running gets converted into either upper or lower case(it does not matter) and removes the multiple spaces down to a single space to match on. so it gives a little tolerance for typing. the program also does not have to worry about the use of files for flags.

      i had a situation where somebody double clicked a desktop icon to run a program on a backup workstation computer. the program was a batch job to backup the server(we have our computer set to use a single click, i personally hate double clicking and most people have a problem hitting the mouse twice standing up over computer leaning over to operated the mouse anyways and then you could navigate to the desired desktop icon then press the return key to start the program to, forget teaching that one to people as they will not use it) ... and there was a double click to start the batch job and naturally it failed or got hung in some way because it was being run twice.

      there maybe a time critical moment when using this method i just wrote about, will fail because of the timing is so near when the batch job is started with two instances.

      that kind of gives me an idea.
      maybe John's idea can be incorporated along with the testing of an application and also a naming of the window name all rolled into one program. a bit much, but it might keep another batch job from quickly starting up.
      picture this
      inside one program
      program creates a file to use as a flag and has it in locked mode.
      if the program cannot lock the file, meaning something else has the file open, then exits with a ERRLEVEL probably being that of 1 for failure.
      program then searches for application(same batch file) running.
      program does not find application and names the window or program does find application running then exits with a proper ERRLEVEL, probably being that of 1 for failure.
      when the batch program does not see another batch program with the same name, naturally it names windows caption then exits the program with a proper ERRLEVEL, probably being that of 0 for success.

      i believe it was MCM that suggested to me sometime ago a way of creating a file while a program was running and the file would be erased automatically upon the completion of the program and that is how i would create the file mentioned being used as a flag.

      it anybody feels they can improve or create an alternative way, i would be interested in your code in the source code section.
      p purvis

      Comment


      • #4
        way of creating a file while a program was running and the file would be erased automatically upon the completion of the program
        There is a difference between a "file exists" test and a "file is in use" test; either could be used to determine if a program is running.

        If "file exists" test is used, then you have to allow for deleting that file should the program terminate abnormally; if "file is in use" test is used, that test is not necessary since Windows will close all handles when the process is completely terminated and the file won't be in use anymore.
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          i wrote another program that has combined functions of two programs isitrung and consname, then added one more feature using a file as a flag to reduce the probability of a second instance of running a batch file.
          the program will return a ERRLEVEL 1 if the program feels another instance is running then
          most people put batch files in a directory named \bat on the msdos machines, i do the same these days except i have batch files in a windows system named \wsbat that contains all my batch files and the directory is set to read write.

          please see the program
          i just altered the first program
          Last edited by Paul Purvis; 6 Jul 2008, 08:36 PM.
          p purvis

          Comment


          • #6
            Originally posted by Wayne Diamond View Post
            I don't like the idea of keeping a file open just to signal that your program is running ... it requires that the program gracefully shuts down so that it can close the handle to and delete that file. But ... what if the app crashes or is prematurely terminated or theres a power blackout and the program doesn't get that chance?
            Wayne the keyword was LOCKED, purportedly no matter how a program ends in NT that lock will be released. The method was a direct recommendation from the Microsoft MSDN Windows API. Went looking and couldn't find it but in the .NET documentation it recommends using a MONITOR instead of a Named Mutex (which I thought would be best). 2000 introduced a whole range of fenced atomic operations such as adding two numbers and Vista has introduced Slim Reader/Writer, all of which seem aimed at reducing the use of Mutexes and Critical sections but the only statement of a weakness in them that I have found is "When multiple threads are reading and writing using a shared resource, exclusive locks such as a critical section or mutex can become a bottleneck".
            Would appreciate if anyone knows of problems.
            John

            Comment


            • #7
              i yanked the cord on my laptop with the battery out while the program ISITRNIT(i had to compile a special version of INISRNIT with a waitkey$ statement in it to do this test) was running and the temporary file was still there on the next boot up that i was hoping would have been deleted on a power failure, wishful thinking hoping the file was not there and it had somehow been deleted upon a computer crash.

              it is best to try to delete any temporary files the INITRNIT program might have created when the computer boots up and that is why i suggested to run the program in a directory where these files can be deleted at will or you can place a specificially try to erase the file prior to INITRNIT running.

              one good news is that while the program INITRNIT is running, the file it uses as a flag, is locked and cannot be deleted while INITRNIT has the file open.
              this will give some assurance if the directory happens to be a shared directory on a file server and/or while a second batch file tries to run the same bit of code.

              just to repeat, if the INITRNIT is interrupted by some event there could be a possibility that the temporary file is left in a directory and needs to be deleted before the next time INITRNIT tries to run from the same batch file or else the batch file will fail when it should succeed.

              maybe i should just have the INITRNIT try to delete the file temporary file in the beginning of the program and that would solve any problems.
              why didn't i think of that earlier.
              Last edited by Paul Purvis; 8 Jul 2008, 10:57 AM.
              p purvis

              Comment


              • #8
                Create and use a file which will be deleted on close:

                http://www.powerbasic.com/support/pb...3&postcount=13
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  although that code is much more in length than
                  hFile = CreateFile(stempfilename,0,0,BYVAL 0&,%CREATE_NEW,%FILE_FLAG_DELETE_ON_CLOSE,BYVAL 0&)

                  stempfilename is an asciiz string

                  ISITRNIT uses the createfile with the DELETE ON CLOSE e flag.
                  if your system crashes, the file opened with the DELETE ON CLOSE flag has a good chance to existing still, thereby maybe causing a conflict in the future or just leaving behind a file that will be use again, taking up space, directory room, and making backups of unnecessary files.
                  that is why i placed a KILL file statement just before the createfile statement that uses the DELETE ON CLOSE flag.

                  KILL stempfilename
                  hFile = CreateFile(stempfilename,0,0,BYVAL 0&,%CREATE_NEW,%FILE_FLAG_DELETE_ON_CLOSE,BYVAL 0&)
                  Last edited by Paul Purvis; 8 Jul 2008, 11:48 AM.
                  p purvis

                  Comment


                  • #10
                    I saw you had done that (KILL first).

                    I posted the reference link because in some applications (not yours), people may want to actually USE such a file while it does exist... e.g. to store a user count or a user list; and for many it's a lot easier to handle that using the familar PB file verbs isntead of the WinAPI ReadFile/WriteFile etc.

                    Not that I endorse the concept of keeping a file open throughout a GUI program's life, but in a batch application it's not all bad.

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

                    Comment


                    • #11
                      MCM

                      i am sure you know that i was not being negative toward your post, i welcomed it.

                      i was trying to focus any readers toward the createfile statement line.

                      also notice, i used the CREATE_NEW flag which may not and probably not be very friendly for many coding purposes.
                      readers should research the use of the CREATEFILE statement and become acquainted with its use and function.

                      and yes Michael, in the INITRNIT program, i was trying to bring all the tricks i had (including any file flag usage)to stop another instance from running.
                      because of how i am using the file as flag, there should not be time for some other program to get its foot in the door, so to say, and we can depend on only one program searching at a time for an instance of a program running.
                      Last edited by Paul Purvis; 8 Jul 2008, 12:11 PM.
                      p purvis

                      Comment


                      • #12
                        If you want to be 100% sure that a file will be deleted, use MoveFileEx/MOVEFILE_DELAY_UNTIL_REBOOT with the file before opening it with CreateFile/FILE_FLAG_DELETE_ON_CLOSE, then if the file is somehow not deleted on close, it will always get deleted on boot.
                        kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                        Comment


                        • #13
                          Thanks Kev,
                          and also remembering MOVEFILEEX function only works on a non shared drive.

                          as a reminder to others, most of this topic has been about keeping only one instance of a program running on a local computer and not on keeping multiple instances of running a program from different workstations.


                          in keeping multiple computers from running a program more than one instance at a time on a shared drive.
                          i would believe the only way you can do that would be to open and lock a file to be used as a flag or create a file used as a flag with the latter being the easiest to implement. i have heard of a file being kept open on a server when the workstation locks up or crashes, but that might of mostly been in the msdos days with msdos servers. so there can be problems when a workstation some how does not complete it's job, because of many unforeseeable reasons, of not releasing the lock on a file or not deleting a file used as a flag so that other workstations can start and instance of a program.
                          Last edited by Paul Purvis; 9 Jul 2008, 02:58 PM.
                          p purvis

                          Comment


                          • #14
                            > ... keeping multiple instances of running a program from different workstations.

                            That's why the 'server edition' of everything costs more than does the "workstation" version. Even though the PB compilers and the Windows operating system provide some nice tools , there's a lot more to it than simply mapping a couple of SHARES, especially when "number of seats" is to be monitored and controlled.

                            You may also recall the "multi-user" version of MS-DOS programs always cost more than did the "single-user"... while not Client-Server (today's preferred architecture), there's a lot more to it than simply changing the file opens to SHARED.

                            As in...
                            "Fundamentals Of Multi-User Programming." Article published in December 1995 issue of "BASICally Speaking" magazine discussing the principles of writing multi-user programs; code samples in BASIC. Rich Text format; placed in the Public Domain June 2005
                            http://www.talsystems.com/tsihome_ht...rogramming.rtf


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

                            Comment


                            • #15
                              One trick an open file can do

                              If you put the Windows User Name into the file it can also prove to be a useful tool showing who is running the program not just that it is running. If you allow multiple copies on a "server" via share or even a terminal server you can get a list of active users.

                              If you use this method you should always try to delete the file before opening it and that will ensure orphaned files are removed.

                              Code:
                                  OPEN gDBPath + "~" + gSecurityMach + ".opn" FOR OUTPUT AS #stat
                                  IF ERR THEN
                                      'This occurs if this machine already has a copy running
                                  ELSE
                                      PRINT #stat, gSecurityUser
                                      CLOSE #stat
                                      OPEN gDBPath + "~" + gSecurityMach + ".opn" FOR INPUT ACCESS READ LOCK SHARED AS #stat
                                  END IF
                                  ERRCLEAR
                              The file name can be for a machine (which will allow multiple copies but only one per machine) or unique to the program (only one copy total). Watch out on a terminal server. You have to detect that it is a terminal server and add something like the process ID to make it unique (if that is what you need).

                              You may want to "fancy this up some" to detect a specific error (70 and others) if the file is already open by another process.

                              Just one more opinion.
                              Mark Strickland, CISSP, CEH
                              SimplyBASICsecurity.com

                              Comment

                              Working...
                              X