私たちの会社には、UNCが次のような共有ポイントドキュメントサーバーがあります:\\ theserver.ourdomain.com \ rootdirectory
現在、このドライブはローカルコンピューターのZ:\にマップされています。Z:\にアクセスするには、(ログインするたびに)資格情報(この場合は、ログオンに使用したユーザー名とパスワード)を指定して、ルートディレクトリ内のフォルダーとファイルにアクセスする必要があります。
ファイルをSharePointサーバーにコピーする必要がある状況にあります。マップされたネットワークドライブを使用せずにファイルをサーバーにコピーできるようにしたい(パスにZ:\を指定する必要はありません)。GetDirectories()、GetFiles()、IO.File.Copy()などの基本的なIO関数を実行できるように、資格情報を提供するにはどうすればよいですか?
私は次のことを調べましたが、それらを機能させることに失敗しました:
- プレーンテキストのユーザー名とパスワードを指定し、その呼び出しからトークンを取得し、WindowsIdentityクラスの新しいインスタンスを使用してそのユーザーを偽装することによるLogonUserAPI呼び出し。トークンを取得できましたが、なりすましが機能していないようです。アクセス拒否エラーを取得し続けました。
CredUIPromptForCredentials / CredUIPromptForWindowsCredentials API呼び出しですが、これらは、資格情報を入力でき、実際には何もしない、凝ったWindowsUI用であることに気付きました。
<DllImport("advapi32.dll", SetLastError:=True)> _ Private Shared Function LogonUser(lpszUsername As String, lpszDomain As String, _ lpszPassword As String, dwLogonType As Integer, _ dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean End Function <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _ Private Shared Function CloseHandle(handle As IntPtr) As Boolean End Function '// logon types Public Const LOGON32_LOGON_NETWORK As Integer = 3 Public Const LOGON32_LOGON_NEW_CREDENTIALS As Integer = 9 '// logon providers Public Const LOGON32_PROVIDER_WINNT50 As Integer = 3 Public Const LOGON32_PROVIDER_WINNT40 As Integer = 2 Public Const LOGON32_PROVIDER_WINNT35 As Integer = 1 Public Const LOGON32_PROVIDER_DEFAULT As Integer = 0 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Dim token = IntPtr.Zero Dim success = LogonUser("username", "domain", "password", _ LOGON32_LOGON_NEW_CREDENTIALS, _ LOGON32_PROVIDER_DEFAULT, token) If Not success Then Me.RaiseLastWin32Error() End If Using identity = New WindowsIdentity(token) Using impersonated = identity.Impersonate() Try Dim info = New DirectoryInfo("\\theserver.ourdomain.com\rootdirectory\") Dim files = info.GetDirectories() Catch ex As Exception Finally impersonated.Undo() End Try If Not CloseHandle(token) Then Me.RaiseLastWin32Error() End If End Using End Using End Sub Private Sub RaiseLastWin32Error() Dim hr = Marshal.GetLastWin32Error() Dim ex = Marshal.GetExceptionForHR(hr) If ex IsNot Nothing Then Throw ex End If Throw New SystemException(String.Format("Call resulted in error code {0}", hr)) End Sub