erebus Posted May 5, 2007 Share Posted May 5, 2007 Hello all, I am using the _Singleton UDF in my programs and usually works well. However last night I found a problem related to _Singleton in one of my scripts which made me to make some tests so as to realize exactly how the function works. Have a look at this piece of code please: #include <Misc.au3> $app = "MyProg" $title = "Title" If _Singleton($app, 1) = 0 Then CError(_Singleton($app, 1) & @LF & @LF & "Already running.") Else CError(_Singleton($app, 1) & @LF & @LF & "End of script.") EndIf Func CError($msg) MsgBox(16, $title, $msg) Exit EndFunc Notice that even if you run the program once, the number on the message box is zero (meaning _Singleton($app, 1) = 0). Since = 0 means "already running" why the return of _Singleton is always zero? And since in that script the "Else" part is executed successfully, why the report number on that msgbox remains zero and not something else? Please explain because I have a script where _Singleton behaves abnormally. Thank you. Link to comment Share on other sites More sharing options...
PsaltyDS Posted May 5, 2007 Share Posted May 5, 2007 There is a rather cryptic remark in the the help file entry for _Singleton():RemarksIf an occurrence is already found the script is exited.The second call to the function in the same running script will fail.You are making a second and third call to the function in the same script... and it's failing?Seems odd, but that is an odd remark. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
PsaltyDS Posted May 5, 2007 Share Posted May 5, 2007 More information: Here is Valik's _Singleton() UDF from Misc.au3:; ------------------------------------------------------------------------------ ; ; AutoIt Version: 3.1.1++ ; Language: English ; Description: Functions that assist with Common Dialogs. ; ; ------------------------------------------------------------------------------ ; <snip> ;=============================================================================== ; ; Description: _Singleton ; Parameter(s): $occurenceName ; $flag ; User CallTip: _Singleton($occurenceName [,$flag = 0]) Check if no other occurence is running. (required: <Misc.au3>) ; Return Value(s): if $flag = 1 ; Author(s): Valik ; ;=============================================================================== Func _Singleton($occurenceName, $flag = 0) Local $ERROR_ALREADY_EXISTS = 183 $occurenceName = StringReplace($occurenceName, "\", "") ; to avoid error ; Local $handle = DllCall("kernel32.dll", "int", "CreateSemaphore", "int", 0, "long", 1, "long", 1, "str", $occurenceName) Local $handle = DllCall("kernel32.dll", "int", "CreateMutex", "int", 0, "long", 1, "str", $occurenceName) Local $lastError = DllCall("kernel32.dll", "int", "GetLastError") If $lastError[0] = $ERROR_ALREADY_EXISTS Then If $flag = 0 Then Exit -1 Else SetError($lastError[0]) Return 0 EndIf EndIf Return $handle[0] EndFunc ;==>_SingletonHe test for the process by creating a process (or at least a Mutex which appears to be equivilent) with the same name - "CreateMutex". After returning results that mutex/process seems to be abandoned, meaning it will still be there and throw off the results if you run it again. Seems like there ought to be code in there to get rid of the just-created object once it's not required, but if you think about it, it's not a big deal.It's only meant to be run once, so only one extra object should be created. Since it is a child process of the running script, it should die when the script exits, I guess.Seems like the UDF could clean up after itself with a "ReleaseMutex" call using the handle of the one just created. But smarter people may know why it doesn't work that way. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
erebus Posted May 5, 2007 Author Share Posted May 5, 2007 (edited) Maybe Valik can enlight us on this. I have no clue. Thank you very much for this tip. I had miss the part on the helpfile where it says that "The second call to the function in the same running script will fail.". Apparently this seems to be my problem. However, I can understand the initial purpose of the _Singleton function, however it is not standard that one would like to call it only once in his script. And I will explain you why. In my script I give the user the option to make a setting so as different script's parts to be allowed to execute while another instance of the script is already running. Let's say: piece of code here... If $MultiCheck = "3" And _Singleton($app, 1) = 0 Then CError("Please close all previous instances of " & $app & " first."); disallow multiple instances completely more code here... If $MultiCheck = "2" And _Singleton($app, 1) = 0 Then CError("Please close all previous instances of " & $app & " first."); allow preview of the GUI only more code here... If $MultiCheck = "1" And _Singleton($app, 1) = 0 Then CError("Please close all previous instances of " & $app & " first."); allow preview of the GUI + button press but nothing more more code here... The code is almost 500 lines and I wouldn't like to publish it, but you got the point. However the _Singleton command does not always work the way I want. So, if Valik consider this as a bug, or a new feature to add to this function he can let us know (maybe we both are wrong, I don't know). To be honest, I suspected something like that and added Sleep() pauses before calling _Singleton to do if this would do the trick. But it didn't... Or else I don't know, maybe I should check in a different manner for multiple instances to do what I want. So far, Edited May 5, 2007 by erebus Link to comment Share on other sites More sharing options...
flyingboz Posted May 5, 2007 Share Posted May 5, 2007 However the _Singleton command does not always work the way I want.So code a function that does, or a wrapper around _Singleton(). I don't see anything that isn't straightforward that would be required for you to get what you want (though I admit I skipped over quite a bit of verbage ) Reading the help file before you post... Not only will it make you look smarter, it will make you smarter. Link to comment Share on other sites More sharing options...
MHz Posted May 5, 2007 Share Posted May 5, 2007 There is always FAQ14... But checking for new instance is normally done in the new instance, not the existing script as you portray? Link to comment Share on other sites More sharing options...
erebus Posted May 5, 2007 Author Share Posted May 5, 2007 (edited) @flyingboz: If I knew the way to do something better than this, trust me I would have done it already. Please do not just use irony if you don't have something useful to add on the issue. I am not a kiddy to just tell me "use it if you like it or write up your own". I have a problem with a function and I propose a new idea to expand its functionality. If Valik (or anybody else) likes that and finds it can do something (if he also thinks that there is a good reason to do so), that's fine, I would be glad and thankful. If not, it's ok too, I will find another workaround and would be all happy again. So what is the problem now? Why is this forum made for if not for discussing problems and new ideas? @MHZ: I didn't exactly understand this... If I translate correctly, yes the check is done in the new instance but since it is the same script, the code is the same. The problem is that I cannot reproduce this in a small script - because then it works fine. So I need a verification on this - was _Singleton() made in the first place to be called multiple times in a script? Is there any chance (even theoritically) for the function to fail if used in that way? The only reason I am thinking of this is because of what PsaltyDS said about the "ReleaseMutex" thing. I am sorry, I do not have the knowledge to examine the _Singleton() function and analyze step-by-step what it does to understand if something is going wrong. That's why I am asking here... Thank you all so far, Edited May 5, 2007 by erebus Link to comment Share on other sites More sharing options...
MHz Posted May 5, 2007 Share Posted May 5, 2007 Script a.au3 #include <Misc.au3> $app = "MyProg" $title = "Title" If _Singleton($app, 1) = 0 Then CError(_Singleton($app, 1) & @LF & @LF & "Already running.") EndIf Sleep(10000) Func CError($msg) MsgBox(16, $title, $msg) Exit EndFuncoÝ÷ ÚØ^»§m«·jëh×6#include <Misc.au3> $app = "MyProg" $title = "Title" If _Singleton($app, 1) = 0 Then CError(_Singleton($app, 1) & @LF & @LF & "Already running.") EndIf Func CError($msg) MsgBox(16, $title, $msg) Exit EndFunc then tell me singleton is not working... if it was not, then you would see same from both scripts. Link to comment Share on other sites More sharing options...
erebus Posted May 5, 2007 Author Share Posted May 5, 2007 Yes it works as expected. That is why I said 'sometimes' in a previous post. Anyway, I have sent you a PM with the code to see for yourself if you want to examine it a little further. Thank you all very much for your help. Link to comment Share on other sites More sharing options...
martin Posted May 5, 2007 Share Posted May 5, 2007 Seems like the UDF could clean up after itself with a "ReleaseMutex" call using the handle of the one just created. But smarter people may know why it doesn't work that way.The Mutex created by a process must be cleaned up by Windows when an application closes because if you end end a script which uses _singleton with Ctrl Alt Del the script will run again. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
corgano Posted August 8, 2013 Share Posted August 8, 2013 (edited) sorry for bumping an old topic, but this had a lot of very useful, relevant information, and I thought it would be a good idea to keep all this info in one thread for anyone looking for it later Is there a way to clear a singleton after it's made? In my script, I'm useing ProgressOn boxes to show a file copying. Since the window remains inactive for most of the copy, moving it is award. I was using singletons to check if there are any other progress windows and offset the new window when created expandcollapse popupFunc ProgressCopy($src, $dst, $copygap = 2) Local $OptEnv, $OptVar, $size, $in, $out Local $progress = 0, $count = 0, $chunk = 524288, $timer = TimerInit(), $size = FileGetSize($src) ConsoleWrite("Copy "&$src&@CRLF&"To "&$dst&@CRLF) $OptEnv = Opt("ExpandEnvStrings", 0) $OptVar = Opt("ExpandVarStrings", 0) for $y = 0 to 9 If _Singleton("Progress-"&$y, 1) <> 0 Then ExitLoop Next ProgressOn("File Copy Progress", "Copying " & $src & " ...", "0 of " & Round($size / 1024 / 1024, 2) & " MB copied. (0%)", 0, 100*$y, 18) ; Open input and output files (exit if error) $in = FileOpen($src, 0) If @error <> 0 Then Return 0 $out = FileOpen($dst, 10) If @error <> 0 Then FileClose($in) Return 0 EndIf ; Start reading input $bin = FileRead($in, $chunk) While @error = 0 ; Write chunk of data, keep trying for up to 10 seconds if failed Do FileWrite($out, $bin) Until (@error = 0) Or (TimerDiff($timer) > 10000) If @error <> 0 Then FileClose($in) FileClose($out) Return 0 EndIf $count = $count + $chunk If TimerDiff($timer) > 150 Then $progress = Int(($count / $size) * 100) ProgressSet($progress, Round($count / 1024 / 1024, 2) & " of " & Round($size / 1024 / 1024, 2) & " MB copied. (" & $progress & "%)") $timer = TimerInit() EndIf Sleep($copygap) $bin = FileRead($in, $chunk) WEnd ProgressSet(100, $size & " of " & $size & " bytes copied. (100%)") FileClose($in) FileClose($out) Sleep(100) ProgressOff() Opt("ExpandEnvStrings", $OptEnv) Opt("ExpandVarStrings", $OptVar) ; Return success Return 1 EndFunc ;==>ProgressCopy (From someone on the forum, don;t remember whom. Credit goes to him and/or her) I added the singleton bit and the offset, so if it is called by more than one program, the windows won't overlap. The problem is if the same program calls it twice, the second progress window will be moved down because the singleton exists form the first one If I could remove a singleton after the copy completes, It would always position the windows correctly. Anyone know how? Edited August 8, 2013 by corgano 0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e Link to comment Share on other sites More sharing options...
Abilio_KID Posted February 28, 2014 Share Posted February 28, 2014 Isn't it simpler to go around and use the builtin AutoIT functions? To check if our program (whatever the name is) is already running (the way I do it, of course): ; Check if this program is already running. If so then exit. $p = ProcessList(StringReplace(@ScriptName,".au3",".exe")) If $p[0][0] > 1 Then MsgBox(0,"Error", @ScriptName & " is already running! Exiting...", 3) Exit EndIf vicsar 1 Link to comment Share on other sites More sharing options...
FireFox Posted February 28, 2014 Share Posted February 28, 2014 It only works if the scriptname is the same so no. Link to comment Share on other sites More sharing options...
guinness Posted February 28, 2014 Share Posted February 28, 2014 Abilio_KID, Don't necro old posts. Create a new support thread in the future please. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now