复制网络共享驱动器上的文件

时间:2009-09-16 10:41:30

标签: c# authentication network-drive

我有一个网络共享驱动器(“\ serveur \ folder”),我想在其上复制文件。 我可以使用特定用户(“user”/“pass”)在驱动器上写入。 如何使用C#访问共享驱动写入权限?

4 个答案:

答案 0 :(得分:27)

未经测试的代码,但它类似于:

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

// http://pinvoke.net/default.aspx/advapi32/LogonUser.html    
IntPtr token;
LogonUser("username", "domain", "password", LogonType.LOGON32_LOGON_BATCH, LogonProvider.LOGON32_PROVIDER_DEFAULT);

WindowsIdentity identity = new WindowsIdentity(token);

WindowsImpersonationContext context = identity.Impersonate();

try
{
    File.Copy(@"c:\temp\MyFile.txt", @"\\server\folder\Myfile.txt", true);
}
finally
{
    context.Undo();
}

答案 1 :(得分:4)

这是ASP.NET应用程序的一个工作示例。 Original source

private void SendToFileShare(byte[] pdfData, string fileName)
{
    if(pdfData == null)
    {
        throw new ArgumentNullException("pdfData");
    }
    if (string.IsNullOrWhiteSpace(fileName))
    {
        //Assign a unique name because the programmer failed to specify one.
        fileName = Guid.NewGuid().ToString();
    }
    else
    {
        //Should probably replace special characters (windows filenames) with something.                
    }


    string networkShareLocation = @"\\your\network\share\";

    var path = $"{networkShareLocation}{fileName}.pdf";


    //Credentials for the account that has write-access. Probably best to store these in a web.config file.
    var domain = "AB";
    var userID = "Mr";
    var password = "C";


    if (ImpersonateUser(domain, userID, password) == true)
    {
        //write the PDF to the share:
        System.IO.File.WriteAllBytes(path, report);

        undoImpersonation();
    }
    else
    {
        //Could not authenticate account. Something is up.
        //Log or something.
    }
}

/// <summary>
/// Impersonates the given user during the session.
/// </summary>
/// <param name="domain">The domain.</param>
/// <param name="userName">Name of the user.</param>
/// <param name="password">The password.</param>
/// <returns></returns>
private bool ImpersonateUser(string domain, string userName, string password)
{
    WindowsIdentity tempWindowsIdentity;
    IntPtr token = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;

    if (RevertToSelf())
    {
        if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
            LOGON32_PROVIDER_DEFAULT, ref token) != 0)
        {
            if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
            {
                tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                impersonationContext = tempWindowsIdentity.Impersonate();
                if (impersonationContext != null)
                {
                    CloseHandle(token);
                    CloseHandle(tokenDuplicate);
                    return true;
                }
            }
        }
    }
    if (token != IntPtr.Zero)
        CloseHandle(token);
    if (tokenDuplicate != IntPtr.Zero)
        CloseHandle(tokenDuplicate);
    return false;
}

/// <summary>
/// Undoes the current impersonation.
/// </summary>
private void undoImpersonation()
{
    impersonationContext.Undo();
}


#region Impersionation global variables
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;

WindowsImpersonationContext impersonationContext;

[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
    String lpszDomain,
    String lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
    int impersonationLevel,
    ref IntPtr hNewToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
#endregion

答案 2 :(得分:1)

更简单,更现代的方法。在企业网络中为我工作。

 try
{
    bool validLogin = false;
    using (PrincipalContext tempcontext = new PrincipalContext(ContextType.Domain, "domain.company.com", null, ContextOptions.Negotiate))
    {
        try
        {
            validLogin = tempcontext.ValidateCredentials("USERNAME", "PASSWORD", ContextOptions.Negotiate);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    if (validLogin)
    {
        File.Copy(@"C:\folder\filename.txt", @"\\domain\folder\filename.txt", true);
        return true;
    }
    else
    {
        MessageBox.Show("Username or Password is incorrect...", "Login Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return false;
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
    return false;
}

答案 3 :(得分:0)

创建具有写入网络驱动器权限的用户,并在c#中使用模拟以在访问驱动器时使用该用户。