Jump to content
ur

Singleton is not restricting the new instance

Recommended Posts

I have used _Singleton function in my script to restrict only one instance to run.

For testing, I have written below code, and triggered multiple instances.

#include <Misc.au3>
MsgBox(0,"",@ScriptName)
if _Singleton(@ScriptName, 1) = 0 Then
    Msgbox(64, @ScriptName, "The program is already running.")
    Exit
Else
    MsgBox(0,@ScriptName,"No other instances running")
EndIf

But all are going to else block.

 

Please suggest.

Share this post


Link to post
Share on other sites
#include <Misc.au3>
MsgBox(0,"",@ScriptName)
if _Singleton(@ScriptName, 1) = 0 Then
    Msgbox(64, @ScriptName, "The program is already running.")
    Exit
Else
    MsgBox(0,@ScriptName,"No other instances running")
EndIf

Is this your complete script? It ends after clicking the message box.

 

Put

While 1
Wend

at the end of your script to keep it running-


Rule #1: Always do a backup         Rule #2: Always do a backup (backup of rule #1)

Share this post


Link to post
Share on other sites

You can also try using the full path of your script for singleton as the identifier, here is an example from one of my projects:

Handle_MultipleInstance()

Func Handle_MultipleInstance()
    If _Singleton(StringReplace(@ScriptFullPath, '\', '/'), 1) = 0 Then
        Local $iMsgBoxParams = $MB_ICONWARNING + $MB_YESNO + $MB_DEFBUTTON2
        Local $sMsgBoxMsg = "ProxAllium seems to be already running, do you still want to create a new instance?"
        Local $iUserChoice = MsgBox($iMsgBoxParams, "ProxAllium is already running!", $sMsgBoxMsg)
        If $iUserChoice = $IDYES Then Return
        Exit
    EndIf
EndFunc

Feel free to adapt it as you wish :)


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

Thanks @KaFu and @ajag

 

It is the script used for testing singleton.

If I run the script and hold it without clicking ok for message box and run another instance again, it is still going to else section only.

Share this post


Link to post
Share on other sites
4 minutes ago, TheDcoder said:

You can also try using the full path of your script for singleton as the identifier, here is an example from one of my projects:

Handle_MultipleInstance()

Func Handle_MultipleInstance()
    If _Singleton(StringReplace(@ScriptFullPath, '\', '/'), 1) = 0 Then
        Local $iMsgBoxParams = $MB_ICONWARNING + $MB_YESNO + $MB_DEFBUTTON2
        Local $sMsgBoxMsg = "ProxAllium seems to be already running, do you still want to create a new instance?"
        Local $iUserChoice = MsgBox($iMsgBoxParams, "ProxAllium is already running!", $sMsgBoxMsg)
        If $iUserChoice = $IDYES Then Return
        Exit
    EndIf
EndFunc

Feel free to adapt it as you wish :)

Thank you .. it is working for my requirement.

Share this post


Link to post
Share on other sites

And also if I replace @ScriptFullPath with some random name (test), it is working.

 

While(_Singleton("test", 1) = 0)
    Sleep(5000)
    MsgBox(0,"","Another instance of MainScript is running..so waiting in the background to complete")
WEnd

 

Share this post


Link to post
Share on other sites

@ur Good to see that it is working, I use @ScriptFullPath because it is kind of good and unique identifier, though you should be aware that you can run multiple instances of the same script but a different copy of it in a different location if you use my method. The string parameter is totally arbitrary and you can have it as anything you want. :)


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

That string needs to be unique per script though.

Here is another way to use the _Singleton command.

$status = _Singleton("unique-name-here", 1)
If $status = 0 Then
    ; Attempt to retore and activate a non-active or minimized window.
    If @Compiled = 1 Then
        $pid = ProcessExists(@ScriptName)
        $exe = @ScriptName
    Else
        $pid = ProcessExists("AutoIt3.exe")
        $exe = "AutoIt3.exe"
    EndIf
    $script = @AutoItPID
    If $script <> $pid Then
        $wins = WinList($Scriptname, "")
        For $w = 1 to $wins[0][0]
            $handle = $wins[$w][1]
            If WinGetProcess($handle, "") = $pid Then
                WinSetState($handle, "", @SW_RESTORE)
                WinActivate($handle, "")
                ExitLoop
            EndIf
        Next
        Exit
    EndIf
EndIf

or

$exist = _Singleton("use-unique-name", 1)
If $exist = 0 Then
     If @Compiled = 1 Then
         $pid = ProcessExists(@ScriptName)
         $exe = @ScriptName
     Else
         $pid = ProcessExists("AutoIt3.exe")
         $exe = "AutoIt3.exe"
     EndIf
     $script = @AutoItPID
     $ans = MsgBox(262177, "Close Running Instance Query", _
         "This program is already running." & @LF & @LF & _
         "Do you want to close it for this new instance?" & @LF & @LF & _
         "NOTE - If all work has been saved, then OK" & @LF & _
         "could be clicked, else click CANCEL." & @LF & @LF & _
         $pid & " (" & $exe & ") " & $script & @LF & @LF & _
         "(will default to CANCEL in 30 seconds)", 30)
     If $ans = 1 Then
         If $pid <> $script Then
             ProcessClose($pid)
         Else
             MsgBox(262192, "Close Error", "OK process failed!", 0)
             Exit
         EndIf
     ElseIf $ans = 2 Or $ans = -1 Then
         Exit
     EndIf
EndIf

Extracted from a couple of my programs, with slight modification.

Edited by TheSaint

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites
8 minutes ago, TheSaint said:

That string needs to be unique per script though.

It doesn't have to be, you can also choose to deliberately generate a string according to whatever set of rules you want for you want. A good example is my code which uses the full path of the script, it is designed to be totally portable and conflict free from other instances of the program excluding the it's own executable ;)


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
31 minutes ago, TheDcoder said:

It doesn't have to be, you can also choose to deliberately generate a string according to whatever set of rules you want for you want.

Not correct. _Singleton is using that value as the query marker.

If two programs have the exact same string, then _Singleton will see them as the same.

P.S. On further reading your reply, it appears you contradicted yourself, because yes you can do the latter of what you said, but the former negation does not apply for a string. I said nothing about a variable or generated string ... I was keeping it simple.

Edited by TheSaint

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites
41 minutes ago, TheDcoder said:

The string parameter is totally arbitrary and you can have it as anything you want.

I was also replying to that, which is incorrect or incomplete. It should be the following.

Quote

The string parameter is totally arbitrary and you can have it as anything you want, so long as it is unique per script.

How you make it unique, is up to you.

You can do a fancy generated string or you can do something quick like I normally do, which is to use name parts of the program name, separated by dashes, plus a dash and my name on the end. That for me, should ensure no-one else will come up with the same name.

i.e. _Singleton("azw-plugin-thsaint", 1)

Edited by TheSaint

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites

@TheSaint I don't see why it is incorrect. For programs which can handle multiple copies (separate instances running in different locations/folders), it is useful to limit to only that particular executable file, if the program had a single constant string for singleton that would obviously not work.

Take my program ProxAllium for example, you can have 2 copies of it and have them run simultaneously, but it will warn you if you try to start another instance of the same copy.

So it is would be wrong to strictly say "the string for singleton must be unique for the script", your script should be able to supply unique strings according to the conflict conditions. (like the path of the script in ProxAllium's case)

Of course you could still go the easy way and just use a hardcoded string, but that doesn't make my usage incorrect :D


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

If I have hurt or offended you in anyway, Please accept my apologies, I never (regardless of the situation) mean to do that to anybody!!!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

@TheDcoder - I am not saying your approach is wrong, and you have indeed explained a good reason. However, you said I was wrong, which I wasn't ... not in the simple context, which was all I used.

In any case, whichever way you look at it, you are still providing a unique string for the string value, which is exactly what I said.

My own later example, was my usage only ... as an example. That was not what you responded to when you said I was wrong. :)

As for my examples, they were just a couple of illustrations of the possibilities. There are others. You could also combine mine or tweak certain elements to do exactly as you suggested, without the need to provide a different path, just work on a response to a query, which is perhaps more correct when running two separate copies of the same program ... but that depends on the program. ;)

Edited by TheSaint

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By ur
      Is there anyway to check whether the script is launched already and wait till the other instance is closed and continue after that.
       
    • By n3wbie
      i Tried Using Function _single ton
      It Works Like Charm on same computer
      But it is unable to catch up when 2 instance of exe are launched in lan pc
      I would also like to know if there was a way to make particular number of instance work like allow 4-5 instance of same exe to run
    • By TheSaint
      This is just a little helpful script, that I started using a month or so ago (one program so far), with this version having a Restore ability added (so now using with two programs of mine, as of tonight).
      You can find other alternatives or similar scripts here, the most recent being - _SingleScript
      guinness also has something much more elaborate, that is well worth checking out - _SingletonHWID.
      Just place the following at the beginning of your script, and adjust where needed and wanted (including Scriptname, variable names and MsgBox magic numbers, etc). Perhaps you should read and use the following - Best coding practices ... unlike my slack hobby programmer self (not always).
      #include <Misc.au3> Global $ans, $exe, $handle, $pid, $script, $Scriptname, $status, $w, $wins ; Assign the program name (window title). $Scriptname = "Update Mp3 Artwork v7.9 (updated December 2015)" ; The following line both sets the unique ID of the current program, plus queries if a program with the same ID is running already. $status = _Singleton("update-mp3artwork-thsaint", 1) If $status = 0 Then ; A program with the same ID is already running. ; Assign a PID for previous script, based on current executable name, whether current script is compiled or not, and assign the executable name. If @Compiled = 1 Then $pid = ProcessExists(@ScriptName) $exe = @ScriptName Else $pid = ProcessExists("AutoIt3.exe") $exe = "AutoIt3.exe" EndIf ; Assign a PID for current script. $script = @AutoItPID ; $ans = MsgBox(262177, "Close Running Instance Query", _ "'Update Mp3 Artwork' program is already running." & @LF & @LF & _ "Do you want to close it for another instance?" & @LF & @LF & _ "NOTE - If all work has been saved, and you are" & @LF & _ "trying to work on another album, then a click on" & @LF & _ "OK is recommended, else just click CANCEL, to" & @LF & _ "attempt a restore or re-activate of original." & @LF & @LF & _ $pid & " (" & $exe & ") " & $script & @LF & @LF & _ "(will default to CANCEL in 30 seconds)", 30) If $ans = 1 Then ; Attempt to close original instance, and continue with new. If $pid <> $script Then ProcessClose($pid) Else MsgBox(262192, "Close Error", "OK process failed!", 0) Exit EndIf ElseIf $ans = 2 Or $ans = -1 Then ; Attempt to retore and activate a non-active or minimized window. ; Get a list of all running programs with the same name. $wins = WinList($Scriptname, "") ; Loop through found instances and compare PID's, restoring or re-activating any match. For $w = 1 to $wins[0][0] $handle = $wins[$w][1] If WinGetProcess($handle, "") = $pid Then WinSetState($handle, "", @SW_RESTORE) WinActivate($handle, "") ExitLoop EndIf Next Exit EndIf EndIf Enjoy!
      P.S. I have a couple of programs that I regularly forget are minimized while working with another related one, so this saves me some mucking around to close and restart or restore etc. Pretty basic, but does the job well so far.
    • By explorerpl
      Hi. I'm a teacher and I do a lot of tutorials and other presentations on my computer. I've developed a tool using AutoIt and Adobe AIR to display all the shortcuts I use while I'm presenting. According to the forum rules this would mean that I've developed a keylogger, so I can't show any of the code, but I'm still hoping someone will help me solve an issue I'm having - a memory leak (or at least I think that's it).
      I can see the application is taking up more and more memory, but it never goes super crazy. I think it was at 25 MB at one point and that was it. However I see that the longer the application is running less responsive it is. It doesn't capture all the events, or it simply lags. 
      I'm using AssocArrays and _MouseOnEvent UDFs, _WinAPI_SetTimer, _WinAPI_SetWindowsHookEx, _Singleton and TCP. I've done some research before posting this and I know there are some issues in special cases, but all solutions were "code specific". Since I can't post any of the code I couldn't respond in those threads. Other than that it really doesn't seem to be the problem with any of the UDFs, so my question is:
      Is this a memory leak? If so how can I find it and remove it? What to do to avoid it in the future.
      I understand that declaring variables over and over (something in the timer) may be the cause of this, so according to what I've read on the forum I've changed the variables to Global and moved them outside the functions. That way they are only declared once, and then only values are being reassigned. That unfortuantly didn't help. Is there anything else I could do or look for?
      BTW - I've used Adobe AIR to create a nice UI. If someone want's to create something similar UEZ was kind enough to share his code of creating such GUI with nice antialiased labels. 
      https://www.autoitscript.com/forum/topic/178366-adobe-air-like-window/#comment-1280587

    • By TheDcoder
      Hello , Please look at the code below:
      ; This is not the real script that I use for my project!!! This decoy script helps you understand better ;) #include "Misc.au3" Global $sProgramIdentifier Func Test($sIdentifier) $sIdentifier = $sProgramIdentifier Switch _Singleton($sProgramIdentifier, 1) Case 0 MsgBox(64, "Testing, Testing", "Its working!!") Case Else MsgBox(64, "Testing, Testing", "Its not working!!") EndSwitch EndFunc Test("Lick the lemon") Save this to a file and run it, you will get a MsgBox telling "Its not working!!"
      Again, Run the script a second-time without closing the first MsgBox and you will again get a MsgBox telling the same thing!! This was not supposed to happen
      How can I get the MsgBox telling that it works ?
      Thanks In Advance, TD
×
×
  • Create New...