Dot-Net

如何通過通常的 System.IO 類訪問網路驅動器?

  • July 28, 2016

我的軟體處理了對文件的多個操作,我現在已經完成了使用System.IO類的相關函式的編寫。

我現在需要添加對網路驅動器的支持。使用映射效果很好(雖然Directory.GetFiles有點低,我不知道為什麼),但我現在希望能夠直接處理\\192.168.0.10\Shared Folder\MyDrive. 除了將驅動器安裝到可用驅動器號,使用新生成的路徑然後解除安裝之外,還有什麼方法可以處理這種類型的路徑?

\\您可以直接在路徑中使用 UNC 路徑(以 開頭)。但是,您必須考慮此連接的憑據,這可能是棘手的部分。

有幾種方法:

  1. 如果遠端系統在同一個域上或域之間存在信任關係,並且您的程序執行的使用者具有適當的訪問權限,它將“正常工作”。
  2. 您可以脫殼並執行net use命令(通過 Windowsnet.exe程序)以使用特定的使用者名和密碼建立連接。請注意,在使用者會話中執行的任何程序都可以使用連接,而不僅僅是您的應用程序。完成後使用/DELETE命令刪除連接。典型的語法是:net use \\computername\sharename password /USER:domain\username.
  3. 您可以 P/InvokeWNetAddConnection2完成與net use不使用net.exe. 通過將 NULL 作為 傳遞lpLocalName,不分配驅動器號,但使用者名和密碼將應用於通過 UNC 路徑進行的後續訪問。該WNetCancelConnection2功能可用於斷開連接。
  4. LogonUser您可以使用標誌進行P/Invoke ,LOGON32_LOGON_NEW_CREDENTIALS然後進行模擬以將其他遠端憑據添加到您的執行緒。與#2 和#3 不同,對使用者整個會話的影響會更有限。(實際上,這很少有利於眾所周知的WNetAddConnection2解決方案。)

以下是如何WNetAddConnection2從 VB.NET 呼叫的範例。

Private Sub Test()
   Dim nr As New NETRESOURCE
   nr.dwType = RESOURCETYPE_DISK
   nr.lpRemoteName = "\\computer\share"
   If WNetAddConnection2(nr, "password", "user", 0) <> NO_ERROR Then
       Throw New Exception("WNetAddConnection2 failed.")
   End If
   'Code to use connection here.'
   If WNetCancelConnection2("\\computer\share", 0, True) <> NO_ERROR Then
       Throw New Exception("WNetCancelConnection2 failed.")
   End If
End Sub

<StructLayout(LayoutKind.Sequential)> _
Private Structure NETRESOURCE
   Public dwScope As UInteger
   Public dwType As UInteger
   Public dwDisplayType As UInteger
   Public dwUsage As UInteger
   <MarshalAs(UnmanagedType.LPTStr)> _
   Public lpLocalName As String
   <MarshalAs(UnmanagedType.LPTStr)> _
   Public lpRemoteName As String
   <MarshalAs(UnmanagedType.LPTStr)> _
   Public lpComment As String
   <MarshalAs(UnmanagedType.LPTStr)> _
   Public lpProvider As String
End Structure

Private Const NO_ERROR As UInteger = 0
Private Const RESOURCETYPE_DISK As UInteger = 1

<DllImport("mpr.dll", CharSet:=CharSet.Auto)> _
Private Shared Function WNetAddConnection2(ByRef lpNetResource As NETRESOURCE, <[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpPassword As String, <[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpUserName As String, ByVal dwFlags As UInteger) As UInteger
End Function

<DllImport("mpr.dll", CharSet:=CharSet.Auto)> _
Private Shared Function WNetCancelConnection2(<[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpName As String, ByVal dwFlags As UInteger, <MarshalAs(UnmanagedType.Bool)> ByVal fForce As Boolean) As UInteger
End Function

引用自:https://stackoverflow.com/questions/2352197