[[https://www.revelation.com/|Sign up on the Revelation Software website to have access to the most current content, and to be able to ask questions and get answers from the Revelation community]] ==== List Current Users (AREV Specific) ==== === At 17 JAN 2006 04:53:41AM Paul Cummins wrote: === {{tag>"AREV Specific"}} Is there any way I can find out who the current users are? I currently have a problem with the error "too many Users" where there is a 6 user licence but less than 6 are logged in. Someone's terminal is still logged as a current user! ---- === At 17 JAN 2006 12:13PM Matt Sorrell wrote: === Are you using a networking product? If you are on a NetWare server and using the NLM, then the utility NLM_STATS will show you all of the currently logged-in users. To my knowledge, such a utility does not exist for the Windows Service. However, the server admins should be able to provide you with a list of users that have any REV*.* files opened. If a user has an REV*.* file opened or locked, then the system thinks they are logged in. Finally, you could implement your own login tracking as we have done. Basically, all of the logon scripts write a record to a table, using the @ID of the station. Then, we have overriden the OFF command. First, it deletes the @ID record from our table and then executes the internal OFF command. The one downside to this is the table is not updated correctly if a user merely kills their session without executing the OFF command. Matt Sorrell ---- === At 20 JAN 2006 06:54AM Bruce Nuriootpa wrote: === If AREV is the *only* command.com / NTVDM based process on each workstation, create a network path (accessible by all users with read, write, delete, scan and create privileges) called \arev\monitor on the same drive as AREV.EXE on the network. Get Visual Basic 6, open a new project, slap a timer control on the form, and attach the following code. Then compile and put the VB6 executable in each user's startup group. The usernames of people who are using AREV will appear as files in the \arev\monitor path. And they won't even know there's a process active on their workstation. [size=-1] Option Explicit Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassname As String, ByVal lpWindowName As String) As Long Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal Hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal Hwnd As Long, ByVal lpClassname As String, ByVal nMaxCount As Long) As Long Private Declare Function ShowWindow Lib "user32" (ByVal Hwnd As Long, ByVal nCmdShow As Long) As Long Private Declare Function OemKeyScan Lib "user32" (ByVal wOemChar As Integer) As Long Private Declare Function CharToOem Lib "user32" Alias "CharToOemA" (ByVal lpszSrc As String, ByVal lpszDst As String) As Long Private Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" (ByVal cChar As Byte) As Integer Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long) Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Function SetFocusAPI Lib "user32" Alias "SetFocus" (ByVal Hwnd As Long) Private Declare Function SetForegroundWindow Lib "user32" (ByVal Hwnd As Long) Private Declare Function GetForegroundWindow Lib "user32" () As Long Private Declare Function apiGetClassName Lib "user32" Alias _ "GetClassNameA" (ByVal Hwnd As Long, _ ByVal lpClassname As String, _ ByVal nMaxCount As Long) As Long Private Declare Function apiGetDesktopWindow Lib "user32" Alias _ "GetDesktopWindow" () As Long Private Declare Function apiGetWindow Lib "user32" Alias _ "GetWindow" (ByVal Hwnd As Long, _ ByVal wCmd As Long) As Long Private Declare Function apiGetWindowLong Lib "user32" Alias _ "GetWindowLongA" (ByVal Hwnd As Long, ByVal _ nIndex As Long) As Long Private Declare Function apiGetWindowText Lib "user32" Alias _ "GetWindowTextA" (ByVal Hwnd As Long, ByVal _ lpString As String, ByVal aint As Long) As Long Private Const mcGWCHILD=5 Private Const mcGWHWNDNEXT=2 Private Const mcGWLSTYLE=(-16) Private Const mcWSVISIBLE=&H10000000 Private Const mconMAXLEN=255 Private Sub Command1_Click() fEnumWindows End Sub Private Sub Form_Load() Timer1.Interval=1000 Form1.Visible=False Form1.Caption=" Me.WindowState=1 End Sub Private Sub Form_Terminate() End Sub Private Sub Form_Unload(Cancel As Integer) FindIE End Sub Private Sub Timer1_Timer() FindIE End Sub Public Sub FindIE() fEnumWindows End Sub Function fEnumWindows() Dim lngx As Long, lngLen As Long Dim lngStyle As Long, strCaption As String Dim Found As Boolean Found=False lngx=apiGetDesktopWindow() '''' 'Return the first child to Desktop lngx=apiGetWindow(lngx, mcGWCHILD) '''' lngx=GetForegroundWindow() Do While Not lngx=0 '''' strCaption=fGetCaption(lngx) If Len(strCaption) ] 0 Then lngStyle=apiGetWindowLong(lngx, mcGWLSTYLE) 'enum visible windows only If lngStyle And mcWSVISIBLE Then Dim Cmd As String Cmd=Trim(Command()) If Cmd=" Then Cmd=ConsoleWindowClass" End If If fGetClassName(lngx)=Cmd Then Found=True End If End If End If lngx=apiGetWindow(lngx, mcGWHWNDNEXT) '''' Loop '''' Dim user, filename As String Dim retval As Double On Error Resume Next If Found=True Then user=Environ("USERNAME") filename=\arev\monitor\" & user Open filename For Output As #1 ' Create file name. Print #1, user ' Output text. Close #1 ' Close file. DoEvents Else user=Environ("USERNAME") filename=\arev\monitor\" & user Kill filename End If Err.Clear End Function Private Function fGetClassName(Hwnd As Long) As String Dim strBuffer As String Dim intCount As Integer strBuffer=String$(mconMAXLEN - 1, 0) intCount=apiGetClassName(Hwnd, strBuffer, mconMAXLEN) If intCount ] 0 Then fGetClassName=Left$(strBuffer, intCount) End If End Function Private Function fGetCaption(Hwnd As Long) As String Dim strBuffer As String Dim intCount As Integer strBuffer=String$(mconMAXLEN - 1, 0) intCount=apiGetWindowText(Hwnd, strBuffer, mconMAXLEN) If intCount ] 0 Then fGetCaption=Left$(strBuffer, intCount) End If End Function '************** Code End *************** ---- === At 21 JAN 2006 07:36PM Hippo wrote: === We use replace background process to 1) to sent messages to users 2) to monitor users activity Of course dead process and process without idle do not differ from this point of view, but most of our users don't run time consuming processes (logons and logoffs are monitored, too). [[https://www.revelation.com/revweb/oecgi4p.php/O4W_HANDOFF?DESTN=O4W_RUN_FORM&INQID=NONWORKS_READ&SUMMARY=1&KEY=6C937027F9B2E495852570F900365A87|View this thread on the forum...]]