“指定的登录会话不存在。它可能已经被终止。”尝试使用WindowsIdentity.Impersonate复制文件时

时间:2009-09-01 17:33:18

标签: c# .net sharepoint moss wss

我正在尝试将文件从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路径)。

2 个答案:

答案 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
}