我正在尝试将文件从sharepoint复制到unc路径。我使用以下代码:
var id = new WindowsIdentity("administrator@mysite.com");
var p = new WindowsPrincipal(id);
var wic = id.Impersonate();
File.Move(oldName, newName);
wic.Undo();
oldname是C:\ test.txt newName是\\ server \ folder \ test.txt
我收到错误
A specified logon session does not exist. It may already have been terminated.
如何使用sharepoint删除此错误或将文件从A复制到B(UNC路径)。
答案 0 :(得分:1)
您实际上并未获取登录令牌以进行模拟。您需要调用LogonUser API以获取有效的登录令牌,您可以使用该令牌来模拟该用户。
有关模拟Windows用户的信息,请参阅this blog entry中的c#代码。您还可以看到this KB article也包含c#代码(以及对.net 1.0问题的重复调用)
答案 1 :(得分:1)
以下类允许您通过用户名和密码访问SMB共享。我在Windows-to-windows和windows-to-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
}