Jump to content

how to check for duplicate instance of script


Guest s_mack
 Share

Recommended Posts

  • Developers

Hmmm... very interesting.

I don't wish to introduce complex code into this application (it crashes enough as it is lol) so is this method considered safe? DllCall, kernel32.dll, something called "CreateMutex".... seems like a very convoluted way to see if an instance is already running.

I'm more than willing to give it a try, but I hesitate to add something to the code that is going to require hours upon hours of exhaustive testing to try and break it. Also, as soon as I see kernel32.dll I have to ask what platforms it will work on - no mention of that in the file.

Thank you very much for the suggestion! Any other methods?

- Steven

Another way:

If WinExists("MyProgram_Unique") then Exit
AutoItWinSetTitle("MyProgram_Unique")

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Yeah, but I wanted to do it with processes because win titles seem both slow and loose. While I appreciate they are at the heart of much of what AutoIt is used for... its not whay I use it for :P

Thanks though!

Is there no way to do it by PID?

- Steven

Link to comment
Share on other sites

  • Moderators

Singleton("Put your window name here")


Func Singleton($semaphore)
    Local $ERROR_ALREADY_EXISTS = 183
    DllCall("kernel32.dll", "int", "CreateSemaphore", "int", 0, "long", 1, "long", 1, "str", $semaphore)
    Local $lastError = DllCall("kernel32.dll", "int", "GetLastError")
    If $lastError[0] = $ERROR_ALREADY_EXISTS Then Exit -1
EndFunc; Singleton()

Pretty simple, only a few lines and fixes you right up.

Edit:

Put it at the very top of your script, so it's the first thing ran.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Thanks, but that's exactly what JdeB first suggested, to which I had concerns (not addressed - but that's ok, I asked the author).

For this particular case, I think a hybrid solution will be best. See, in my script it depends on how the script is called whether or not I want interaction so I I'm going to use a combination of the WinExists method along with a ProcessExists method that checks for spawned processes if the script is called a certain way.

I believe this will cover me the best without having to worry about whether or not a DLL call is stable.

- Steven

Link to comment
Share on other sites

  • Moderators

Thanks, but that's exactly what JdeB first suggested, to which I had concerns (not addressed - but that's ok, I asked the author).

For this particular case, I think a hybrid solution will be best. See, in my script it depends on how the script is called whether or not I want interaction so I I'm going to use a combination of the WinExists method along with a ProcessExists method that checks for spawned processes if the script is called a certain way.

I believe this will cover me the best without having to worry about whether or not a DLL call is stable.

- Steven

I understand Jdeb answered it for you... And with someone of his ability, I would have taken that to heart. You probably want to do some research on the term Semaphore, and look at how it generates a "unique flag" for whatever your doing. You don't just have to use it to "Exit", you can make it do something else.

You say, you don't "Always" want it to run, only if a specific action is done... You also say you don't know if you can trust the stability of DLLCall() (well..., I'd trust that over untested coding any day, especially using a windows DLL).

Below, if you put the first line at the top of your script, create a simple ini file (probably don't even need to do that), you'd see. Try a test on it... Compile 2 of them with different names even, and do something that would trigger the Semaphore, then try to run the other copy. Then, exit the original, and without setting it off, try and run both... you'll see that in one instance you get the MsgBox and the other you don't.

If IniRead("C:\WHERE_EVER_INI_IS", "SEMAPHORE", "ON_OR_OFF", "") <> "" Then Singleton("TITLE FOR INI")
    
While 1
    If "WHATERVER I WANT TO DO TO CREATE A UNIQUE FLAG OPTION" = "WHATEVER I'M SETTING IT TOO" Then
        IniWrite("C:\WHERE_EVER_INI_IS", "SEMAPHORE", 'ON_OR_OFF", "SOMETHING GREATER THAN ""')
        Singleton("TITLE FOR INI")
    EndIf
    Sleep(100)
WEnd

Func Singleton($semaphore)
    Local $ERROR_ALREADY_EXISTS = 183
    DllCall("kernel32.dll", "int", "CreateSemaphore", "int", 0, "long", 1, "long", 1, "str", $semaphore)
    Local $lastError = DllCall("kernel32.dll", "int", "GetLastError")
    If $lastError[0] = $ERROR_ALREADY_EXISTS Then 
        MsgBox(0, "TEST", "THIS A TEST, THERE IS A COPY RUNNING ALREADY, I WILL EXIT NOW")
        Exit
    EndIf
EndFunc; Singleton()

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Don't get me wrong! I completely appreciate that people who suggest an author such things know far more than I do - you're sounding as though I was not believing them or something. No, I'm smart enough to know that when I don't understand something I should be cautious of using it. You're right, if I want to use such a function I should be reading up on Semaphore, etc because without that knowledge I'd be blindly using the function not entirely sure of the circumstances of when it will work and, more importantly, when it may not. Hense my valid questioning.

And without understanding any of it, I am still certain I should be unconfortable using it. Take your comment for me to look up what a semphamore is... well, clearly someone thought that wasn't the way to go because in the latest code for _Singleton the reference to CreateSemphamore has been commented out and CreateMutex has been put in its place. In other words, there is aparantly debate or extenuating circumstances relating to its use.

To be quite honest, I don't have the time nor the inclanation to learn the inner workings of these programs and I was hoping to find a simple solution OR get an indication that this function was 100% surefire. However, I've read several posts of people who were unable to get it to work, with little explanation back rather than "I wrote it so it must work" type answers.

Anyway, I thank you all for your input. I'll take it on advisement and I'll experiment with it. I've already done many tests and yes, in my environment, it appears to work - but that doesn't mean it will work in other environments.

- Steven

Link to comment
Share on other sites

  • Moderators

I wasn't aware that the 2 were different or that they had even added one to the help file (I just looked)... I'm sure the author of mine ("Valik"), could explain the 2 differences if and or whenever he reads the post.

And I've used it in all windows enviroment except 95 and 98 1st edition, it's quite stable just so that you know... GL with it :P.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

this is the one from the help file...works pretty good

; Place at the top of your script
$g_szVersion = "My Script 1.1"
If WinExists($g_szVersion) Then Exit; It's already running
AutoItWinSetTitle($g_szVersion)
; Rest of your script goes here
Link to comment
Share on other sites

Smoke - so you used it in 98SE? If it works there than that's probably as far back as I need to go.

I never said it wasn't the best way to do it - by all accounts it sounds like it is - I just want to be sure I understand what it is doing more thoroughly before I implement it and I was hoping to get a better indication of its track record before spending the time to learn (and the concepts, I'll admit, are FAR beyond where I'm at now so it would be hours of reading)

- Steven

Link to comment
Share on other sites

In the future, may I suggest you be careful about who's code you question. In both threads where you have commented on _Singleton(), you have stated you are a inexperienced with this sort of stuff. Therefore, given your inexperience, does it seem wise to question a developer's code about stability and such (I'm completely ignoring the fact that I am the particular developer, by the way)? If it was unstable, don't you think that an author with as much experience as this one would of marked it as such? Your comments and doubts about the stability more or less read like the author of the function was an idiot who doesn't know what he is doing. If things were really all that bad, don't you think somebody would of maybe remarked on the instability?

And for the record, using a Semaphore/Mutex is the correct way under Windows programming for allowing only a single instance of an application to run. Calling trivial code complex and saying it is convoluted when it is the standard method for doing something shows a very high level of ignorance on the subject; a level high enough that you shouldn't be making such comments in the first place because you aren't informed enough to make them.

Now, with that out of the way. Whatever your hybrid solution is, it's probably not necessary. I can allow multiple instances of a script to run when necessary while still using my _Singleton() function. In fact, I don't even use the version in Misc.au3 which offers more functionality than my original. I just continue to use the original function posted in the thread I created.

Link to comment
Share on other sites

I did not take it personally and my comment to the effect that I was ignoring the fact that I was the author was meant to convey that. Perhaps the thing I find most... derogatory about your post(s) is the length/number on the subject. Ignoring the fact that you should be able to scientifically draw the conclusion that the function is safe based on several factors:

  • Who the author was (As in a broad group).
  • Who the author was (the specific person).
  • The fact that the function comes with the language.
Ignoring that, perhaps if you would of just asked how the function worked instead of polluting the posts with comments of your ignorance on the subject and making subjective claims about the code, perhaps it wouldn't be so bad. Or maybe if you would of searched the forum more as I've explained in great detail why the _Singleton() function using either a Semaphore or Mutex is the best way to give an application the singleton pattern.

In other words, the information is already there and available from several different avenues. In addition, even if still compelled to ask, the extraneous comments were unnecessary and served only to make the important information more lost in the sea of words.

To address other points:

I use code I don't understand the implementation of all the time. I don't delve (too much) into the STL libraries when I happen to use them or the C libraries which I'm more likely to use. I don't question the Windows functions I call. I rely on the fact that if it's provided by the people producing the tools, chances are, it's safe to use. If I have a curiosity about a particular function or library or a need to roll my own version of a concept, I'll look at the source code available for other libraries in addition to reading literature on the internet.

There is some science that can be applied to software engineering but the idea of completely understanding everything before using it is not scalable. Functions should be treated as a black box. The documentation should tell you what to put in and assuming you put in the data correctly, the function should return the data that is expected (based on the correct documentation). How something works should never be relevant until it becomes relevant for performance reasons or the need/want to create your own version. Most of the time, as long as I give a function what it wants and it does what I need, that's all that is important.

I also want to emphasize that I am not questioning JP's modification to my function. Questioning it implies to me that I have a problem with the change. I do not. However, I wish to know his reason. I'm curious if he read something I missed which means a Semaphore won't work in all cases or if he mis-read something and has an error in his thinking (Although, still, no error in the code). So, if you wish to make a tidal wave from a ripple, that is your decision but I assure you that there is more disagreement between JP and I than just a simple function that works using either his code or mine.

As for the suitability of your code? Well, I'm still probably the better judge because I understand the design pattern you are dealing with. I can point out multiple ways of implementing it with varying degrees of reliability as well as ways to beat every method. Some are very difficult like using a Semaphore/Mutex and others are trivial to bypass like using the process name or window title. Also, keep in mind, if you are breaking the design pattern my function is implementing, then yes, my code is not going to work for your problem. However, it isn't fair to say code doesn't work for a problem when it wasn't meant to solve the problem it's being used for. Based on what you explained, my function is the one you want. If my function does not suit your needs, it is an error in communicating your needs correctly.

Link to comment
Share on other sites

You've obviously not read very many posts by me. I wasn't even being hard on you and you're whining about how you're being treated. I suggest you look up a few of my posts to other members to see what I can be like if I'm in a bad mood.

Link to comment
Share on other sites

You've obviously not read very many posts by me. I wasn't even being hard on you and you're whining about how you're being treated. I suggest you look up a few of my posts to other members to see what I can be like if I'm in a bad mood.

I think he's just one of the type that he's trying to pretend everyone else is. Taking any feedback as direct criticism of himself. In another thread i suggested that he post some of his code so that others may be able to help him speed up a function, and he replied back in similar fashion. He said that because his function was only one line to an external executable to detect a server status, there would be no way to speed it up, blah blah blah, but because of his obvious resistance, i didn't even bother to let him know that he may be able to bypass the need for the external program completely, using other methods to get the same info much faster. What can you do about someone asking for help that doesn't want help?
Link to comment
Share on other sites

I think he's just one of the type that he's trying to pretend everyone else is. Taking any feedback as direct criticism of himself. In another thread i suggested that he post some of his code so that others may be able to help him speed up a function, and he replied back in similar fashion. He said that because his function was only one line to an external executable to detect a server status, there would be no way to speed it up, blah blah blah, but because of his obvious resistance, i didn't even bother to let him know that he may be able to bypass the need for the external program completely, using other methods to get the same info much faster. What can you do about someone asking for help that doesn't want help?

I had a reply typed up to that other thread which would have hidden the delay the OP was talking about which is effectively the same as making it go away. However, before I submitted, my browser crashed. Obviously I didn't bother re-typing the reply. Oh well, I would of probably be questioned about the complexity and the convolution and the stability of my code anyway and I would be asked to explain it all despite it's simple nature so perhaps my browser's crash saved me some hassle.
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...