Announcement

Collapse
No announcement yet.

Stopping multiple executions

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

    Stopping multiple executions

    Hi all

    I was wondering how I can stop multiple executions of my program?



    ------------------
    Henning
    Henning

    #2
    Originally posted by Henning Wallgren:
    Hi all

    I was wondering how I can stop multiple executions of my program?


    Search the Forum for "App Previnstance"


    ------------------
    Sven Blumenstein
    IT-Trainee at DECOMA Exterior Systems, Germany
    E-Mail: mailto:sven.blumenstein@[NOSPAM]cycos.netsven.blumenstein@[NOSPAM]cycos.net</A>
    Programming with: PB/DLL, MASM, VB, VC++, LCC, VBA, WML

    Comment


      #3
      lasse rantanen once posted a way. see http://www.powerbasic.com/support/pb...ad.php?t=17497


      ------------------

      Comment


        #4
        I have a mutex example too on my site IN the helpfile i believe..


        ------------------
        http://www.hellobasic.com
        hellobasic

        Comment


          #5
          Thanks guys.

          ------------------
          Henning
          Henning

          Comment


            #6
            This is the code I use, which uses a Mutex:

            Code:
            DIM szTemp AS ASCIIZ*%MAX_PATH
            szTemp = "myprogram.exe"
            '
            DIM hMutex AS LONG
            '
            hMutex = CreateMutex(BYVAL %NULL, 0, szTemp)
            IF hMutex = %NULL THEN EXIT FUNCTION
            
            IF GetLastError = %ERROR_ALREADY_EXISTS THEN EXIT FUNCTION
            I believe Semen posted the original code.

            Hope this helps!

            Regards,


            ------------------
            Clay C. Clear

            Clay Clear's Software
            mailto:[email protected][email protected]</A>

            [This message has been edited by Clay Clear (edited September 26, 2001).]

            Comment


              #7
              Thanks Clay,

              That was the easiest of all codes to implement.

              I found a well of ways of doing it here and in POFFS (once I knew
              what to look for) including a short samplecode from Semen who
              always seems to provide a right to the point sample. Thank you.




              ------------------
              Henning
              Henning

              Comment


                #8
                Henning,

                You're quite welcome.

                You should note that, if you use my sample, you should also put
                in your code, right before "EXIT FUNCTION" or "END FUNCTION"
                the following:

                CloseHandle hMutex

                Sorry for forgetting to mention that.

                Regards,


                ------------------
                Clay C. Clear

                Clay Clear's Software
                mailto:[email protected][email protected]</A>

                Comment


                  #9
                  A note of caution if you use mutexes to determine if your prog is already alive - 3rd party programs (including trojans/viruses etc) can use your mutex if your program isn't running/using it, so your program can effectively be blocked and won't be able to run. This wouldn't apply to programs such as simple tools and utilities, but certainly would apply to any security-related programs! (I recall that ZoneAlarm's components each have a fixed mutex name, big no no!)
                  So rather than using a fixed mutex name, you may want to use a secure hash (MD5/SHA)
                  Best,
                  Wayne


                  ------------------
                  -

                  Comment


                    #10
                    The good part is that it isn't required to destroy the mutex as suggested above.

                    This saves programming.


                    ------------------
                    http://www.hellobasic.com
                    hellobasic

                    Comment


                      #11
                      Wayne,

                      Do you have any examples of how to do that (what you just said is
                      unfortunately greek to me..) ?


                      ------------------
                      Henning
                      Henning

                      Comment


                        #12
                        Henning, well lets just say that youve developed a security program, and it uses a mutex to determine if it's already running. Just say its mutex name is "MyMutex" (remembering that mutexes are case sensitive ). A virus/trojan could find your security program (which could be as easy as one call to FindWindow) and then terminate it. Once it has terminated your program (which also naturally terminates all mutexes created by that process), it can then create the mutex "MyMutex". From that point on, you wouldn't be able to use your security program, because every time you tried to run it it would detect the mutex and assume that it's already running, even though it's actually the trojan/virus that is using the mutex - not another instance of your program.

                        So! I was just suggesting that if you are building a program that could be targetted by trojans/viruses such as security programs then it would be a wise idea not to use a fixed mutex name like "MyMutex". If your mutex is based on a unique checksum or mathematical algorithm then there's a very good chance that no trojan/virus author would bother going to such a length just to stop your program from running, but with plaintext fixed mutexes like "MyName" there's no effort, it's game set and match with one call to CreateMutex

                        For example, I dont know if this is still the case, but ZoneAlarm (the personal firewall) used a mutex called something like "ZAMutex"! Needless to say it didnt take long for some trojan authors to realise this.
                        Its not really something you need to worry about though if your program isn't likely to be the target of viruses/trojans, but just something to be aware of nonetheless!
                        I hope that makes a bit more sense

                        Also this applies not just to mutexes. If your security program uses (for example) FindWindow to determine if it is already running, then a trojan just has to create a window with the same title that your program looks for, pretty much the same as the mutex problem. A less efficient but more secure method would be to literally check the process list to see if your process is listed more than once

                        Best,
                        Wayne


                        [This message has been edited by Wayne Diamond (edited September 27, 2001).]
                        -

                        Comment


                          #13
                          I don't think that it's necessary to think about viruses.
                          Another question that "correct" app should activate first instance.
                          For this purpose SetProp could be much more useful.

                          Correct "activation" code is a separate thread.
                          Here I used "quick" (but not 100% correct) method, because wanted to show SetProp only.

                          Code:
                             #Compile Exe
                             #Dim All
                             #Register None
                             #Include "WIN32API.INC"
                          
                             %Sign1 = &H12345678&  ' Any unique
                             %Sign2 = &H90123456&
                          
                          
                             Function EnumWindowsProc(ByVal hWnd As Long, Param As Long Ptr) As Long
                                If GetProp (hWnd, ByVal 1) = %Sign1 Then _
                                   If GetProp (hWnd, ByVal 2) = %Sign2 Then @Param = hWnd: Exit Function
                                Function = 1
                             End Function
                          
                             CallBack Function DlgProc
                               Select Case CbMsg
                               Case %WM_INITDIALOG
                                  SetProp CbHndl, ByVal 1, ByVal %Sign1
                                  SetProp CbHndl, ByVal 2, ByVal %Sign2
                               End Select
                             End Function
                          
                             Function PbMain
                                Dim hDlg As Long, k As Long
                                EnumWindows CodePtr(EnumWindowsProc), VarPtr(k)
                                If k <> 0 Then ShowWindow k, %SW_RESTORE: SetForegroundWindow k: Exit Function ' dirty and incorrect method; simply for test
                                Dialog New  %HWND_DESKTOP, "Started at " + Time$, 240, 120, 150, 60, %WS_CAPTION Or %WS_OVERLAPPEDWINDOW To hDlg
                                Dialog Show Modal hDlg, Call DlgProc
                             End Function



                          ------------------
                          E-MAIL: [email protected]

                          Comment


                            #14
                            I don't do this (it is quite lame ) but it seems one might use a "semaphore" file to control multiple executions and check for proper shutdown of the last instance of the app which was running.
                            Code:
                            #Dim All
                            #Register None
                            #Option Version4
                             
                            Type SemaphoreType
                              AppAlreadyRunning       As Long
                              LastShutdownSuccessful  As Long
                            End Type
                             
                             
                            '  Put in Registry or cfg/ini file
                            $Hash = "0102030405060708090A0B0C0D0E0F101112131415161718191A"
                            $SemaPath = "SemaPhore\"
                             
                            Declare Function AppRunning( HashName As String ) As Long
                            Declare Function ReHash( HashHex As String ) As String
                            Declare Sub CreateDirectoryTree( ByVal NewPath As String )
                            Declare Sub DoStuff()
                            Declare Sub UpdateSemaphore( ReHashName As String )
                             
                            Global CurDrive$
                             
                            Function PbMain
                              Local lResult As Long
                              CurDrive$ = Left$(CurDir$,3)
                              'Create the Path for the SemaPhore file
                              CreateDirectoryTree CurDrive$ & $SemaPath
                             
                              lResult = AppRunning(ReHash($Hash))
                              If (lResult > 0& ) Then
                                Beep
                                Select Case lResult
                                  Case 1&
                                    StdOut "No can Do.  App Running..."
                                  Case 2&
                                    StdOut "No can Do.  Semaphore File already opened."
                                End Select
                                Exit Function
                              End If
                             
                              DoStuff
                              Call UpdateSemaphore( ReHash($Hash) )
                            End Function
                             
                             
                            Sub DoStuff
                              WaitKey$
                            End Sub
                             
                             
                            Function AppRunning( ReHashName As String ) As Long
                              Local DaError   As Long
                              Local udtSema   As SemaphoreType
                             
                              ErrClear
                              Open CurDrive$ & $SemaPath & ReHashName For Binary Access Read Write Lock Read Write As #1
                              DaError = ErrClear
                              If DaError > 0& Then
                                StdOut "Error Opening Semaphore File:" & Str$(DaError)
                                Function = 2&
                              End If
                              Get #1,, udtSema
                             
                              Select Case udtSema.AppAlreadyRunning
                                Case 0&
                                  udtSema.AppAlreadyRunning = 1&
                                  udtSema.LastShutdownSuccessful = 0&
                                  Put #1,1, udtSema
                                  Function = 0&
                             
                                Case 1&
                                  If udtSema.LastShutdownSuccessful = 0& Then
                                    Function = 1&
                                  Else
                                    Function = 0&
                                  End If
                              End Select
                              Close 1
                            End Function
                             
                             
                            Sub UpdateSemaphore( ReHashName As String )
                              Local DaError   As Long
                              Local udtSema   As SemaphoreType
                             
                              udtSema.LastShutdownSuccessful = 1&
                              udtSema.AppAlreadyRunning = 0&
                              ErrClear
                              Open CurDrive$ & $SemaPath & ReHashName For Binary Access Write Lock Read Write As #1
                              DaError = ErrClear
                              If DaError > 0& Then
                                StdOut "Error Opening Semaphore File:" & Str$(DaError) & "!  Investigate and manually update file."
                                Exit Sub
                              End If
                             
                              Put #1,, udtSema
                              Close 1
                            End Sub
                             
                             
                            Function ReHash( HashHex As String ) As String
                              '  Do something real here with hash code...
                              Rehash = "HashTest"
                            End Function
                             
                            Sub CreateDirectoryTree( ByVal NewPath As String )
                              Local s   As String
                              Local Pth As String
                              Local l   As Long
                             
                              If Right$(NewPath,1) = "\" Then
                                NewPath = Left$(NewPath, Len(NewPath) -1 )
                              End If
                             
                              l = 1
                              Do
                                s = Parse$( NewPath, "\", l )
                                If Len(s) > 0& Then
                                  Pth = Pth & s & "\"
                                  MkDir Pth
                                  Incr l
                                Else
                                  Exit Do
                                End If
                              Loop
                            End Sub
                            [This message has been edited by Ron Pierce (edited September 28, 2001).]

                            Comment


                              #15
                              Hi all

                              I've been using Clay/Semen's Mutex sample which I put into a DLL.
                              So far this has worked 100%. However, Clay, if I use the commented line
                              it does not.. With the multitude of ways suggested, can I consider
                              this a safe way?

                              FUNCTION ProgramRunning(byval program$) EXPORT AS LONG
                              FUNCTION = %FALSE
                              DIM szTemp AS ASCIIZ * %MAX_PATH
                              szTemp = program$
                              DIM hMutex AS LONG
                              hMutex = CreateMutex(BYVAL %NULL, 0, szTemp)
                              IF hMutex = %NULL THEN FUNCTION = %TRUE
                              IF GETLASTERROR = %ERROR_ALREADY_EXISTS THEN FUNCTION = %TRUE
                              'CloseHandle hMutex
                              END FUNCTION


                              ------------------
                              Henning
                              Henning

                              Comment


                                #16
                                Henning --
                                You should close Mutex, when it's not necessary anymore.
                                In certain situation - exactly before program termination (in PbMain).

                                Meanwhile, like Edwin mentioned, OS closes the handle automatically when the process terminates.
                                So, to close or not to close is mostly a style of programming.
                                You can leave a file opened. Here is the same.

                                Personally I follow a logic - if I opened/created, I should close/destroy.



                                ------------------
                                E-MAIL: [email protected]

                                Comment


                                  #17
                                  Semen,

                                  Thanks for clearing it up.

                                  ------------------
                                  Henning
                                  Henning

                                  Comment


                                    #18
                                    Henning,

                                    i have never used a Mutex in a DLL. You may want to consider
                                    doing so in the LIBMAIN function, and open or close the mutex
                                    depending on the Reason that the LIBMAIN was called.

                                    This is an idea, only, as I've never used them in DLL's.

                                    Regards,


                                    ------------------
                                    Clay C. Clear

                                    Clay Clear's Software
                                    mailto:[email protected][email protected]</A>

                                    Comment

                                    Working...
                                    X
                                    😀
                                    🥰
                                    🤢
                                    😎
                                    😡
                                    👍
                                    👎