15

我的软件处理了对文件的多个操作,我现在已经完成了使用System.IO类的相关函数的编写。

我现在需要添加对网络驱动器的支持。使用映射效果很好(虽然Directory.GetFiles有点低,我不知道为什么),但我现在希望能够直接处理\\192.168.0.10\Shared Folder\MyDrive. 除了将驱动器安装到可用驱动器号,使用新生成的路径然后卸载之外,还有什么方法可以处理这种类型的路径?

4

3 回答 3

25

\\您可以直接在路径中使用 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
于 2010-02-28T19:34:55.197 回答
4

使用正常的 UNC 路径(例如您提到的路径)对我来说非常有效。例如:

string[] dirs = Directory.GetDirectories(@"\\192.168.1.116\");

工作得很好。如果没有,您可能有安全问题或其他问题。在这种情况下,您将不得不考虑模仿来解决这个问题。检查以了解有关模拟的更多信息。

于 2010-02-28T19:03:00.070 回答
1

您发布的 UNC 路径 ( \\192.168.0.10\Shared Folder\MyDrive) 很奇怪。没有“驱动器”,这样的共享表现为目录。你会用Directory.GetFiles(@"\\192.168.0.10\Shared Folder").

于 2010-02-28T19:14:06.317 回答