使用Process.Start()从本地计算机到文件共享的RoboCopy会抛出访问被拒绝错误

时间:2012-03-26 11:09:38

标签: c#

我有网络文件共享。网络共享具有登录帐户,每当用户将文件复制到目录时,用户将被验证。首先,用户将使用c#中的WindowsImpersonationContext在文件共享中创建目录。创建后目录用户正在将文件copp到networkshare中的目录。

用户可以在网络共享中创建目录,但是当用户通过将文件从本地计算机复制到网络文件共享来启动robocopy时,系统会显示Access denied。我使用相同的用户帐户来模拟to fileshare帐户在fileshare和robocopy中创建目录。

请帮帮我。请找到以下代码。 是否可以在将文件复制到网络文件共享目录时将robocopy作为其他帐户运行或模拟其他用户帐户。

在Network Fileshare中创建目录

public void CreateFolder(string FilePath,string UserName,string DomainName,string Password)
   {
       try
       {

           string path = FilePath;
           bool impersonateResult=impersonateValidUser(UserName, DomainName, Password);
           if (impersonateResult)
           {
               Directory.CreateDirectory(path);
           }

       }
       catch (Exception ex)
       {

           throw ex;  
       }
   }

在Filshare

中创建目录时进行模拟
 public bool impersonateValidUser(String userName, String domain, 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;
   }

的Robocopy:

public void RoboCopy(string strSourceFilePath,string DestinationFilePath,string FileName,string UserName,String DomainName,string Password)
   {
       try
       {


           System.Security.SecureString password = new System.Security.SecureString();
           char[] pass = Password.ToCharArray();
           foreach (char c in pass)
            password.AppendChar(c);
            Process p = new Process();
           p.StartInfo = new ProcessStartInfo();
           p.StartInfo.FileName = "Robocopy.exe";
           p.StartInfo.Arguments = string.Format("\"{0}\"  \"{1}\"  \"{2}\"  \"{3}\"   ", strSourceFilePath, DestinationFilePath, FileName,"/R:2" );
           p.StartInfo.Domain = DomainName;
           p.StartInfo.UserName = UserName;
           p.StartInfo.Password = password;       
           p.StartInfo.UseShellExecute = false; // set this to false so that we can redirect the output
           p.StartInfo.RedirectStandardError = true; 
           p.StartInfo.RedirectStandardOutput = true;
           p.Start();
           string result = p.StandardOutput.ReadToEnd();
           string output = p.StandardOutput.ReadToEnd();
           p.WaitForExit();



       }
       catch (Exception ex)
       {
           // Setting the Error Description in CommonFunctions Class.
             throw ex; 
       }
   }

在进行robocopy时,我使用Fileshare登录帐户将文件从本地计算机复制到Network Filesahre时出现拒绝访问错误。 我能够创建没有任何访问被拒绝错误的目录吗?

1 个答案:

答案 0 :(得分:1)

我做了类似的事情(虽然不使用RoboCopy),对我来说有用的是使用具有所需权限的用户名和密码将源计算机上的驱动器映射到远程计算机。映射驱动器后,您可以复制文件,创建目录等。下面是一些将处理映射的代码:

public class DriveSettings
{
    private enum ResourceScope
    {
        RESOURCE_CONNECTED = 1,
        RESOURCE_GLOBALNET,
        RESOURCE_REMEMBERED,
        RESOURCE_RECENT,
        RESOURCE_CONTEXT
    }
    private enum ResourceType
    {
        RESOURCETYPE_ANY,
        RESOURCETYPE_DISK,
        RESOURCETYPE_PRINT,
        RESOURCETYPE_RESERVED
    }
    private enum ResourceUsage
    {
        RESOURCEUSAGE_CONNECTABLE = 0x00000001,
        RESOURCEUSAGE_CONTAINER = 0x00000002,
        RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
        RESOURCEUSAGE_SIBLING = 0x00000008,
        RESOURCEUSAGE_ATTACHED = 0x00000010
    }
    private enum ResourceDisplayType
    {
        RESOURCEDISPLAYTYPE_GENERIC,
        RESOURCEDISPLAYTYPE_DOMAIN,
        RESOURCEDISPLAYTYPE_SERVER,
        RESOURCEDISPLAYTYPE_SHARE,
        RESOURCEDISPLAYTYPE_FILE,
        RESOURCEDISPLAYTYPE_GROUP,
        RESOURCEDISPLAYTYPE_NETWORK,
        RESOURCEDISPLAYTYPE_ROOT,
        RESOURCEDISPLAYTYPE_SHAREADMIN,
        RESOURCEDISPLAYTYPE_DIRECTORY,
        RESOURCEDISPLAYTYPE_TREE,
        RESOURCEDISPLAYTYPE_NDSCONTAINER
    }
    [StructLayout(LayoutKind.Sequential)]
    private struct NETRESOURCE
    {
        public ResourceScope oResourceScope;
        public ResourceType oResourceType;
        public ResourceDisplayType oDisplayType;
        public ResourceUsage oResourceUsage;
        public string sLocalName;
        public string sRemoteName;
        public string sComments;
        public string sProvider;
    }
    [DllImport("mpr.dll")]
    private static extern int WNetAddConnection2
        (ref NETRESOURCE oNetworkResource, string sPassword,
        string sUserName, int iFlags);

    [DllImport("mpr.dll")]
    private static extern int WNetCancelConnection2
        (string sLocalName, uint iFlags, int iForce);

    public static void MapNetworkDrive(string sDriveLetter, string sNetworkPath, string userName, string password)
    {
        //Checks if the last character is \ as this causes error on mapping a drive.
        if (sNetworkPath.Substring(sNetworkPath.Length - 1, 1) == @"\")
        {
            sNetworkPath = sNetworkPath.Substring(0, sNetworkPath.Length - 1);
        }

        NETRESOURCE oNetworkResource = new NETRESOURCE();
        oNetworkResource.oResourceType = ResourceType.RESOURCETYPE_DISK;
        oNetworkResource.sLocalName = sDriveLetter + ":";
        oNetworkResource.sRemoteName = sNetworkPath;

        //If Drive is already mapped disconnect the current 
        //mapping before adding the new mapping
        if (IsDriveMapped(sDriveLetter))
        {
            DisconnectNetworkDrive(sDriveLetter, true);
        }

        WNetAddConnection2(ref oNetworkResource, password, userName, 0);
    }

    public static int DisconnectNetworkDrive(string sDriveLetter, bool bForceDisconnect)
    {
        if (bForceDisconnect)
        {
            return WNetCancelConnection2(sDriveLetter + ":", 0, 1);
        }
        else
        {
            return WNetCancelConnection2(sDriveLetter + ":", 0, 0);
        }
    }

    public static bool IsDriveMapped(string sDriveLetter)
    {
        string[] DriveList = Environment.GetLogicalDrives();
        for (int i = 0; i < DriveList.Length; i++)
        {
            if (sDriveLetter + ":\\" == DriveList[i].ToString())
            {
                return true;
            }
        }
        return false;
    }
}

然后你可以这样称呼它:

if (!DriveSettings.IsDriveMapped(mapDriveLetter)) // For example: "K"
{
    DriveSettings.MapNetworkDrive(mapDriveLetter, shareName, adminUserName, adminPassword);
}

复制后,断开连接:

if (DriveSettings.IsDriveMapped(mapDriveLetter))
{
    DriveSettings.DisconnectNetworkDrive(mapDriveLetter, true);
}
相关问题