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

24

我有一个网络共享驱动器 ("\serveur\folder"),希望复制文件到此处。 我可以使用特定用户("user"/"pass")在此驱动器上写入数据。 如何使用C#访问共享驱动器以具有写入权限?

4个回答

28

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

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
LogonUser 函数的声明在哪里? - Nitin Sawant
1
@Nitin:看到代码里的注释了吗?http://pinvoke.net/default.aspx/advapi32/LogonUser.html。这是一个Win32 API调用。 - Mitch Wheat
@MitchWheat:目前此链接已失效。 - cuongle

8
这是一个ASP.NET应用程序的实际示例。原始来源
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

你为什么要复制这个标记? - Error404

4

更简单和现代的方法。在企业网络中适用。

 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;
}

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接