Hallo zusammen,
ich komme leider mit meinem vb.net Programm nicht weiter, deswegen wende ich mich nun an euch.
Ich will ein Programm schreiben, dass mittels FileSystemWatcher einen Ordner überwacht und bei Änderungen diese in ein File protokolliert.
Soweit alles gut, was mir nur Kopfzerbrechen bereitet ist, wie ich herausfinde welcher User das File erstellt/gelöscht/etc hat?
Meine ersten Recherchen im Internet haben bis jetzt ergeben, dass es nicht geht.
Anderweitig habe ich gelesen, dass es mit der netapi32.dll funktionieren sollte.
Leider krieg ich es nicht hin.
Folgendes habe ich:
[highlight=vbnet]
Option Explicit On
Imports System
Imports System.Net
Imports System.IO
Imports System.Security.Principal
Imports System.Runtime.InteropServices
Imports System.Text[/highlight]
...
[highlight=vbnet]
Declare Unicode Function NetFileEnum Lib "netapi32.dll" ( _
ByVal servername As String, _
ByVal basepath As String, _
ByVal username As String, _
ByVal level As Integer, _
ByRef bufptr As IntPtr, _
ByVal prefmaxlen As Integer, _
ByRef entriesread As Integer, _
ByRef totalentries As Integer, _
ByVal resume_handle As IntPtr) As Integer[/highlight]
...
[highlight=vbnet]
Declare Unicode Function NetFileGetInfo Lib "netapi32.dll" ( _
ByVal servername As String, _
ByVal fileid As String, _
ByVal level As Integer, _
ByRef bufptr As IntPtr) As Integer[/highlight]
...
[highlight=vbnet]
Private Function GetFileIdFromPath(ByVal filepath As String) As Integer
Const MAX_PREFERRED_LENGTH As Integer = -1
Dim dwIndex, dwStatus, dwReadEntries, dwTotalEntries As Integer
Dim iPtr, pBuffer As IntPtr
Dim pCurrent As File_Info_3 = New File_Info_3
dwStatus = NetFileEnum(Nothing, filepath, Nothing, 3, pBuffer, MAX_PREFERRED_LENGTH, dwReadEntries, dwTotalEntries, IntPtr.Zero)
If dwStatus = 0 Then
For dwIndex = 0 To dwReadEntries - 1
iPtr = New IntPtr(pBuffer.ToInt32 + (dwIndex * Marshal.SizeOf(pCurrent)))
pCurrent = CType(Marshal.PtrToStructure(iPtr, GetType(FILE_INFO_3)), FILE_INFO_3)
'Dim fileId = pCurrent.fi3_id
NetApiBufferFree(pBuffer)
Return pCurrent.fi3_id
Next
End If
NetApiBufferFree(pBuffer)
Return -1
End Function[/highlight]
...
[highlight=vbnet]
Private Function GetUsernameHandlingFile(ByVal fileId As Integer) As String
Dim defaultUser As String = "Unknown User"
Dim pBuffer_Info As IntPtr = IntPtr.Zero
Dim dwStatus_Info = NetFileGetInfo(Nothing, fileId, 3, pBuffer_Info)
If dwStatus_Info = 0 Then
Dim iPtr_Info As IntPtr = New IntPtr(pBuffer_Info.ToInt32())
Dim pCurrent_Info As File_Info_3 = CType(Marshal.PtrToStructure(iPtr_Info, GetType(File_Info_3)), File_Info_3)
Return pCurrent_Info.fi3_UserName
End If
NetApiBufferFree(pBuffer_Info)
Return defaultUser
End Function[/highlight]
...
[highlight=vbnet]
Private Sub logchange(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
If e.ChangeType = IO.WatcherChangeTypes.Created Then
logtype = "Created"
ElseIf e.ChangeType = IO.WatcherChangeTypes.Changed Then
logtype = "Changed"
ElseIf e.ChangeType = IO.WatcherChangeTypes.Deleted Then
logtype = "Deleted"
End If
logentry = _
"User: " & GetUsernameHandlingFile(GetFileIdFromPath(e.FullPa th))
My.Computer.FileSystem.WriteAllText(log, logentry, append:=True)
End Sub[/highlight]
Testweise lasse ich das Programm auf meinen lokalen PC laufen.
Überwachen lasse ich immer c:\temp
Später soll es dann mal einen Server überwachen.
Hier noch ein bisschen Debugging:
dwstatus ist 0
dwentries ist auch 0 <-- ich glaub hier liegt eben der Fehler
dwtotalentries ist auch 0
dwstatus_info ist immer 2 (von der Function GetUsernameHandlingFile)
ich komme leider mit meinem vb.net Programm nicht weiter, deswegen wende ich mich nun an euch.
Ich will ein Programm schreiben, dass mittels FileSystemWatcher einen Ordner überwacht und bei Änderungen diese in ein File protokolliert.
Soweit alles gut, was mir nur Kopfzerbrechen bereitet ist, wie ich herausfinde welcher User das File erstellt/gelöscht/etc hat?
Meine ersten Recherchen im Internet haben bis jetzt ergeben, dass es nicht geht.
Anderweitig habe ich gelesen, dass es mit der netapi32.dll funktionieren sollte.
Leider krieg ich es nicht hin.
Folgendes habe ich:
[highlight=vbnet]
Option Explicit On
Imports System
Imports System.Net
Imports System.IO
Imports System.Security.Principal
Imports System.Runtime.InteropServices
Imports System.Text[/highlight]
...
[highlight=vbnet]
Declare Unicode Function NetFileEnum Lib "netapi32.dll" ( _
ByVal servername As String, _
ByVal basepath As String, _
ByVal username As String, _
ByVal level As Integer, _
ByRef bufptr As IntPtr, _
ByVal prefmaxlen As Integer, _
ByRef entriesread As Integer, _
ByRef totalentries As Integer, _
ByVal resume_handle As IntPtr) As Integer[/highlight]
...
[highlight=vbnet]
Declare Unicode Function NetFileGetInfo Lib "netapi32.dll" ( _
ByVal servername As String, _
ByVal fileid As String, _
ByVal level As Integer, _
ByRef bufptr As IntPtr) As Integer[/highlight]
...
[highlight=vbnet]
Private Function GetFileIdFromPath(ByVal filepath As String) As Integer
Const MAX_PREFERRED_LENGTH As Integer = -1
Dim dwIndex, dwStatus, dwReadEntries, dwTotalEntries As Integer
Dim iPtr, pBuffer As IntPtr
Dim pCurrent As File_Info_3 = New File_Info_3
dwStatus = NetFileEnum(Nothing, filepath, Nothing, 3, pBuffer, MAX_PREFERRED_LENGTH, dwReadEntries, dwTotalEntries, IntPtr.Zero)
If dwStatus = 0 Then
For dwIndex = 0 To dwReadEntries - 1
iPtr = New IntPtr(pBuffer.ToInt32 + (dwIndex * Marshal.SizeOf(pCurrent)))
pCurrent = CType(Marshal.PtrToStructure(iPtr, GetType(FILE_INFO_3)), FILE_INFO_3)
'Dim fileId = pCurrent.fi3_id
NetApiBufferFree(pBuffer)
Return pCurrent.fi3_id
Next
End If
NetApiBufferFree(pBuffer)
Return -1
End Function[/highlight]
...
[highlight=vbnet]
Private Function GetUsernameHandlingFile(ByVal fileId As Integer) As String
Dim defaultUser As String = "Unknown User"
Dim pBuffer_Info As IntPtr = IntPtr.Zero
Dim dwStatus_Info = NetFileGetInfo(Nothing, fileId, 3, pBuffer_Info)
If dwStatus_Info = 0 Then
Dim iPtr_Info As IntPtr = New IntPtr(pBuffer_Info.ToInt32())
Dim pCurrent_Info As File_Info_3 = CType(Marshal.PtrToStructure(iPtr_Info, GetType(File_Info_3)), File_Info_3)
Return pCurrent_Info.fi3_UserName
End If
NetApiBufferFree(pBuffer_Info)
Return defaultUser
End Function[/highlight]
...
[highlight=vbnet]
Private Sub logchange(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs)
If e.ChangeType = IO.WatcherChangeTypes.Created Then
logtype = "Created"
ElseIf e.ChangeType = IO.WatcherChangeTypes.Changed Then
logtype = "Changed"
ElseIf e.ChangeType = IO.WatcherChangeTypes.Deleted Then
logtype = "Deleted"
End If
logentry = _
"User: " & GetUsernameHandlingFile(GetFileIdFromPath(e.FullPa th))
My.Computer.FileSystem.WriteAllText(log, logentry, append:=True)
End Sub[/highlight]
Testweise lasse ich das Programm auf meinen lokalen PC laufen.
Überwachen lasse ich immer c:\temp
Später soll es dann mal einen Server überwachen.
Hier noch ein bisschen Debugging:
dwstatus ist 0
dwentries ist auch 0 <-- ich glaub hier liegt eben der Fehler
dwtotalentries ist auch 0
dwstatus_info ist immer 2 (von der Function GetUsernameHandlingFile)