Переместить файл с помощью ImpersonateLoggedOnUser - PullRequest
3 голосов
/ 01 июня 2010

Я пытаюсь переместить файл, но выдает эту ошибку:

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 ]

3 голосов
/ 01 июня 2010

Сделано успешно с этим кодом.

[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();
    }
}
0 голосов
/ 01 июня 2010

возможны два конфликта: разрешено ли олицетворенное использование удалить исходный файл?

разрешено ли пользователю видеть полный путь к ssDestinationDirectoryPath?

У меня много проблем с перемещением файлов, поэтому попробуйте скопировать, а затем удалить .

...