PDA

Vollständige Version anzeigen : In eine MDB eingeloggte User feststellen


Sascha Trowitzsch
18.10.2007, 13:28
Mit dem folgenden Code, der in ein normales Modul zu kopieren ist, kann man ermitteln, wer alles auf eine MDB zugreift, d.h. sie geöffnet hat.
Zurückgegeben werden:
- Username, mit der die DB geöffnet wurde. (Falls sie nicht extra mit einer MDW abgesichert wurde, ist das normalerweise "Admin")
- Rechnername, von dem aus auf die MDB zugegriffen wird
- Name des Users, der auf diesem Rechner eingeloggt ist. Das können eventuell auch mehrere sein. Die Namen werden durch Semikola separiert zurückgegeben.

Das Ganze funktioniert auch für Datenbanken im A2007-Format.
Getestet unter A2000, A2003, A2007 und Windows 2000, Windows XP.
Interessant wäre, ob's auch unter Vista läuft?

Option Compare Database
Option Explicit

'mossSOFT 2007
'Sascha Trowitzsch

Private Const ERROR_MORE_DATA As Long = 234
Private Const ERROR_SUCCESS As Long = 0&
Private Const MAX_PREFERRED_LENGTH As Long = -1

Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000
Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const FILE_FLAG_RANDOM_ACCESS = &H10000000
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Const OPEN_EXISTING = 3
Private Const FILE_BEGIN = 0

Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type

Private Type SecInfo
bMachine(1 To 32) As Byte
bSecurity(1 To 32) As Byte
End Type

Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Type BY_HANDLE_FILE_INFORMATION
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
dwVolumeSerialNumber As Long
nFileSizeHigh As Long
nFileSizeLow As Long
nNumberOfLinks As Long
nFileIndexHigh As Long
nFileIndexLow As Long
End Type

Private Type WKSTA_USER_INFO_1
wkui1_username As Long
wkui1_logon_domain As Long
wkui1_oth_domains As Long
wkui1_logon_server As Long
End Type

Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As _
SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal _
hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function LockFile Lib "kernel32" (ByVal hFile As Long, ByVal dwFileOffsetLow As _
Long, ByVal dwFileOffsetHigh As Long, ByVal nNumberOfBytesToLockLow As Long, ByVal _
nNumberOfBytesToLockHigh As Long) As Long
Private Declare Function UnlockFile Lib "kernel32" (ByVal hFile As Long, ByVal dwFileOffsetLow As _
Long, ByVal dwFileOffsetHigh As Long, ByVal nNumberOfBytesToUnlockLow As Long, ByVal _
nNumberOfBytesToUnlockHigh As Long) As Long
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove _
As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Declare Function lRead Lib "kernel32" Alias "_lread" (ByVal hFile As Long, lpBuffer As Any, _
ByVal wBytes As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, Source As Any, _
ByVal Length As Long)
Private Declare Function NetApiBufferFree Lib "NETAPI32.dll" (ByRef Buffer As Any) As Long
Private Declare Function NetWkstaUserEnum Lib "Netapi32" (ByVal servername As Long, ByVal Level As _
Long, bufptr As Long, ByVal prefmaxlen As Long, entriesread As Long, totalentries As Long, _
resume_handle As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long

'Prozedur zum Testen der Funktion DBUsers
Public Sub TestThisDbUsers()
Dim strPath As String
Dim arrUserList As Variant
Dim n, i As Long

strPath = CurrentDb.Name
arrUserList = DBUsers(strPath)

i = -1
On Error Resume Next
i = UBound(arrUserList, 2)
On Error GoTo 0
If i > -1 Then
For n = 0 To i
Debug.Print "DBUser:", arrUserList(0, n)
Debug.Print "Rechner:", arrUserList(1, n)
Debug.Print "User Login:", arrUserList(2, n)
Debug.Print
Next n
End If
End Sub

'In eine Access-DB eingeloggte User ermitteln
'Gibt ein zwidimensionales String-Array zurück
'Erste Dimension: 0 = Name des Users, der die DB geöffnet hat
' 1 = Rechnername, von dem zugegriffen wird
' 2 = Name des Users, wie er sich auf jenem Rechner eingeloggt hat
'Zweite Dimension: Counter
Public Function DBUsers(ByVal sDBFile As String) As Variant
Dim sLDBFile
Dim mSecurity As SECURITY_ATTRIBUTES
Dim fHandle As Long
Dim LDBInfo As SecInfo
Dim arrUser(254, 2) As String
Dim i As Integer
Dim iOffset As Integer
Dim lBytesRead As Long
Dim lPos As Long
Dim lLock As Long
Dim arrResult() As String
Dim lngRet As Long
Dim nCount As Long
Dim sDB As String
Dim strExt As String

On Error Resume Next
sDB = Dir(sDBFile)

On Error GoTo Fehler
If Len(sDB) = 0 Then
Err.Raise 53, "DBUsers", "Datei nicht gefunden: " & sDBFile
End If

strExt = Mid(sDBFile, InStrRev(sDBFile, "."))
Select Case Left(strExt , 3)
Case ".ac" 'A2007
strExt = ".laccdb"
Case Else
strExt = ".ldb"
End Select
sLDBFile = Mid(sDBFile, 1, InStrRev(sDBFile, ".") - 1) & strExt

On Error Resume Next
sDB = ""
sDB = Dir(sLDBFile)
On Error GoTo Fehler
If Len(sDB) = 0 Then
Err.Raise 53, "DBUsers", "Datenbank " & sDBFile & " scheint nicht geöffnet zu sein." & _
vbCrLf & "(Es existiert keine zugehörige LDB-Datei)"
End If

With mSecurity
.nLength = Len(mSecurity)
.lpSecurityDescriptor = 0
.bInheritHandle = True
End With

fHandle = CreateFile(sLDBFile, _
GENERIC_READ Or GENERIC_WRITE, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
mSecurity, _
OPEN_EXISTING, _
FILE_FLAG_RANDOM_ACCESS Or FILE_ATTRIBUTE_NORMAL, 0)

If fHandle = 0 Then Err.Raise _
vbObjectError + 1, "DBUsers", "LDB kann nicht geöffnet werden"

SetFilePointer fHandle, 0, 0, FILE_BEGIN
iOffset = 0
i = 0

'Texte aus ldb auslesen
Do
lBytesRead = lRead(fHandle, LDBInfo, 64)
If lBytesRead = 0 Then Exit Do
If lBytesRead <> 64 Then Err.Raise _
vbObjectError + 2, "DBUsers", "Fehler beim Lesen der LDB bzw. LACCDB"
arrUser(i, 0) = BytesToString(LDBInfo.bSecurity)
arrUser(i, 1) = BytesToString(LDBInfo.bMachine)
arrUser(i, 2) = iOffset
i = i + 1
iOffset = iOffset + 64
Loop

'Locks ermitteln
i = 0
lPos = &H10000001
ReDim arrResult(2, 0)
Do Until lPos = &H100000FF
lLock = LockFile(fHandle, lPos, 0, 1, 0)
If lLock = 0 Then
iOffset = (lPos And &HFF) * 64 - 64
For i = 0 To 254
If Len(arrUser(i, 2)) = 0 Then Exit For
If arrUser(i, 2) = iOffset Then
ReDim Preserve arrResult(2, nCount)
arrResult(0, nCount) = arrUser(i, 0)
arrResult(1, nCount) = arrUser(i, 1)
arrResult(2, nCount) = GetConnectedUsers(arrResult(1, nCount))
nCount = nCount + 1
End If
Next i
Else
lLock = UnlockFile(fHandle, lPos, 0, 1, 0)
End If
lPos = lPos + 1
Loop

DBUsers = arrResult

Ende:
If fHandle > 0 Then CloseHandle (fHandle)
Exit Function

Fehler:
MsgBox Err.Description, vbCritical
DBUsers = Null
Resume Ende
End Function

'Usernamen ermitteln, die auf einem Rechner eingeloggt sind
'Mehrere User werden semikolonsepariert
'Bsp.: ? GetConnectedUsers("\\Zentralserver")
Public Function GetConnectedUsers(Optional sMachineName As String) As String
Dim lPtrBuf As Long
Dim lpServerName As Long
Dim lRead As Long
Dim lSum As Long
Dim lResume As Long
Dim nStatus As Long
Dim nSize As Long
Dim i As Long
Dim TUserInfo As WKSTA_USER_INFO_1
Dim strUsers As String
Dim strUser As String

On Error GoTo Fehler

lpServerName = StrPtr(sMachineName)
nSize = LenB(TUserInfo)
Do
nStatus = NetWkstaUserEnum(lpServerName, _
1, _
lPtrBuf, _
MAX_PREFERRED_LENGTH, _
lRead, _
lSum, _
lResume)
If nStatus = ERROR_SUCCESS Or nStatus = ERROR_MORE_DATA Then
If lRead > 0 Then
For i = 0 To lRead - 1
CopyMemory TUserInfo, ByVal lPtrBuf + (nSize * i), nSize
strUser = PointerToStringW(TUserInfo.wkui1_username)
'Administrative User ausfiltern
If InStr(1, strUser, "$") = 0 Then
strUsers = strUsers & strUser & "/"
End If
Next
End If
If Len(strUsers) > 0 Then GetConnectedUsers = Left(strUsers, Len(strUsers) - 1)
Else
Err.Raise nStatus, "GetConnectedUsers", "Netzwerkzugriff scheiterte"
End If
Loop While nStatus = ERROR_MORE_DATA

Ende:
If lPtrBuf <> 0 Then NetApiBufferFree lPtrBuf
Exit Function

Fehler:
' MsgBox Err.Description, vbCritical, "GetConnectedUsers"
Debug.Print "Fehler in Prozedur GetConnectedUsers für '" & _
sMachineName & "': " & Err.Description
Resume Ende
End Function


'--- Hilfsfunktionen -------------------------------------------

Private Function BytesToString(arrBytes() As Byte) As String
Dim sTemp As String
sTemp = StrConv(arrBytes(), vbUnicode)
BytesToString = Left$(sTemp, (InStr(1, sTemp, Chr(0))) - 1)
End Function

Private Function PointerToStringW(lpString As Long) As String
Dim buff() As Byte
Dim nSize As Long

If lpString Then
nSize = lstrlenW(lpString) * 2
If nSize > 0 Then
ReDim buff(0 To (nSize - 1)) As Byte
CopyMemory buff(0), ByVal lpString, nSize
PointerToStringW = buff
End If
End If

End Function


Ciao, Sascha

Sascha Trowitzsch
18.10.2007, 13:29
Zum Testen einfach im VBA-Direktfenster eingeben:

? TestThisDbUsers

Ciao, Sascha

bofspb
18.10.2007, 13:54
Hallo!

Dim ***t As String

Was bedeutet das? Zumindest bei mir (AXP, WINXP PRO SP2) markiert der Editor diese Stellen in Rot und kann damit nix anfangen.

Sascha Trowitzsch
18.10.2007, 14:01
Zum Kuckuck mit dem automatischen Zensieren!
Rate mal, was die *** bedeuten könnten? ;) Es ist ein böses, böses Wort, das die Forensoftware einfach ersetzt.

Ok, hab den Code jetzt oben so angepasst, dass keine Sternchem mehr escheinen.

Thanx
Gruß, SAscha

bofspb
18.10.2007, 14:11
Rate mal, was die *** bedeuten könnten

:( Bin bei bösen Worten nicht so bewandert... :grins:

Nachtrag: Der Direktbereich mag keine Subs ;)

Sascha Trowitzsch
18.10.2007, 14:42
TestThisDbUsers

ohne

?

uwek
18.10.2007, 23:03
Hallo Sascha,

Interessant wäre, ob's auch unter Vista läuft?

Zumindest bei mir Vista Ultimate A03 SP3 :top:

Sascha Trowitzsch
18.10.2007, 23:39
Thanx Uwe!
Sind ja eigentlich auch nur Allerweltsfunktionen im Modul, aber man weiß ja nie unter Vista...

Ciao, Sascha

Konrad Lepping
17.01.2008, 21:00
Hallo Sascha und natürlich auch alle anderen Accessfüchse,
ich möchte den Code in einem Frm mit einem Button ausführen. Da brauche ich noch etwas HILFE.

Kann ich mit dem Code auch die BE User ermitteln, oder muss ich den Code in ein Modul der BE kopieren und dann im BE ein Frm erstellen.

Danke

uwek
17.01.2008, 21:12
Hallo Konrad,

ich bin zwar nicht Sascha.. ;)

Public Sub TestThisDbUsers()
Dim strPath As String
Dim arrUserList As Variant
Dim n, i As Long

strPath = CurrentDb.Name
arrUserList = DBUsers(strPath)

Du musst halt strPath an deine Bedürfnisse anpassen oder gleich in den Prozeduraufruf stellen.

Public Sub TestThisBackEndUsers(strPath As String)
Dim arrUserList As Variant
Dim n, i As Long

arrUserList = DBUsers(strPath)

Konrad Lepping
17.01.2008, 21:37
Uwe, aber halt auch ein Accessfuchs ;)

Tja, VBA lange Rede kurzer Sinn, nicht mein Ding.

Wenn du so freundlich wärest und ein kleines Bsp anhängst, das ich dann für mich anpasse?

nur wen es nicht zuviel Arbeit ist.

thx

uwek
17.01.2008, 23:02
Hallo Konrad,

anbei mal ein kl. Bsp.

Konrad Lepping
18.01.2008, 17:42
Hallo Uwe,
ich sage einfach mal Danke. Habe es in meiner DB eingebaut und muss sagen:

FUNKTINIERT SUPER!

Nochmals vielen Dank:)

uwek
18.01.2008, 17:48
Freut mich..

kgaston
29.01.2008, 10:35
Hallo Forums Gemeinde,

das Code-Bsp. bzw das Bsp. von uwek funktioniert bei mir nur bedingt.

D.h. bei einigen bekomme ich alles angezeigt den RechnerName und die UserId.
Bei einigen wird nur der RechnerName angezeigt.

Im Direkt-Fenster der VBA Umgebung bekomme ich folgende Fehlermeldung angezeigt.

Fehler in Prozedur GetConnectedUsers für 'RachnerName': Netzwerkzugriff scheiterte


Netzwerkzugriff :confused:

Die Benutzer melden sich doch alle an der gleichen Domain an.
==> Was wäre wenn sich die Benutzer an verschieden Domains anmelden, weil mehrer Unternehmen zusammen Arbeiten.

Weiß jemand Rat oder Tipp was die Problematik ist.

Danke im Voraus

kgaston
11.02.2008, 12:38
ontop

Sascha Trowitzsch
11.02.2008, 16:02
Häng mal bitte an die Fehlerausgabe die Fehlernummer ran:

Debug.Print "Fehler in Prozedur GetConnectedUsers für '" & _
sMachineName & "': " & Err.Description & "; Fehlernummer:" & Err.Number

Welche wird bei den Problemkandidaten generiert?

Hast du auf dem lokalen Rechner getestet, oder ist das Backend auf einem Server?
Falls ja: Läuft da Active Directory?

Das Problem ist jedenfalls die API-Funktion NetWkstaUserEnum, die einen Fehlercode zurückgibt. (Siehe auch http://msdn2.microsoft.com/en-us/library/aa370669(VS.85).aspx bzw. http://vbnet.mvps.org/index.html?code/network/netwkstauserenum.htm ) Und deren Verhalten hängt von der Konfiguration des angesprochenen Rechners/Servers ab.

Weiterer Vorschlag: Baue in diese Funktion noch die zwei Zeilen ein:
Public Function GetConnectedUsers(Optional sMachineName As String) As String
...
On Error Goto Fehler
If Len(sMachineName) = 0 Then Exit Function
If Left(sMachineName, 2) <> "\\" Then sMachineName = "\\" & sMachineName
...


Ciao, Sascha

Sascha Trowitzsch
16.02.2008, 12:56
Warum sollte das "on top", lieber kgaston?

Crady
20.02.2008, 19:18
Sascha, Uwe!

Respekt! Sehr hilfreiche Funktion! hat bei meinem kleinen Heimnetzwerk funktioniert! Werde es heute Nacht mal in der Firma testen...

Zwei fragen ergeben sich noch (Access, blutiger Anfänger): Was muss in jedes FE rein, damit es funktioniert? Oder reicht es ein "Admin" FE zu erstellen und nur im BE die entsprechende Tabelle zu erstellen?

Wenn alles wie gewünscht bei unsere Server / Client Konfiguration funktioniert wäre es schön, wenn man jedem angemeldeten Mitarbeiter per Netsend oder so eine Nachricht schicken könnte: "Bitte sofort aus der DB abmelden, wichtige Wartungsarbeiten"...

Sascha Trowitzsch
20.02.2008, 20:33
Ist mir nicht ganz klar, was du meinst, Crady: Es reicht ein "Admin-FE", wenn du der Admin bist, der die eingeloggten User sehen möchte. Was aber für eine Tabelle im Backend? Das können beliebige sein; der Code erfordert da nichts. Er loggt nur die Zugriffe auf die Datei selbst.

Du baust den Code in eine DB ein, die die User anzeigen soll. Alle anderen FE brauchen nichts. Das BE auch nicht.

BTW: User aus der DB rausschmeißen finde ich grundsätzlich keine so gute Idee. Man weiß nie, bei welchen Aktionen sich die User gerade befinden und wie sehr man den Betriebsablauf stört. Ich würde mich bedanken, wenn ich etwa gerade irgendwelche Unterlagen aus dem Archiv herausgeholt hätte und nun die Daten eingeben möchte, just jetzt jedoch aus der DB geschmissen werde und dann Däumchen drehen darf oder meinen Workflow gezwungenermaßen umstellen muss.
Ich würde ehrlich gesagt erwarten, dass sowas nach Feierabend passiert.
Ich halte es bei meinen Kunden jedenfalls so, dass Wartungsarbeiten am Backend auf die Abendzeit oder auf's Wochenende verschoben werden.

Ciao, Sascha

Crady
22.02.2008, 19:50
Sascha,

Das mit dem "Admin FE" habe ich hinbekommen! Funktioniert bestens - musste nur die Feldgröße auf mehr als 50 Zeichen anpassen, da wie 24 Stunden arbeiten und als angemeldeter User komischerweise alle jemals angemeldeten User auf diesem Computer angezeigt werden.

Zum rausschmeißen: Es geht auch nicht darum, User aus der DB zu schmeißen, sondern darum dass es bei unserem derzeitigen Konstrukt sehr häufig dazu kommt , dass sich das BE verabschiedet und sich neue User nicht anmelden können. Dann muss das BE repariert werden damit alle möglichst schnell weiter arbeiten können.

Da viele Kollegen aber gar keine Ahnung von irgendwelchen PCs haben und mit der Eingabe von Daten schon überfordert sind, reagieren diese Kollegen auch nicht auf die Bitte, die DB kurz zu schließen um das BE wieder zu reparieren, sondern machen ihre Arbeit in Ruhe fertigt und melden sich dann ab - wenn sie es dann nicht wieder vergessen haben.

Daher wäre es schön, wenn man dann per Netsend eine entsprechende Mitteilung an den entsprechenden Computer senden zu können.

Erfahrungsgemäß sind ja leider auch sämtliche Daten die bei einem zerschossenen BE eingegeben werden eh verloren.

(Die Gründe für diese Probleme wurden / werden bereits in anderen Threads behandelt)

kgaston
25.02.2008, 10:23
Err.No: -2147463168
Err.Desc: Automatisierungsfehler

Crady
26.02.2008, 00:56
Sascha,

Lanz Rudolf hat mich auf einen Fehler in Deinem Code hingewiesen:

Public Sub TestThisDbUsers()
Dim strPath As String
Dim arrUserList As Variant
Dim n As Long, i As Long

strPath = CurrentDb.Name
arrUserList = DBUsers(strPath)

i = -1
On Error Resume Next
i = UBound(arrUserList, 2)
On Error GoTo 0
If i > -1 Then
For n = 0 To i
Debug.Print "DBUser:", arrUserList(0, n)
Debug.Print "Rechner:", arrUserList(1, n)
Debug.Print "User Login:", arrUserList(2, n)
Debug.Print
Next n
End If
End Sub

vorher war es Dim n,i As Long sollte dann auch für jede Variable einzeln deklariert werden -habe ich so gelernt...

Sascha Trowitzsch
26.02.2008, 10:48
Nana (Ruedi), ein Fehler ist das aber nicht.
Abgesehen davon, dass die Testprozedur ja nur zum Testen ist und nicht 1:1 in eine echte DB übertragen werden sollte, kann man n auch problemlos als Variant deklarieren, wie es hier implizit mit Dim n, i as long passierte.

@kgaston:
Du hättest gern noch was zu meinen anderen Fragen sagen können.
Dann hätte ich mir die Suche nach der Fehlernummer nämlich ersparen können: Die Nummer ist im Windows-SDK in ADSERR.H deklariert und besagt: "ADS_BAD_PATHNAME".
Das bedeutet, dass bei dir/bei euch das Netzwerk über Active Directory läuft. Und da gibt es nunmal die Einschränkungen zur API-Funktion NetWkstaUserEnum, die im von mir oben unter #17 gelinkten MSDN-Artikel stehen. Es ist eine Berechtigungsfrage auf das Backend-File. We dort ausgeführt, kann man zwar durchaus die Vollberechtigung auf das Backend haben, so dass es zugreifbar ist, die Informations-API-Funktion schlägt aber dennoch wegen nicht passender ACL fehl. Ich zitiere die Passage hier mal:
"Windows Server 2003 and Windows XP: If you call this function on a domain controller that is running Active Directory, access is allowed or denied based on the ACL for the securable object. To enable anonymous access, the user Anonymous must be a member of the "Pre-Windows 2000 compatible access" group. This is because anonymous tokens do not include the Everyone group SID by default. If you call this function on a member server or workstation, all authenticated users can view the information. Anonymous access is also permitted if the RestrictAnonymous policy setting permits anonymous access. If the RestrictAnonymous policy setting does not permit anonymous access, only an administrator can successfully execute the function. Members of the Administrators, and the Server, System and Print Operator local groups can also view information. For more information about restricting anonymous access, see Security Requirements for the Network Management Functions."

Da ist also nichts zu machen, es sei denn, der SysAdmin würde die entspr. ACLs im Active Directory für das Backend-File und/oder dessen Verzeichnis betreffend die fraglichen User anders einstellen.

Ciao, Sascha

TomVision
27.02.2008, 16:18
Ich muss mich auch bedanken..
wirklich sehr praktische Funktion..

TomVision
29.02.2008, 08:08
ich habe das Tool noch ein wenig ergänzt mit einem Dateiauswahldialog..
Dank dazu geht an Günther Kramer und seinen Code -> http://www.ms-office-forum.net/forum/showthread.php?t=40922

Ich habe allerdings den Code genommen der erst ab AXP gültig ist

belanglos
10.06.2008, 09:38
Könnte mir jemand sagen, wie ich den Code ändern müsste, damit mit jedem Aufruf in eine Tabelle "Name", "Rechner" und "Login" sowie Tag und Uhrzeit reingeschrieben werden?

Schonmal vielen Dank!

Blade01
05.11.2009, 17:21
Hallo zusammen,

Finde die Funktion richtig super, wenn sie bei mir auf der Firma auch Funktionieren würde.

1. Übers Direktfenster ausgeführt, schmeist er mir alle User des Terminalservers raus
2. Die Funktion von Uwe geht irgendwie überhaupt nicht bei mir Error 94
3. Die Version von TomVision geht leider bei meinem Access 2000 nicht.
4. Hab auch das Problem

Fehler in Prozedur GetConnectedUsers für '\\SRVDTS05': Netzwerkzugriff scheiterte; Fehlernummer:5


Was kann ich tun?

Würde es auch gerne nutzen

Afk009
12.11.2009, 10:30
wie kann ich das umsetzen, dass ENVIRON("USername") ausgelesen wird bei dem Code, also nicht nur eigen, sonder von allen eingeloggten.
arrUser(i, 1) = BytesToString(LDBInfo.bMachine)
Ich hab ein Problem dass mir nur die Server angezeigt werden, auf denen die Benutzer über Citrix zugreifen, und somit sind die User nicht identdifizierbar.

Sascha Trowitzsch
12.11.2009, 14:43
Leute, wegen den Netzwerk-Usern kann ich nur nochmals auf Beitrag #24 verweisen.
Unter diversen Konfiguationen (AD, Terminal Server) funktioniert nunmal die Funktion GetConnectedUsers nicht korrekt, weil für die eingesetzte API NetWkstaUserEnum bestimmte Bedingungen gelten, die da nicht erfüllt sind. Oder sie bringt nichts - wie im Falle TS -, weil alle User auf dem Server enumeriert werden.
In solchen Fällen muss die Funktion durch eine geeignetere ersetzt werden, die z.B. WMI verwendet.
Ich habe aber gerade weder Zeit, noch besonders Lust, solch eine Ersatzfunktion zu schreiben, zumal sie ja nur eine Beigabe zum eigentlichen Kern der Routine DBUsers ist.
Vielleicht findet sich jemand?

Gruß, Sascha

punkNgrind
29.07.2014, 16:37
Hallo Zusammen und danke schon einmal für das tolle Programm.

Bei der Ausführung habe ich leider ein Problem:

So weit ich den Code über die Test-Prozedur ausprobiere ist alles gut, wenn ich jetzt über ein Button-Ereignis von einem Formular aus die Test-Prozedur ausführe 'hängt' sich MS Access auf.

Und zwar in der Funktion GetConnectedUsers an folgender Stelle:


If lPtrBuf <> 0 Then NetApiBufferFree lPtrBuf


Habt jemand eine Idee wodran das liegen kann!?
Auskommentiert stürzt Access zumindest nicht mehr ab.