* MUTEX.PRG 'Mutually Exclusive Class' prevents AM_CRON from concurrently being run. ... Local oMutex, cformcaptiono ... cformcaptiono= _SCREEN.Caption _Screen.Caption= "" cformcaption= "yourinfo Version 2.11.12" ... oMutex = CREATEOBJECT('Mutex', cformcaption) If oMutex.nMutexError # ERROR_ALREADY_EXISTS _Screen.Caption = cformcaption ...... run your program Else oMutex.DisplayInstance() Endif On Error oMutex = .NULL. Wait Clear _Screen.Caption = cformcaptiono ... Close All Clear All Clear * ... *:) MUTEX.PRG DEFINE CLASS Mutex AS CUSTOM * Author: George Tasker * Date: February 14, 1998 - 11:41 AM * Purpose: Creates a mutex used to determine * whether or not an instance of an * application exists. hMutex = 0 nMutexError = 0 cFormCaption = "" PROCEDURE Init LPARAMETERS pcformcaption DECLARE INTEGER CreateMutex IN Win32API; STRING @lpMutexAttributes,; STRING bInitialOwner,; STRING @lpName DECLARE INTEGER GetLastError IN Win32API LOCAL lcInitOwner, lcname, lcformcaption * So that the mutex name is different * from the caption lcformcaption = pcformcaption lcname = CHRTRAN(pcformcaption, SPACE(1), "") * Simulate a BOOL type equaling TRUE lcInitOwner = CHR(1) WITH This .cFormCaption = lcformcaption .hMutex = CreateMutex(0, lcInitOwner, @lcname) .nMutexError = GetLastError() ENDWITH RETURN ENDPROC PROCEDURE DisplayInstance * This procedure is used to display * the initial instance of the application DECLARE INTEGER FindWindow IN Win32API; STRING @lpClassName, STRING @lpWindowName DECLARE SHORT IsIconic IN Win32API; INTEGER hwnd DECLARE INTEGER ShowWindow IN Win32API; INTEGER hwnd, INTEGER nCmdShow DECLARE SHORT BringWindowToTop IN Win32API; INTEGER hWnd LOCAL lcformcaption, lnhWnd, llicon lcformcaption = This.cFormCaption lnhWnd = FindWindow(0, @lcformcaption) IF NOT EMPTY(lnhWnd) * Make sure it's active = BringWindowToTop(lnhWnd) * Determine if the application * is minimized (an icon) llicon = (IsIconic(lnhWnd) # 0) IF llicon * It's an icon, so restore it = ShowWindow(lnhWnd, 9) ENDIF ELSE * This handles applications with * dynamic title text bars = MESSAGEBOX("You already have an instance" +; " of this application running." + CHR(13) +; CHR(13) + "Please check your task bar", ; 64, "Only One Instance Allowed") ENDIF RETURN ENDPROC PROCEDURE Destroy DECLARE INTEGER WaitForSingleObject IN Win32API; INTEGER hObject, INTEGER dwTimeOut DECLARE SHORT ReleaseMutex IN Win32API; INTEGER hMutex DECLARE SHORT CloseHandle IN Win32API; INTEGER hObject LOCAL lnresult IF This.hMutex # 0 lnresult = WaitForSingleObject(This.hMutex, 50) * 258 = STATUS_TIMEOUT IF lnresult # 258 lnresult = ReleaseMutex(This.hMutex) * 1 equals Boolean TRUE IF lnresult = 1 lnresult = CloseHandle(This.hMutex) ENDIF ENDIF ENDIF CLEAR DLLS RETURN ENDPROC ENDDEFINEA simple way, As for seperate workstations - that will require a login table that can be read shared - and a field for 'userloggedin' and 'userloggedout'