使用ImpersonateLoggedOnUser移动文件

时间:2010-06-01 13:25:55

标签: c# permissions

我正在尝试移动文件,但是会出现此错误:

  

System.UnauthorizedAccessException:拒绝访问路径。
  在System.IO .__ Error.WinIOError(Int32 errorCode,String maybeFullPath)
  在System.IO .__ Error.WinIOError()
  在System.IO.FileInfo.MoveTo(String destFileName)

要移动文件,我有以下代码:

public void MssFile_Move (string ssPath, string ssDestinationDirectoryPath, string ssDomain, string ssUsername, string ssPassword, out string ssError_message) {
        IntPtr admin_token = IntPtr.Zero;
        ssError_message = "";

        try
        {
            DoImpersonateLoggedOnUser(  ssDomain
                          , ssUsername
                          , ssPassword
                          , out ssError_message
                          , out admin_token);                   


            FileInfo fi = new FileInfo(ssPath);
            //Destination Directory does not exist ?
            if ( !Directory.Exists(Path.GetDirectoryName(ssDestinationDirectoryPath)))
                    Directory.CreateDirectory(Path.GetDirectoryName(
                    ssDestinationDirectoryPath));
            fi.MoveTo (ssDestinationDirectoryPath);

            DoRevertToSelf(ssDomain);

        }
        catch (System.Exception se)
        {
            int ret = Marshal.GetLastWin32Error();
            ssError_message += "Win32Error: " + ret + "\n";
            ssError_message += se.ToString();
        }
        finally
        {
            if (admin_token != IntPtr.Zero)
                CloseHandle(admin_token);
        }                   
    }

冒充我:

[DllImport("advapi32.DLL", SetLastError = true)]
        public static extern int LogonUser(string lpszUsername, string lpszDomain,
            string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
        [DllImport("advapi32.DLL")]
        public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); //handle to token for logged-on user


public void DoImpersonateLoggedOnUser (     string ssDomain
                                            ,   string ssUsername
                                            ,   string ssPassword
                                            ,   out string ssError_message
                                            ,   out IntPtr admin_token)
    {
        IntPtr phToken = IntPtr.Zero;
        admin_token = IntPtr.Zero;
        ssError_message = "";

        if (ssDomain != "")
        {
            if (LogonUser(ssUsername, ssDomain, ssPassword, 9, 0, out phToken) != 0)
            {
                ImpersonateLoggedOnUser(phToken);           
            }
            else
            {
                int nErrorCode = Marshal.GetLastWin32Error();

                ssError_message = "Operation Failed, error: " + nErrorCode;
            }
            admin_token = phToken;
        }           
    }

如果我将文件夹/文件设置为权限所有人,它可以工作,但我不希望这样。我做错了什么?

2 个答案:

答案 0 :(得分:3)

使用此代码成功完成。

[DllImport("advapi32.DLL", SetLastError = true)]
public static extern int LogonUser(
    string lpszUsername, 
    string lpszDomain,
    string lpszPassword, 
    int dwLogonType, 
    int dwLogonProvider, 
    out IntPtr phToken);

[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); //handle to token for logged-on user

[DllImport("advapi32.DLL")]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll")]
public extern static bool CloseHandle(IntPtr hToken);

enum LogonType
{
    Interactive = 2,
    Network = 3,
    Batch = 4,
    Service = 5,
    Unlock = 7,
    NetworkClearText = 8,
    NewCredentials = 9
}

enum LogonProvider
{
     Default = 0,
     WinNT35 = 1,
     WinNT40 = 2,
     WinNT50 = 3
}

int valid = LogonUser(
    ssUsername,
    ssDomain,
    ssPassword,
    (int)LogonType.Interactive,
    (int)LogonProvider.WinNT50,
    out admin_token);

if (valid != 0)
{
    using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(admin_token))
    {
        CloseHandle(admin_token);
        FileInfo fi = new FileInfo(ssPath);

        //Destination Directory does not exist ?
        if (!Directory.Exists(Path.GetDirectoryName(ssDestinationDirectoryPath)))
            Directory.CreateDirectory(Path.GetDirectoryName(ssDestinationDirectoryPath));

        fi.CopyTo(ssDestinationDirectoryPath);
        fi.Delete();
    }
}

答案 1 :(得分:0)

有两种可能的冲突: 是否允许删除源文件?

是否允许用户查看到ssDestinationDirectoryPath的完整路径?

我在文件移动方面遇到了很多麻烦,所以请尝试复制然后删除