我正在尝试将文件从共享点复制到 unc 路径。我正在使用以下代码:
var id = new WindowsIdentity("administrator@mysite.com");
var p = new WindowsPrincipal(id);
var wic = id.Impersonate();
File.Move(oldName, newName);
wic.Undo();
旧名称是 C:\test.txt 新名称是\\server\folder\test.txt
我遇到了错误
A specified logon session does not exist. It may already have been terminated.
我该如何去消除这个错误或使用共享点将文件从 A 复制到 B(UNC 路径)。
最佳答案
以下类将允许您通过用户名和密码访问 SMB 共享。在 windows 到 windows 和 windows 到 unix 环境中将文件复制到网络共享时,我一直使用它。这里的好处是您不需要作为用户进行身份验证。本质上,您可以使用仅在目标机器本地的凭据。
class WNetConnection : IDisposable
{
public readonly string RemoteShare;
public WNetConnection( string remoteHost, string remoteUser, string remotePassword )
{
Uri loc;
if( !Uri.TryCreate( remoteHost, UriKind.Absolute, out loc ) || loc.IsUnc == false )
throw new ApplicationException( "Not a valid UNC path: " + remoteHost );
string auth = loc.Host;
string[] segments = loc.Segments;
// expected format is '\\machine\share'
this.RemoteShare = String.Format( @"\\{0}\{1}", auth, segments[1].Trim( '\\', '/' ) );
this.Connect( remoteUser, remotePassword );
}
~WNetConnection()
{
Disconnect();
}
public void Dispose()
{
Disconnect();
GC.SuppressFinalize( this );
}
#region Win32 API...
[StructLayout( LayoutKind.Sequential )]
internal struct NETRESOURCE
{
public int dwScope;
public int dwType;
public int dwDisplayType;
public int dwUsage;
[MarshalAs( UnmanagedType.LPWStr )]
public string lpLocalName;
[MarshalAs( UnmanagedType.LPWStr )]
public string lpRemoteName;
[MarshalAs( UnmanagedType.LPWStr )]
public string lpComment;
[MarshalAs( UnmanagedType.LPWStr )]
public string lpProvider;
}
[DllImport( "mpr.dll", EntryPoint = "WNetAddConnection2W", CharSet = System.Runtime.InteropServices.CharSet.Unicode )]
private static extern int WNetAddConnection2( ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, Int32 dwFlags );
[DllImport( "mpr.dll", EntryPoint = "WNetCancelConnectionW", CharSet = System.Runtime.InteropServices.CharSet.Unicode )]
private static extern int WNetCancelConnection( string lpRemoteName, bool bForce );
private const int RESOURCETYPE_ANY = 0x00000000;
private const int RESOURCETYPE_DISK = 0x00000001;
private const int CONNECT_INTERACTIVE = 0x00000008;
private const int CONNECT_PROMPT = 0x00000010;
private const int NO_ERROR = 0;
void Connect( string remoteUser, string remotePassword )
{
NETRESOURCE ConnInf = new NETRESOURCE();
ConnInf.dwScope = 0;
ConnInf.dwType = RESOURCETYPE_DISK;
ConnInf.dwDisplayType = 0;
ConnInf.dwUsage = 0;
ConnInf.lpRemoteName = this.RemoteShare;
ConnInf.lpLocalName = null;
ConnInf.lpComment = null;
ConnInf.lpProvider = null;
// user must be qualified 'authority\user'
if( remoteUser.IndexOf( '\\' ) < 0 )
remoteUser = String.Format( @"{0}\{1}", new Uri(RemoteShare).Host, remoteUser );
int dwResult = WNetAddConnection2( ref ConnInf, remotePassword, remoteUser, 0 );
if( NO_ERROR != dwResult )
throw new Win32Exception( dwResult );
}
void Disconnect()
{
int dwResult = WNetCancelConnection( this.RemoteShare, true );
if( NO_ERROR != dwResult )
throw new Win32Exception( dwResult );
}
#endregion
}
关于c# - 尝试使用 WindowsIdentity.Impersonate 复制文件时出现 "A specified logon session does not exist. It may already have been terminated.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1363679/