C# 使用模拟和CopyFileEx从内核DLL复制文件?

C# 使用模拟和CopyFileEx从内核DLL复制文件?,c#,windows,c#-3.0,C#,Windows,C# 3.0,我使用以下代码将文件复制到只有一个X用户可以访问的目录中,我使用的是模拟,但当我使用它时,CopyFileEx不起作用,但我不知道为什么。如果我删除模拟的一部分,它可以正常工作,但我需要用用户X复制它,因为在生产中它必须是这样的 ImpersonationUtils impersonation = new ImpersonationUtils(); var token = impersonation.LogonAsU

我使用以下代码将文件复制到只有一个X用户可以访问的目录中,我使用的是模拟,但当我使用它时,CopyFileEx不起作用,但我不知道为什么。如果我删除模拟的一部分,它可以正常工作,但我需要用用户X复制它,因为在生产中它必须是这样的

                        ImpersonationUtils impersonation = new ImpersonationUtils();
                var token = impersonation.LogonAsUser("User", "Domain", "pwd");

                if (!IntPtr.Equals(token, IntPtr.Zero))
                {
                    System.Security.Principal.WindowsImpersonationContext impersonatedUser = null;
                    var newIdentity = new System.Security.Principal.WindowsIdentity(token);
                    impersonatedUser = newIdentity.Impersonate();

                    bool result = CopyFileEx(filename, tempFilepath, new CopyProgressRoutine(this.CopyProgressHandler), IntPtr.Zero, cancelp, 0);

                    if (impersonatedUser != null)
                        impersonatedUser.Undo();

                    impersonation.LogonAsUserEnd(token);
                }

这是我以前编写的一个类,用于在
模拟
下进行操作, 查看如何在
DoWorkUnderImpersonation()中创建令牌
使用
advapi32.dll的
LogonUser()
的凭据和所需常量

所需的操作在
DoWork()方法中进行,请将复制文件逻辑添加到该方法中。
从外部调用静态方法
DoWorkUnderImpersonation()

// Implementation of the Impersonation class
Impersonation.DoWorkUnderImpersonation("DOMAIN", "USER", "PASSWORD");


public static class Impersonation
{
    // obtains user token
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
        int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    // closes open handes returned by LogonUser
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    public static void DoWorkUnderImpersonation(string _domain, string _userName, string _password)
    {
        //elevate privileges before doing file copy to handle domain security
        WindowsImpersonationContext impersonationContext = null;
        IntPtr userHandle = IntPtr.Zero;
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_LOGON_INTERACTIVE = 2;
        string domain = _domain;
        string user = _userName;
        string password = _password;

        try
        {
            Debug.WriteLine("windows identify before impersonation: " + WindowsIdentity.GetCurrent().Name);

            // if domain name was blank, assume local machine
            if (domain == "")
                domain = System.Environment.MachineName;

            // Call LogonUser to get a token for the user
            bool loggedOn = LogonUser(user,
                                        domain,
                                        password,
                                        LOGON32_LOGON_INTERACTIVE,
                                        LOGON32_PROVIDER_DEFAULT,
                                        ref userHandle);

            if (!loggedOn)
            {
                Debug.WriteLine("Exception impersonating user, error code: " + Marshal.GetLastWin32Error());
                return;
            }

            // Begin impersonating the user
            using (impersonationContext = WindowsIdentity.Impersonate(userHandle))
            {
                Debug.WriteLine("Main() windows identify after impersonation: " + WindowsIdentity.GetCurrent().Name);
                //run the program with elevated privileges (like file copying from a domain server)
                DoWork();
            }

        }
        catch (Exception ex)
        {
            Console.Write("Exception impersonating user: " + ex.Message);
        }
        finally
        {
            // Clean up
            if (impersonationContext != null)
            {
                impersonationContext.Undo();
            }

            if (userHandle != IntPtr.Zero)
            {
                CloseHandle(userHandle);
            }
        }
    }


    private static void DoWork()
    {
        try
        {
            // MAKE YOUR REQUIRED TASK HERE UNDER IMPERSONATION
        }
        catch (Exception ex)
        {
            Console.Write("error in Impersonation.DoWork() executing a task: " + ex.Message);
        }

    }
}
我删除了你的C#4标记,因为声明上面的代码将使用C#语言版本3和C#语言版本4进行编译没有多大意义。因为C#3是最小的公分母,所以我留下了这个标签。我还删除了winforms标记,因为这里的代码中似乎没有与UI相关的内容。