2011-11-17 6 views
10

Je crée un programme console .NET C# pour déployer le fichier sur un serveur de partage de fichiers Windows (dossier en cours de partage). Le chemin est :: \\192.168.0.76\htdocs\publicCopie de fichiers sur le réseau via un partage de fichiers, authentification de l'utilisateur

En cours d'exécution, je reçois l'erreur:

[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 

Je pense que je dois me authentifier. Je suis venu à travers ceci:

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

J'ai aussi essayé:

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

Je ne sais pas comment l'utiliser. Quand je lance l'application que je reçois:

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 

Voici le code de base:

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

Le code système de copie en boucle pour les travaux de, je l'ai testé sur mon système local.

Si quelqu'un sait comment utiliser WindowsIdentity et WindowsIdentity pour que cela fonctionne, merci de m'éclairer. J'ai regardé autour et la documentation de la fenêtre n'aide pas beaucoup.

Comment puis-je copier un répertoire distant en le connectant au système?

+1

Vous pourriez envisager d'utiliser Powershell pour cela. Vous pouvez alors juste utiliser net * \\ 192.168.9.76 \/USER: SomeUser avant de faire la copie (pour lequel j'utiliserais Robocopy.exe ...) –

+0

@JamesJohnson J'utilise l'IP parce que nous travaillons avec VMware et que la machine exécute ce programme sous un domaine différent sous VMware. Donc, le nom de l'ordinateur ne fonctionne pas. –

+0

Je crois qu'il existe un moyen plus universel: http://stackoverflow.com/questions/295538/how-to-provide-user-name-and-password-when-connecting-to-a-network-share/39540451# 39540451 –

Répondre

5

VB mais facilement traduit en C#. Faites ceci avant votre copie:

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 vous voulez authentifier sur un ordinateur distant afin de déplacer un fichier, vous pouvez utiliser la fonction LogonUser à et WindowsIdentity pour usurper l'identité de votre utilisateur.

/// <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); 
Questions connexes