Page 1 of 2

How to reject double run?

Posted: Thu Apr 05, 2012 7:26 am
by oryaaaaa
I don't know english word about follow code. and I don't research Tips.
Could you tell me follows tips?

1 Run
2 Run parameter -> Stop and gift parameter for 1..Run.

Thanks

VB code

Code: Select all

Namespace My

        Private Sub MyApplication_StartupNextInstance( _
                ByVal sender As Object, _
                ByVal e As Microsoft.VisualBasic.ApplicationServices. _
                StartupNextInstanceEventArgs) _
                Handles Me.StartupNextInstance
            Console.WriteLine("Cannot RUN")

            For Each cmd As String In e.CommandLine
                Console.WriteLine(cmd)
            Next

            e.BringToForeground = False
        End Sub
    End Class

End Namespace

Re: How to reject double run?

Posted: Thu Apr 05, 2012 8:41 am
by shadow
Hi,

do you mean a Mutex? The Mutex provides functionality to determine if your app is already running and so prevent to run multiple instances.
http://msdn.microsoft.com/de-de/library/aa914601.aspx

Re: How to reject double run?

Posted: Thu Apr 05, 2012 9:09 am
by oryaaaaa
I know CreateMutex. I used many times it. Do you know PB tips?

Re: How to reject double run?

Posted: Thu Apr 05, 2012 9:24 am
by oryaaaaa
I learned from jaPBe source. Do you know another solution?

Code: Select all

;/ Code snippets From jaPBEe Source
ProgramParameter$=ProgramParameter()

RunOneWin=FindWindow_(@"WindowClass_0",@"jaPBe-RunOneWindow")
File$=ProgramParameter$
;
If RunOneWin
  If runone
    If File$
      cd.COPYDATASTRUCT
      cd\dwData=#WMCD_OpenFile
      cd\cbData=Len(File$)
      cd\lpData=@File$
      SendMessage_(RunOneWin,#WM_COPYDATA,MainWin,cd)  
    EndIf
    End ;/ END
  EndIf
Else
  RunOneWin=OpenWindow(0,0,0,100,100,#PB_Window_Invisible,"jaPBe-RunOneWindow")
EndIf
;

Procedure WindowCallback(WindowId, message, wParam, lParam)
  Select message
    Case #WM_COPYDATA
      *cd.COPYDATASTRUCT=lParam
      Result=#False
      Select *cd\dwData
        Case #WMCD_OpenFile
          ;{Datei fnen
          If *cd\lpData
            autoload$= PeekS(*cd\lpData,*cd\cbData)
            If CheckCurrentFileList(autoload$) ; gnozal : enable reload source from plugin (like VD)
              If Sources()\FileName = autoload$
                Sources()\FileName=""
                NoFoldChangeProtection=a
                NoFoldChangeProtection=#True
                SCI_ClearAll()
                Sources()\Modify=#False
                SCI_SetSavePoint()
                NoFoldChangeProtection=a
              EndIf
              LoadSourceCodeReal(autoload$)
            Else
              LoadSourceCodeReal(autoload$)
            EndIf
            AddRecentFile(autoload$)
            SetForegroundWindow_(MainWin)
            EnableWindow_(MainWin,#True)
            If IsZoomed_(MainWin)
              ShowWindow_(MainWin, #SW_MAXIMIZE)
            Else
              ShowWindow_(MainWin, #SW_RESTORE)
            EndIf
            Result=#True
          EndIf
          ;}
      EndSelect
      Result=#True
  EndSelect
  ProcedureReturn Result 
EndProcedure

Re: How to reject double run?

Posted: Thu Apr 05, 2012 9:51 am
by dobro
at the top of the listing

Code: Select all

; ******* mettre ceci au debut du prg ****************
name_prg.s="EPB" ; the name of application
If Instance_Running(name_prg.s)=#False  ; si EPB n'est pas lancé on quitte
	End
EndIf
; **************************************************²

the procedure test :)

Code: Select all

ProcedureDLL.l Instance_Running(LockStr$)
	*MyMutex = CreateMutex_(#Null, 1, LockStr$)
	If *MyMutex <> 0 And GetLastError_() = #ERROR_ALREADY_EXISTS
		CloseHandle_(*MyMutex)
		ProcedureReturn #True
		Else
		ProcedureReturn #False
	EndIf
EndProcedure

Re: How to reject double run?

Posted: Thu Apr 05, 2012 11:59 am
by TI-994A
Code updated for 5.20+

This code will prevent a second application instance from running, and will re-activate the running instance to the foreground even if it is hidden or minimized. It also passes the new command line parameters/arguments to the running instance, to be processed as required. To test it, you'll have to compile it, and launch a second instance with parameters from the command prompt:

Code: Select all

;==========================================
;
;   Passing command line parameters to a
;   running instance of an application
;   
;   by TI-994A  -  5th April, 2012
;
;==========================================

EnableExplicit
Enumeration
  #MainWindow
  #TextBox1
EndEnumeration

Define.i appInstance, hWndRunningInstance, paraLoop, wFlags
Define.s mutexName, cmdLineParameters, cmdLineDATA.COPYDATASTRUCT

mutexName = "myUniqueAppFlag"
appInstance = CreateMutex_(0, 1, @mutexName)

If appInstance <> 0 And GetLastError_() = #ERROR_ALREADY_EXISTS
  hWndRunningInstance = FindWindow_(0, "Command Line Arguments")
  
  For paraLoop = 1 To CountProgramParameters()
    cmdLineParameters = cmdLineParameters + "," + ProgramParameter()
  Next paraLoop
  
  cmdLineDATA\cbData = Len(cmdLineParameters)
  cmdLineDATA\lpData = @cmdLineParameters
  SendMessage_(hWndRunningInstance, #WM_COPYDATA, 0, @cmdLineDATA)
  
  CloseHandle_(appInstance)
  End
EndIf

Procedure WndProc(hWnd, uMsg, wParam, lParam)
  Define.i result = #PB_ProcessPureBasicEvents
  Define cmdLineARGs.s, *cmdLineDATA.COPYDATASTRUCT

  Select uMsg
      
    Case #WM_COPYDATA
      If Not IsWindowVisible_(WindowID(#MainWindow))
        HideWindow(#MainWindow, 0)
      EndIf
      If GetWindowState(#MainWindow) = #PB_Window_Minimize
        SetWindowState(#MainWindow, #PB_Window_Normal)
      EndIf
      SetForegroundWindow_(WindowID(#MainWindow))
      *cmdLineDATA = lParam
      cmdLineARGs = PeekS(*cmdLineDATA\lpData, *cmdLineDATA\cbData)
      If Trim(cmdLineARGs) = "" 
        cmdLineARGs = "none received."
      EndIf
      SetGadgetText(#TextBox1, "New Parameters: " + cmdLineARGs)
      
  EndSelect
  
  ProcedureReturn result
  
EndProcedure

    
wFlags = #PB_Window_ScreenCentered | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
OpenWindow(#MainWindow, #PB_Any, #PB_Any, 500, 100, "Command Line Arguments", wFlags)
TextGadget(#TextBox1, 50, 30, 400, 30, "")
SetWindowCallback(@WndProc())

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Hope this is helpful for you.


EDIT: code updated to comply with PureBasic's new label/colon syntax.

Re: How to reject double run?

Posted: Thu Apr 05, 2012 4:21 pm
by oryaaaaa
Thank you.

I am making Bug head new version. It's new audio player on the world.

Re: How to reject double run?

Posted: Thu Apr 05, 2012 11:05 pm
by ozzie
dobro wrote:at the top of the listing

Code: Select all

; ******* mettre ceci au debut du prg ****************
name_prg.s="EPB" ; the name of application
If Instance_Running(name_prg.s)=#False  ; si EPB n'est pas lancé on quitte
	End
EndIf
; **************************************************²

the procedure test :)

Code: Select all

ProcedureDLL.l Instance_Running(LockStr$)
	*MyMutex = CreateMutex_(#Null, 1, LockStr$)
	If *MyMutex <> 0 And GetLastError_() = #ERROR_ALREADY_EXISTS
		CloseHandle_(*MyMutex)
		ProcedureReturn #True
		Else
		ProcedureReturn #False
	EndIf
EndProcedure
Interesting! I'm using almost identical code to the above except I'm calling CreateSemaphore_ instead of CreateMutex_. Seems to work OK, but is CreateMutex_ a better function to use for this purpose?

Re: How to reject double run?

Posted: Fri Apr 06, 2012 5:53 am
by TI-994A
ozzie wrote:Interesting! I'm using almost identical code to the above except I'm calling CreateSemaphore_ instead of CreateMutex_. Seems to work OK, but is CreateMutex_ a better function to use for this purpose?
Gooday ozzie! While both these functions are good implementations for controlling application instances, as we are doing, they are actually meant for controlling thread or object instances within applications. The main difference between the two, that I know of, is that CreateMutex() is restricted to a single instance, while CreateSemaphore() allows multiple instances with its maximumCount parameter. These are powerful functions, with elaborate security attributes, that are very useful for controlling access to shared resources, like databases.

So, for checking if an instance of an application is already running, either one will do, but to allow a limited number of instances to run simultaneously, CreateSemaphore() would be required.

Hope it answers your question.

Re: How to reject double run?

Posted: Fri Apr 06, 2012 9:18 am
by Mesa
That works fine with me :
http://www.purebasic.fr/english/viewtop ... 12&t=47684
(for Windows only).

Mesa.

Re: How to reject double run?

Posted: Fri Apr 06, 2012 11:45 am
by ozzie
Thanks for the explanation re semaphores, TI-994A. That all makes sense.

Re: How to reject double run?

Posted: Fri Apr 06, 2012 12:25 pm
by dobro
[HS on ]

I also possessed a TI-994A and Cartridge ,voice synthesizer

very good memory of this computer

cool link :
http://www.ti99.com/zoneti.htm

Ti99 in tower :
http://www.ti99.com/ti994f.htm
[HS off ]

Re: How to reject double run?

Posted: Fri Apr 06, 2012 1:29 pm
by TI-994A
ozzie wrote:Thanks for the explanation re semaphores, TI-994A. That all makes sense.
Thank you for saying so. I'm really glad it helped.
dobro wrote:I also possessed a TI-994A and Cartridge ,voice synthesizer

very good memory of this computer

cool link :
http://www.ti99.com/zoneti.htm

Ti99 in tower :
http://www.ti99.com/ti994f.htm
Absolutely! The BASIC programming reference that it was bundled with was my very first programming "textbook". And because of the expensive cartridges, I was relegated to typing in source listings that were found in computer magazines. I really learned a lot from that computer.

Thanks for the cool links!

Re: How to reject double run?

Posted: Sat Apr 07, 2012 1:19 am
by ozzie
I know we're going OT here, but my first 'personal' computer was a Sinclair ZX80. My only regret is that I sold it :(

Re: How to reject double run?

Posted: Sat Apr 07, 2012 5:55 am
by TI-994A
ozzie wrote:I know we're going OT here, but my first 'personal' computer was a Sinclair ZX80. My only regret is that I sold it :(
That was a very popular machine as well. I never got used to the membrane keyboard, not having lower case, and how the lines of code jumped to the top of the screen whenever we hit [NEW LINE]; but I loved the design.