2016-04-20 12 views
1

Я использую this Impersonator class для копирования файлов в каталог с правами доступа.Копирование файла с использованием имитатора, выброс исключений несанкционированного доступа

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

Этот код работает практически отлично. Проблема, с которой я сталкиваюсь, - это когда sourceFullName является файлом, находящимся в папке C: \ Users \ имя_пользователя \ Документы, где у исходного пользователя есть доступ, но нет имитатора.

Исключение я получаю при попытке скопировать файл из такого расположения является:

Необработанное исключение типа «System.UnauthorizedAccessException» произошло в mscorlib.dll Дополнительная информация: Доступ к пути " C: \ Users \ имя_пользователя \ Documents \ file.txt ".

+0

Эй, это мой класс, аккуратным :-) –

+0

Как об использовании [Process Monitor] (https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx), чтобы увидеть, что на самом деле происходит на файловый уровень (фактический пользователь, фактический файл, фактические разрешения и т. д.) –

+1

Wow !!! Рад сообщить вам, что вы сделали очень хорошую работу. Спасибо – ehh

ответ

2

Перед олицетворения, текущий пользователь имеет доступ к пути исходного файла, но не путь к файлу назначения.

После олицетворения, это совершенно противоположное: у олицетворенного пользователя есть доступ к пути к целевому файлу, но не к пути к исходному файлу.

Если файлы не слишком велики, моя идея была бы следующей:

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

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

т.е .:

  1. Читать все содержимое с пути исходного файла в массив байтов в памяти.
  2. Сделайте олицетворение.
  3. Запишите все содержимое из массива байтов в память в путь к целевому файлу.

Методы и классы, используемые здесь:

  • File.ReadAllBytes читать все в памяти.
  • File.WriteAllBytes написать все из памяти в файл.
  • Impersonator, чтобы временно изменить личность текущего потока.
+1

Благодарим вас за помощь – ehh

+0

Спасибо за ваше продвижение и принятие, @ehh! –

1

Благодаря @Uwe KEIM идее, следующее решение работает отлично:

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

Это выглядит странно. Вы дважды читаете «что-то» (что такое 'ms'?). [Это то, что я имел в виду] (http://stackoverflow.com/a/36743951/107625). Плюс: этот блокирующий блок без какого-либо смысла бесполезен. Просто опустите его, чтобы иметь такую ​​же функциональность и улучшенную читаемость. –

+1

Обновлен код. К сожалению, мне не хватает части потока памяти. – ehh