2011-11-17 56 views
10

Estoy construyendo un programa de consola .net C# para implementar el archivo en un servidor compartido de archivos de Windows (carpeta que se está compartiendo). El camino es :: \\192.168.0.76\htdocs\publicCopiar archivos a través de la red mediante el uso compartido de archivos, autenticación de usuario

en el funcionamiento que estoy recibiendo el error:

[09:35:29]: [Step 1/3] Unhandled Exception: System.UnauthorizedAccessException: Access to the path '\\192.168.0.76\htdocs\public' is denied. 
[09:35:29]: [Step 1/3] at DeployFileShare.Program.CopyDir(String source, String dest, String[] exclude, Boolean overwrite) 
[09:35:29]: [Step 1/3] at DeployFileShare.Program.Deploy(String num, String source) 
[09:35:29]: [Step 1/3] at DeployFileShare.Program.Main(String[] args) 
[09:35:29]: [Step 1/3] Process exited with code -532459699 

creo que es necesario para autenticar a mí mismo. Me he encontrado con esto:

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); 
WindowsIdentity idnt = new WindowsIdentity(username, password); 
WindowsImpersonationContext context = idnt.Impersonate(); 

También he intentado:

AppDomain.CreateDomain("192.168.0.76").SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); 
WindowsIdentity idnt = new WindowsIdentity("user", "pass"); 
WindowsImpersonationContext context = idnt.Impersonate(); 

No estoy seguro de cómo usarlo. Cuando ejecuto la aplicación consigo:

C:\Users\Administrator>DeployFileShare 1 R:\BuildOutput\_PublishedWebsites\Web 2 
1 
Deploy Started Web, version 21 
-- Deploy Prepared 
-- Deploying to 1 

Unhandled Exception: System.Security.SecurityException: There are currently no l 
ogon servers available to service the logon request. 

    at System.Security.Principal.WindowsIdentity.KerbS4ULogon(String upn) 
    at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName, 
String type) 
    at DeployFileShare.Program.Authenticate(String server) 
    at DeployFileShare.Program.Deploy(String num, String source) 
    at DeployFileShare.Program.Main(String[] args) 
The Zone of the assembly that failed was: 
MyComputer 

Aquí es el código básico:

static void Main() 
{ 
Copy(); 
} 
static void Copy() 
{ 
AppDomain.CreateDomain(GetServerInfo(server, "server")).SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); 
      WindowsIdentity idnt = new WindowsIdentity(GetServerInfo(server, "user"), GetServerInfo(server, "pass")); 
      WindowsImpersonationContext context = idnt.Impersonate(); 
string source = "C:\\someDir"; 
string dest = "\\192.168.0.76\shareFolder" 
string[] sourceFiles = Directory.GetFiles(source, "*", SearchOption.AllDirectories); 
      foreach (string file in sourceFiles) 
      { 
       string local = file.Replace(source, ""); 
       if (exclude.Contains(local)) 
        continue; 
       if (!Directory.Exists(Path.GetDirectoryName(dest + "\\" + local))) 
        Directory.CreateDirectory(Path.GetDirectoryName(dest + "\\" + local)); 
       File.Copy(file, dest + "\\" + local, overwrite); 
       Console.WriteLine("-- -- [copied] {0} -> {1}", file, dest + "\\" + local); 
      } 
} 

El sistema de copia de código en el bucle de obras, que he probado en mi sistema local.

Si alguien sabe cómo debo usar WindowsIdentity y WindowsIdentity para que esto funcione, por favor, infórmeme. He estado buscando y la documentación de Windows no ayuda mucho.

Básicamente, ¿cómo puedo copiar a un directorio remoto que se comparte iniciando sesión en el sistema?

+1

Es posible que desee considerar el uso de Powershell para esto. A continuación, simplemente puede utilizar net * * 192.68.9.76 \/USER: SomeUser antes de hacer la copia (para lo cual usaría Robocopy.exe ...) –

+0

@JamesJohnson Estoy usando la IP porque estamos trabajando con VMware y hacer que la máquina ejecute este programa bajo un dominio diferente bajo VMware. Entonces el nombre de la computadora no funciona. –

+0

Creo que hay una manera más universal: http://stackoverflow.com/questions/295538/how-to-provide-user-name-and-password-when-connecting-to-a-network-share/39540451# 39540451 –

Respuesta

5

VB pero fácilmente traducido a C#. Hacer esto antes de su copia:

Private Sub Open_Remote_Connection(ByVal strComputer As String, ByVal strUserName As String, ByVal strPassword As String) 
    Dim ProcessStartInfo As New System.Diagnostics.ProcessStartInfo 
    ProcessStartInfo.FileName = "net" 
    ProcessStartInfo.Arguments = "use \\" & strComputer & "\c$ /USER:" & strUsername & " " & strPassword 
    ProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden 
    System.Diagnostics.Process.Start(ProcessStartInfo) 
    System.Threading.Thread.Sleep(2000) 
End Sub 
5

Si desea autenticar a un equipo remoto con el fin de mover un archivo, puede utilizar la función de LogonUser y WindowsIdentity para hacerse pasar por el usuario.

/// <summary> 
/// Exécute une fonction en empruntant les credentials 
/// </summary> 
private T ApplyCredentials<T>(Func<T> func) 
{ 
    IntPtr token; 

    if (!LogonUser(
     _credentials.UserName, 
     _credentials.Domain, 
     _credentials.Password, 
     LOGON32_LOGON_INTERACTIVE, 
     LOGON32_PROVIDER_DEFAULT, 
     out token)) 
    { 
     Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); 
    } 

    try 
    { 
     // On doit être impersonifié seulement le temps d'ouvrir le handle. 
     using (var identity = new WindowsIdentity(token)) 
     using (var context = identity.Impersonate()) 
     { 
      return func(); 
     } 
    } 
    finally 
    { 
     CloseHandle(token); 
    } 
} 

// ... 

if (_credentials != null) 
{ 
    return this.ApplyCredentials(() => File.Open(path, mode, access, share)); 
} 

return File.Open(path, mode, access, share); 
Cuestiones relacionadas