You can download the UDF from here.
If you want to see it in action, before implementing it in your own production scripts, I have written up a little demo here:
#include <CFS.au3> #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Opt("MustDeclareVars", 1) Opt("TrayAutoPause", 0) Opt("TrayMenuMode", 0) Opt("TrayIconHide", 0) Opt("TrayIconDebug", 0) Global $frm_demo, $frm_demo_status, $frm_demo_quit Global Const $frm_demo_width = 180 Global Const $frm_demo_height = 65 Global Const $MyName = StringLeft(@ScriptName, StringInStr(@ScriptName, ".", 0, -1) - 1) Global Const $logpath = "f:\logs" Global Const $logfile = $logpath & "\CFSdemo.log" Global $SessionID = 0 Global $loop = True _UniqueSession() DirCreate($logpath) _frm_demo_create() main() Func main() Local $lock While $loop _frm_demo_update("Requesting") $lock = _CFS_RequestSemaphore($logfile, 600, 300) If $lock Then _frm_demo_update("Locked") FileWriteLine($logfile, @ComputerName & ":" & $SessionID & " - " & @HOUR & ":" & @MIN & ":" & @SEC & ":" & @MSEC) _frm_demo_update("Releasing") _CFS_ReleaseSemaphore($logfile) _frm_demo_update("") EndIf WEnd EndFunc ;==>main Func _UniqueSession() While _MutexExists($MyName & "-" & $SessionID) $SessionID += 1 WEnd EndFunc ;==>_UniqueSession Func _MutexExists($sOccurenceName) ;thanks to martin for this function Local $ERROR_ALREADY_EXISTS = 183, $handle, $lastError $sOccurenceName = StringReplace($sOccurenceName, "\", "") $handle = DllCall("kernel32.dll", "int", "CreateMutex", "int", 0, "long", 1, "str", $sOccurenceName) $lastError = DllCall("kernel32.dll", "int", "GetLastError") Return $lastError[0] = $ERROR_ALREADY_EXISTS EndFunc ;==>_MutexExists Func _frm_demo_create() $frm_demo = GUICreate("Session " & $SessionID, $frm_demo_width, $frm_demo_height) GUISetOnEvent($GUI_EVENT_CLOSE, "_frm_demo_close") GUISetOnEvent($GUI_EVENT_MINIMIZE, "_frm_demo_minimize") GUISetOnEvent($GUI_EVENT_RESTORE, "_frm_demo_restore") $frm_demo_status = GUICtrlCreateLabel("Initializing", 0, 8, 175, 17) $frm_demo_quit = GUICtrlCreateButton("Quit", 0, 32, 179, 25, $WS_GROUP) GUICtrlSetOnEvent($frm_demo_quit, "_frm_demo_quit_click") GUISetState(@SW_SHOW) _frm_demo_xy() EndFunc ;==>_frm_demo_create Func _frm_demo_quit_click() _frm_demo_close() EndFunc ;==>_frm_demo_quit_click Func _frm_demo_close() GUIDelete($frm_demo) $loop = False EndFunc ;==>_frm_demo_close Func _frm_demo_minimize() EndFunc ;==>_frm_demo_minimize Func _frm_demo_restore() EndFunc ;==>_frm_demo_restore Func _frm_demo_update($update) GUICtrlSetData($frm_demo_status, $update) EndFunc ;==>_frm_demo_update Func _frm_demo_xy() Local $x, $y Local $winsize = WinGetPos("Session " & $SessionID) Local $mx = Int(@DesktopWidth / $winsize[2]) Local $my = Int(@DesktopHeight / $winsize[3]) Local $IDpos = Mod($SessionID, ($mx * $my)) $x = Int($IDpos / $my) * ($winsize[2]) $y = Mod($IDpos, $my) * ($winsize[3]) WinMove("Session " & $SessionID, "", $x, $y) EndFunc ;==>_frm_demo_xy
Make sure to set $logpath and $logfile to a proper location on your PC or network.
Run the demo as many times as you like on a single machine to simulate multiple machines, or run on several machines.
You will be able to see when each session gets its "lock" on the log file. You can also look at the log file itself to see what sessions/machines got access.
NOTE: Because of the way Windows handles multitasking, you will probably see groupings of the same session getting its lock several times before the next one. This is because Windows does not do a very good job of sharing the processor between applications, so one session may make several iterations before Windows pulls processor time away for the next session. You will see a better distribution if you actually use multiple machines rather than simulated machines.







