2017-01-03 1 views
0

매핑 된 네트워크 드라이브에 폴더 (파일이 아니라 전체 디렉토리가 아님)를 복사하고 같은 이름으로 다른 이름으로 새 버전을 붙여 넣으려고합니다. 위치. 이 코드는 로컬 드라이브를 사용하는 경우 훌륭하게 작동합니다. 그러나 네트워크 드라이브를 사용할 때 인증 오류가 발생합니다.매핑 된 네트워크 드라이브에 폴더를 프로그래밍 방식으로 복사하여 붙여 넣기

DirectoryCopy(@"\\mappedserver\test", @"\\mappedserver\test2", true); 

는 "사용자 이름 또는 암호가 올바르지 유형 'System.IO.IOException'형식의 처리되지 않은 예외가

추가 정보 가 mscorlib.dll에서 발생했습니다."

다음 MSDN 설명서를 사용했습니다 : Link 및 약간 필요에 맞게 수정했습니다.

private static void DirectoryCopy(
    string sourceDirName, string destDirName, bool copySubDirs) 
    { 
     DirectoryInfo dir = new DirectoryInfo(sourceDirName); 
     DirectoryInfo[] dirs = dir.GetDirectories(); 

     // If the source directory does not exist, throw an exception. 
     if (!dir.Exists) 
     { 
      throw new DirectoryNotFoundException(
       "Source directory does not exist or could not be found: " 
       + sourceDirName); 
     } 

     // If the destination directory does not exist, create it. 
     if (!Directory.Exists(destDirName)) 
     { 
      Directory.CreateDirectory(destDirName); 
     } 


     // Get the file contents of the directory to copy. 
     FileInfo[] files = dir.GetFiles(); 

     foreach (FileInfo file in files) 
     { 
      // Create the path to the new copy of the file. 
      string temppath = Path.Combine(destDirName, file.Name); 

      // Copy the file. 
      file.CopyTo(temppath, false); 
     } 

     // If copySubDirs is true, copy the subdirectories. 
     if (copySubDirs) 
     { 

      foreach (DirectoryInfo subdir in dirs) 
      { 
       // Create the subdirectory. 
       string temppath = Path.Combine(destDirName, subdir.Name); 

       // Copy the subdirectories. 
       DirectoryCopy(subdir.FullName, temppath, copySubDirs); 
      } 
     } 
    } 

인기있는 솔루션은 폴더에 대한 전체 액세스 권한을 부여하는 것으로 보이지만 불행히도 이것은 차이를 만들지 않았습니다.

어떻게 사용자 이름과 암호를 제공 할 수 있습니까? 나는 어디서나 응용 프로그램에 관리자 사용자 이름과 암호를 넣고 싶지 않을 것입니다. 어떻게 그렇게 할 수 있습니까? 내 검색이 거의 비어 있습니다.

+1

응용 프로그램을 실행하는 사용자의 사용자 (또는 사용자 컨텍스트)는 무엇입니까? 그 방향으로 조사하기 시작할 것입니다 ... – Bestter

+0

각 사용자는 사용자 계정이 설정되면 매핑 된 네트워크 드라이브에서 파일 및 폴더를 읽고 쓰거나 수정할 수있는 모든 권한을 갖습니다. 나는 관리자로서 VS와 프로그램을 실행하려고 시도했지만 사용자 이름이나 암호를 제공함에 따라 아무 것도하지 않았습니다 (완전히 예상치 못한 것은 아닙니다). – A1raa

답변

1

일단 원격 PC에서 파일을 복사해야했습니다. 이 수업을 찾았습니다 :

public class NetworkShareAccesser : IDisposable 
{ 
    private string _remoteUncName; 
    private string _remoteComputerName; 

    private string RemoteComputerName 
    { 
     get { return _remoteComputerName; } 
     set 
     { 
      _remoteComputerName = value; 
      _remoteUncName = @"\\" + _remoteComputerName; 
     } 
    } 

    private string UserName { get; set; } 
    private string Password { get; set; } 

    #region Consts 

    private const int RESOURCE_CONNECTED = 0x00000001; 
    private const int RESOURCE_GLOBALNET = 0x00000002; 
    private const int RESOURCE_REMEMBERED = 0x00000003; 

    private const int RESOURCETYPE_ANY = 0x00000000; 
    private const int RESOURCETYPE_DISK = 0x00000001; 
    private const int RESOURCETYPE_PRINT = 0x00000002; 

    private const int RESOURCEDISPLAYTYPE_GENERIC = 0x00000000; 
    private const int RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001; 
    private const int RESOURCEDISPLAYTYPE_SERVER = 0x00000002; 
    private const int RESOURCEDISPLAYTYPE_SHARE = 0x00000003; 
    private const int RESOURCEDISPLAYTYPE_FILE = 0x00000004; 
    private const int RESOURCEDISPLAYTYPE_GROUP = 0x00000005; 

    private const int RESOURCEUSAGE_CONNECTABLE = 0x00000001; 
    private const int RESOURCEUSAGE_CONTAINER = 0x00000002; 


    private const int CONNECT_INTERACTIVE = 0x00000008; 
    private const int CONNECT_PROMPT = 0x00000010; 
    private const int CONNECT_REDIRECT = 0x00000080; 
    private const int CONNECT_UPDATE_PROFILE = 0x00000001; 
    private const int CONNECT_COMMANDLINE = 0x00000800; 
    private const int CONNECT_CMD_SAVECRED = 0x00001000; 

    private const int CONNECT_LOCALDRIVE = 0x00000100; 

    #endregion 

    #region Errors 

    private const int NO_ERROR = 0; 

    private const int ERROR_ACCESS_DENIED = 5; 
    private const int ERROR_ALREADY_ASSIGNED = 85; 
    private const int ERROR_BAD_DEVICE = 1200; 
    private const int ERROR_BAD_NET_NAME = 67; 
    private const int ERROR_BAD_PROVIDER = 1204; 
    private const int ERROR_CANCELLED = 1223; 
    private const int ERROR_EXTENDED_ERROR = 1208; 
    private const int ERROR_INVALID_ADDRESS = 487; 
    private const int ERROR_INVALID_PARAMETER = 87; 
    private const int ERROR_INVALID_PASSWORD = 1216; 
    private const int ERROR_MORE_DATA = 234; 
    private const int ERROR_NO_MORE_ITEMS = 259; 
    private const int ERROR_NO_NET_OR_BAD_PATH = 1203; 
    private const int ERROR_NO_NETWORK = 1222; 

    private const int ERROR_BAD_PROFILE = 1206; 
    private const int ERROR_CANNOT_OPEN_PROFILE = 1205; 
    private const int ERROR_DEVICE_IN_USE = 2404; 
    private const int ERROR_NOT_CONNECTED = 2250; 
    private const int ERROR_OPEN_FILES = 2401; 

    #endregion 

    #region PInvoke Signatures 

    [DllImport("Mpr.dll")] 
    private static extern int WNetUseConnection(
     IntPtr hwndOwner, 
     NETRESOURCE lpNetResource, 
     string lpPassword, 
     string lpUserID, 
     int dwFlags, 
     string lpAccessName, 
     string lpBufferSize, 
     string lpResult 
     ); 

    [DllImport("Mpr.dll")] 
    private static extern int WNetCancelConnection2(
     string lpName, 
     int dwFlags, 
     bool fForce 
     ); 

    [StructLayout(LayoutKind.Sequential)] 
    private class NETRESOURCE 
    { 
     public int dwScope = 0; 
     public int dwType = 0; 
     public int dwDisplayType = 0; 
     public int dwUsage = 0; 
     public string lpLocalName = ""; 
     public string lpRemoteName = ""; 
     public string lpComment = ""; 
     public string lpProvider = ""; 
    } 

    #endregion 

    /// <summary> 
    /// Creates a NetworkShareAccesser for the given computer name. The user will be promted to enter credentials 
    /// </summary> 
    /// <param name="remoteComputerName"></param> 
    /// <returns></returns> 
    public static NetworkShareAccesser Access(string remoteComputerName) 
    { 
     return new NetworkShareAccesser(remoteComputerName); 
    } 

    /// <summary> 
    /// Creates a NetworkShareAccesser for the given computer name using the given domain/computer name, username and password 
    /// </summary> 
    /// <param name="remoteComputerName"></param> 
    /// <param name="domainOrComuterName"></param> 
    /// <param name="userName"></param> 
    /// <param name="password"></param> 
    public static NetworkShareAccesser Access(string remoteComputerName, string domainOrComuterName, string userName, string password) 
    { 
     return new NetworkShareAccesser(remoteComputerName, domainOrComuterName + @"\" + userName, password); 
    } 

    /// <summary> 
    /// Creates a NetworkShareAccesser for the given computer name using the given username (format: domainOrComputername\Username) and password 
    /// </summary> 
    /// <param name="remoteComputerName"></param> 
    /// <param name="userName"></param> 
    /// <param name="password"></param> 
    public static NetworkShareAccesser Access(string remoteComputerName, string userName, string password) 
    { 
     return new NetworkShareAccesser(remoteComputerName, userName, password); 
    } 

    private NetworkShareAccesser(string remoteComputerName) 
    { 
     RemoteComputerName = remoteComputerName; 

     ConnectToShare(_remoteUncName, null, null, true); 
    } 

    private NetworkShareAccesser(string remoteComputerName, string userName, string password) 
    { 
     RemoteComputerName = remoteComputerName; 
     UserName = userName; 
     Password = password; 

     ConnectToShare(_remoteUncName, UserName, Password, false); 
    } 

    private void ConnectToShare(string remoteUnc, string username, string password, bool promptUser) 
    { 
     NETRESOURCE nr = new NETRESOURCE 
     { 
      dwType = RESOURCETYPE_DISK, 
      lpRemoteName = remoteUnc 
     }; 

     if (promptUser) 
     { 
      WNetUseConnection(IntPtr.Zero, nr, "", "", CONNECT_INTERACTIVE | CONNECT_PROMPT, null, null, null); 
     } 
     else 
     { 
      WNetUseConnection(IntPtr.Zero, nr, password, username, 0, null, null, null); 
     } 
    } 

    private void DisconnectFromShare(string remoteUnc) 
    { 
     WNetCancelConnection2(remoteUnc, CONNECT_UPDATE_PROFILE, false);   
    } 

    /// <summary> 
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 
    /// </summary> 
    /// <filterpriority>2</filterpriority> 
    public void Dispose() 
    { 
     DisconnectFromShare(_remoteUncName); 
    } 
} 

당신이 자격증을 가지고있을 때 원격 PC에 연결하는 데 도움이됩니다. 당신은 그것을 이렇게 사용할 수 있습니다 :

using (NetworkShareAccesser.Access("1.1.1.1","domain","login","password")) 
{ 
    //Here you have access to remote pc and you can perform your actions 
} 

희망이 당신이 무엇을 찾고있다.

+0

매력처럼 일했습니다! 그게 바로 내가 뭘 찾고 있었는지 - 원격 PC로 자격 증명을 인증하고 선택된 일련의 작업을 수행하는 방법. 그 계급을 어디에서 찾았습니까? 나는 아침의 대부분을 찾고 비어있는 것을 보았다. – A1raa

+0

@ A1raa, 그것이 당신이 찾고 있던 것이었다. 나는 몇 년 전에 그것을 발견했다. 그래서 나는 그것이 어디에 있었는지 아직 두렵지 않다. – Sasha