2016-04-20 6 views
1

Ich verwende this Impersonator class, um Dateien in ein Verzeichnis mit Zugriffsrechten zu kopieren.Beim Kopieren einer Datei mit dem Imitator wird eine Ausnahme für den nicht autorisierten Zugriff ausgelöst.

public void CopyFile(string sourceFullFileName,string targetFullFileName) 
{ 
    var fileInfo = new FileInfo(sourceFullFileName); 

    try 
    { 
     using (new Impersonator("username", "domain", "pwd")) 
     { 
      // The following code is executed under the impersonated user. 
      fileInfo.CopyTo(targetFullFileName, true); 
     } 
    } 
    catch (IOException) 
    { 
     throw; 
    } 
} 

Dieser Code funktioniert fast perfekt. Das Problem, dem ich gegenüberstehe, ist, wenn der sourceFullFileName eine Datei im Ordner C: \ Benutzer \ Benutzername \ Dokumente ist, wo der ursprüngliche Benutzer Zugriff hat, aber der Imitator nicht.

Die Ausnahme, die ich bekommen habe, während eine Datei aus einer solchen Position zu kopieren versuchen, ist:

Eine nicht behandelte Ausnahme des Typs ‚System.UnauthorizedAccessException‘ ist in mscorlib.dll aufgetreten Zusätzliche Informationen: Zugriff auf den Pfad ' C: \ Benutzer \ Benutzername \ Dokumente \ Datei.txt 'wird abgelehnt.

+0

Hey, das ist meine Klasse, ordentlich :-) –

+0

Wie wäre es mit [Process Monitor] (https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx) zu sehen, was tatsächlich passiert, eine Dateiebene (tatsächlicher Benutzer, tatsächliche Datei, tatsächliche angeforderte Berechtigungen usw.) –

+1

Wow !!! Ich freue mich, Ihnen von Angesicht zu Angesicht zu sagen, dass Sie einen sehr guten Job gemacht haben. Vielen Dank – ehh

Antwort

2

Vor Identitätswechsel hat der aktuelle Benutzer Zugriff auf den Pfad Quelldatei, aber nicht auf den Zieldateipfad.

Nach dem Identitätswechsel ist das Gegenteil der Fall: Der imitierte Benutzer hat Zugriff auf den Zieldateipfad, aber nicht auf den Quelldateipfad.

Wenn die Dateien nicht zu groß sind, wäre meine Idee, die folgenden sein:

public void CopyFile(string sourceFilePath, string destinationFilePath) 
{ 
    var content = File.ReadAllBytes(sourceFilePath); 

    using (new Impersonator("username", "domain", "pwd")) 
    { 
     File.WriteAllBytes(destinationFilePath, content); 
    } 
} 

d.h .:

  1. alle Inhalte Lesen aus der Quelldatei Pfad in ein Byte-Array im Speicher.
  2. Tun Sie den Identitätswechsel.
  3. Schreiben Sie den gesamten Inhalt aus dem Byte-Array im Speicher in den Zieldateipfad.

Methoden und Klassen hier verwendet:

+1

Vielen Dank für Ihre Hilfe – ehh

+0

Vielen Dank für Ihre Unterstützung und Akzeptanz, @ehh! –

1

Dank @Uwe Keim Idee, funktioniert die folgende Lösung perfekt:

public void CopyFile(string sourceFullFileName,string targetFullFileName) 
    { 
     var fileInfo = new FileInfo(sourceFullFileName); 

     using (MemoryStream ms = new MemoryStream()) 
     { 
      using (var file = new FileStream(sourceFullFileName, FileMode.Open, FileAccess.Read)) 
      { 
       byte[] bytes = new byte[file.Length]; 
       file.Read(bytes, 0, (int)file.Length); 
       ms.Write(bytes, 0, (int)file.Length); 
      } 

      using (new Impersonator("username", "domain", "pwd")) 
      { 
       using (var file = new FileStream(targetFullFileName, FileMode.Create, FileAccess.Write)) 
       { 
         byte[] bytes = new byte[ms.Length]; 
         ms.Read(bytes, 0, (int)ms.Length); 
         file.Write(bytes, 0, bytes.Length); 
         ms.Close(); 
       } 
      } 
     } 
    } 
+0

Das sieht seltsam aus. Sie lesen "etwas" zweimal (was ist "ms"?). [Dies war, was ich in meinem Kopf hatte] (http://Stackoverflow.com/a/36743951/107625). Plus: Dieser catch-Block ohne Bedeutung ist nutzlos. Einfach weglassen, um die gleiche Funktionalität und verbesserte Lesbarkeit zu haben. –

+1

Aktualisierte den Code. Entschuldigung, ich vermisse es, den Speicher-Stream-Teil anzuzeigen. – ehh