You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.Net:如何获取访问共享文件夹文件的远程计算机IP及名称

问题:获取访问共享文件夹的远程计算机IP与名称

在Windows系统中使用VB.Net的FileSystemWatcher监控网络共享文件夹时,无法获取访问文件的远程计算机IP和名称,当前代码仅能返回本地系统的IP和名称,需解决该问题以获取远程访问者的信息。

现有代码

Imports System.IO
Imports System.Data.OleDb
Public Class Form1

    Private watchers As New List(Of FileSystemWatcher)

    ' Dictionary to store last access times of files
    Private lastAccessTimes As New Dictionary(Of String, DateTime)

    Dim con As New OleDbConnection
    Dim cmd As OleDbCommand
    Dim flag As Integer = 0
    Dim qry As String

    Dim dr As OleDbDataReader

    Dim data As String = "Provider=Microsoft.ACE.OLEDB.12.0;jet OLEDB:Database Password=open;Data Source=" & Application.StartupPath & "\Database.accdb;"

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load


        con.ConnectionString = data

        If con.State = ConnectionState.Closed Then
            con.Open()
        End If

        load_file_path()

        monitoring_access()

    End Sub

    Private Sub load_file_path()

        If con.State = ConnectionState.Closed Then
            con.Open()
        End If

        qry = "select * from Tbl_FilePath where Status=" & "'Active';"
        cmd = New OleDbCommand(qry, con)
        cmd.ExecuteNonQuery()
        dr = cmd.ExecuteReader

        If dr.HasRows Then
            While dr.Read
                DGView2.Rows.Add(dr("File_Path"))
                'Me.ListBox1.Items.Add(dr("File_Path"))
            End While
        End If

        con.Close()

    End Sub

    Private Sub img_settings_Click(sender As Object, e As EventArgs) Handles img_settings.Click
        Settings.ShowDialog()
    End Sub

    Private Sub monitoring_access()


        ' Start monitoring folders
        For Each row As DataGridViewRow In DGView2.Rows
            Dim folderPath As String = row.Cells(0).Value.ToString()
            AddFolderToWatcher(folderPath)
        Next

    End Sub

    Private Sub AddFolderToWatcher(folderPath As String)

        If Directory.Exists(folderPath) Then

            ' Create a new instance of FileSystemWatcher for the specified path
            Dim watcher As New FileSystemWatcher(folderPath)

            AddHandler watcher.Created, AddressOf FileSystemWatcher_Event
            AddHandler watcher.Deleted, AddressOf FileSystemWatcher_Event
            AddHandler watcher.Changed, AddressOf FileSystemWatcher_Event
            AddHandler watcher.Renamed, AddressOf FileSystemWatcher_Event

            watcher.IncludeSubdirectories = True
            watcher.EnableRaisingEvents = True

            watchers.Add(watcher)

        Else
            MessageBox.Show($"Folder does not exist: {folderPath}")
        End If

    End Sub

    Private Sub FileSystemWatcher_Event(sender As Object, e As FileSystemEventArgs)
        ' Handle file system events here
        Dim eventType As String = GetEventType(e.ChangeType)

        Dim operation As String = $"{eventType}"

        'Dim username As String = currentIdentity.Name
        Dim username As String = $"{Environment.UserName}"
        'Dim user As String = GetUsername()
        Dim now As DateTime = DateTime.Now
        Dim GetDateTime As String = now.ToString("dd-MM-yyyy hh:mm:ss tt")
        Dim file_path As String = $"{e.FullPath}"

        'CheckAccessedUser(file_path)

        If Not file_path.Contains("$") Or file_path.Contains("@") Then
            ' The filePath does not contain '$'
            update_DGView1(operation, username, GetDateTime, file_path)
        End If

        'UpdateListBox(message)

        ' Update last access time in the dictionary
        lastAccessTimes(e.FullPath) = File.GetLastAccessTime(e.FullPath)

        ' Check if the file has been accessed (opened or viewed)
        Dim lastAccessTime As DateTime
        If lastAccessTimes.TryGetValue(e.FullPath, lastAccessTime) AndAlso
           File.GetLastAccessTime(e.FullPath) <> lastAccessTime Then
            'message += " - Viewed"
            update_DGView1("Viewed", username, GetDateTime, file_path)
        End If

    End Sub

    Private Function GetEventType(changeType As WatcherChangeTypes) As String
        Select Case changeType
            Case WatcherChangeTypes.Created
                Return "Created"
            Case WatcherChangeTypes.Changed
                Return "Edited"
            Case WatcherChangeTypes.Deleted
                Return "Deleted"
            Case WatcherChangeTypes.Renamed
                Return "Renamed"
            Case Else
                Return "Unknown event"
        End Select

    End Function

    Private Sub update_DGView1(operation As String, user As String, GetDateTime As String, file_path As String)
        If DGView1.InvokeRequired Then
            DGView1.Invoke(Sub() update_DGView1(operation, user, GetDateTime, file_path))
        Else
            ' Your DGView1 update code goes here
            DGView1.Rows.Add(operation, user, GetDateTime, file_path)
        End If

    End Sub

End Class

解决方案

FileSystemWatcher本身不包含远程访问者的身份信息,需要结合Windows系统的日志、共享会话查询或文件审核来实现:

方法1:查询Windows共享会话(Net Session命令)

通过执行net session命令获取当前连接到共享的会话信息,解析结果得到远程计算机名和IP。在VB.Net中可通过Process类执行命令并读取输出:

Private Function GetRemoteSessionInfo() As Dictionary(Of String, String)
    Dim sessionDict As New Dictionary(Of String, String)
    Dim process As New Process()
    process.StartInfo.FileName = "net"
    process.StartInfo.Arguments = "session"
    process.StartInfo.RedirectStandardOutput = True
    process.StartInfo.UseShellExecute = False
    process.StartInfo.CreateNoWindow = True
    process.Start()

    Dim output As String = process.StandardOutput.ReadToEnd()
    process.WaitForExit()

    ' 解析输出,提取计算机名和IP
    Dim lines As String() = output.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
    For i = 2 To lines.Length - 1 ' 跳过前两行表头
        Dim parts As String() = lines(i).Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries)
        If parts.Length >= 3 Then
            Dim computerName As String = parts(0).TrimEnd("\") ' 去除末尾的反斜杠
            Dim ipAddress As String = parts(2)
            sessionDict(computerName) = ipAddress
        End If
    Next
    Return sessionDict
End Function

在FileSystemWatcher的事件触发时,调用此方法,结合事件时间范围匹配对应的会话信息。

方法2:启用文件审核并读取安全日志

  1. 启用文件审核:右键共享文件夹→属性→安全→高级→审核→添加,选择目标用户/组,勾选“读取”“写入”等操作的成功审核规则。
  2. 读取安全日志:在VB.Net中筛选事件ID为4663(文件/对象访问)和4656(句柄创建)的事件,提取远程计算机名和IP:
Imports System.Diagnostics.Eventing.Reader

Private Sub GetRecentAuditLogs(targetFilePath As String, eventTime As DateTime)
    ' 查询指定时间范围内的文件访问日志
    Dim timeFilter As String = $"*[System[TimeCreated[@SystemTime>='{eventTime.AddSeconds(-5).ToString("o")}'] and EventID=4663]]"
    Dim query As New EventLogQuery("Security", PathType.LogName, timeFilter)
    Dim reader As New EventLogReader(query)
    Dim eventRecord As EventRecord = reader.ReadEvent()

    While eventRecord IsNot Nothing
        ' 解析事件中的文件路径
        Dim accessedPath As String = eventRecord.Properties(6).Value.ToString()
        If accessedPath.Equals(targetFilePath, StringComparison.OrdinalIgnoreCase) Then
            ' 获取远程计算机名
            Dim computerName As String = eventRecord.Properties(11).Value.ToString()
            ' 解析计算机名到IP
            Dim ipAddress As String = GetIpFromComputerName(computerName)
            ' 获取访问用户名
            Dim userName As String = eventRecord.Properties(1).Value.ToString()
            
            ' 更新DataGridView
            update_DGView1("Accessed", $"{userName} ({computerName}/{ipAddress})", eventTime.ToString("dd-MM-yyyy hh:mm:ss tt"), targetFilePath)
            Exit While
        End If
        eventRecord = reader.ReadEvent()
    End While
End Sub

Private Function GetIpFromComputerName(computerName As String) As String
    Try
        Dim hostEntry = System.Net.Dns.GetHostEntry(computerName)
        Return hostEntry.AddressList.FirstOrDefault(Function(ip) ip.AddressFamily = System.Net.Sockets.AddressFamily.InterNetwork)?.ToString() OrElse "Unknown"
    Catch ex As Exception
        Return "Unknown"
    End Try
End Function

在FileSystemWatcher事件中调用此方法,传入文件路径和事件触发时间。

方法3:使用WMI查询共享连接

通过WMI的Win32_ServerConnection类获取当前共享会话信息:

Imports System.Management

Private Function GetWmiSessionInfo() As List(Of Tuple(Of String, String, String))
    Dim sessionList As New List(Of Tuple(Of String, String, String))
    Try
        Dim scope As New ManagementScope("\\.\root\CIMV2")
        scope.Connect()
        Dim query As New ObjectQuery("SELECT ComputerName, UserName, ConnectionID FROM Win32_ServerConnection")
        Dim searcher As New ManagementObjectSearcher(scope, query)
        
        For Each mObj As ManagementObject In searcher.Get()
            Dim computerName As String = mObj("ComputerName")?.ToString().TrimEnd("\")
            Dim userName As String = mObj("UserName")?.ToString()
            Dim ipAddress As String = GetIpFromComputerName(computerName)
            sessionList.Add(Tuple.Create(computerName, ipAddress, userName))
        Next
    Catch ex As Exception
        ' 处理权限或连接异常
    End Try
    Return sessionList
End Function

关键注意事项

  • 权限要求:所有方法均需程序以管理员权限运行,否则无法读取系统日志、执行net session或访问WMI。
  • 事件关联:FileSystemWatcher事件与日志/会话信息的时间可能存在微小偏差,建议设置±5秒的时间范围进行匹配。
  • 性能优化:避免高频查询系统资源,可设置定时器批量查询,或在事件触发时仅查询最近的会话/日志。

内容的提问来源于stack exchange,提问作者karthick ks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 10:34:50