更新:我相信我找到了最简单,最一致的方法,方法2和3可能会或可能不会始终如一地发现。
方法1 - 调用网络使用(一致地工作和跨域)
Net Use Command允许您通过命令提示符将凭据存储到共享,并且您可以非常轻松地从.NET调用它。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim proc As New Process
proc.StartInfo.FileName = "net"
proc.StartInfo.UseShellExecute = True
proc.EnableRaisingEvents = False
Dim server As String = "Server"
Dim user As String = "User"
Dim pass As String = "Pass"
If EnsureConnection(server) Then
proc.StartInfo.Arguments = "use \\" & server & "\IPC$ /u:" & server & "\" & user & " " & pass
proc.Start()
End If
End Sub
Function EnsureConnection(server As String)
'Give more or less ping attempts depending on how reliable your connection is.
'I have found that one ping can give false negative easily even on reliable connections
If My.Computer.Network.Ping(server) Then
Return True
ElseIf My.Computer.Network.Ping(server) Then
Return True
Else
Return False
End If
End Function
此方法将凭证存储在计算机上,直到计算机关闭或重新启动,并且用户也将在程序外部进行身份验证。 如果不希望这样,你可以随时使用命令的'/ delete'开关在程序完成后立即将其删除。
方法2 - 使用MPR.DLL中的函数
我最终找到了另一个问题的答案 。 这是对我有用的方法。 这就是它集成到我的项目中的样子:
Imports System.IO
Imports System.Runtime.InteropServices
Public Class Form1
Dim user As String
Dim pass As String
Dim path As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Cursor = Cursors.WaitCursor
user = "UsernameString"
pass = "PasswordString"
path = "\\10.0.15.87\c$"
MPRAuth()
DirSearch(path)
Cursor = Cursors.Default
End Sub
Private Sub MPRAuth()
Dim nr As New NETRESOURCE
nr.dwType = RESOURCETYPE_DISK
nr.lpRemoteName = path
If WNetAddConnection2(nr, pass, user, 0) <> NO_ERROR Then
Throw New Exception("WNetAddConnection2 failed.")
End If
If WNetCancelConnection2(path, 0, True) <> NO_ERROR Then
Throw New Exception("WNetCancelConnection2 failed.")
End If
End Sub
Public Sub DirSearch(ByVal sDir As String)
Try
For Each dir As String In Directory.GetDirectories(sDir)
Try
For Each file In Directory.GetFiles(dir, "*.exe")
MsgBox(file)
Next
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
DirSearch(dir)
Next
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
End Sub
Private Structure NETRESOURCE
Public dwScope As UInteger
Public dwType As UInteger
Public dwDisplayType As UInteger
Public dwUsage As UInteger
Public lpLocalName As String
Public lpRemoteName As String
Public lpComment As String
Public lpProvider As String
End Structure
Private Const NO_ERROR As UInteger = 0
Private Const RESOURCETYPE_DISK As UInteger = 1
Private Shared Function WNetAddConnection2(ByRef lpNetResource As NETRESOURCE, ByVal lpPassword As String, ByVal lpUserName As String, ByVal dwFlags As UInteger) As UInteger
End Function
Private Shared Function WNetCancelConnection2( ByVal lpName As String, ByVal dwFlags As UInteger, ByVal fForce As Boolean) As UInteger
End Function
End Class
方法3 - NetworkCredential和CredentialCache
此方法将ip转换为URI并缓存凭据。 我无法使这个方法适用于与我不同的域上的服务器。
Imports System.Net
Dim builder As New UriBuilder("10.0.15.87")
Dim uri As Uri = builder.Uri
Dim netCred = New NetworkCredential("UsernameString", "PasswordString", "DomainString")
Dim netCache = New CredentialCache()
netCache.Add(uri, "Basic", netCred)
DirSearch("\\10.0.15.87\c$")
方法2与方法2的关系要少得多,只要我尝试连接的服务器与我在同一个域中,它就可以正常工作。 当我尝试连接到不在域上的服务器时,我收到错误“用户名或密码不正确”,这是不正确的,所以我不确定问题出在哪里 - 也许其他人都知道。 到目前为止,对于任何服务器而言,无论是域还是在运行代码之前已经手动对其进行了身份验证,方法2对我来说都是完美无缺的。 希望这有助于他人!