Ответ 1
Вы можете использовать путь UNC (который начинается с \\
) непосредственно на ваших путях. Однако вы должны учитывать учетные данные для этого соединения, что может быть сложной частью.
Существует несколько подходов:
-
Если удаленная система находится в том же домене или существует доверительная связь между доменами, а пользователь, с которым работает ваша программа, имеет подходящий доступ, он будет "просто работать".
-
Вы можете выложить и выполнить команду
net use
(через программу Windowsnet.exe
), чтобы установить соединение с определенным именем пользователя и паролем. Имейте в виду, что соединение можно использовать любой программой, выполняемой в сеансе пользователя, а не только вашим приложением. Используйте команду/DELETE
, чтобы удалить соединение, когда вы закончите. Типичный синтаксис:net use \\computername\sharename password /USER:domain\username
. -
Вы можете P/Invoke
WNetAddConnection2
выполнить то же самое, что иnet use
, без обхода наnet.exe
. Передавая NULL какlpLocalName
, никакая буква диска не назначается, но имя пользователя и пароль будут применяться к последующим обращениям, выполненным по пути UNC. ФункцияWNetCancelConnection2
может использоваться для разъединения. -
Вы можете P/Invoke
LogonUser
с флагом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