Я использую этот класс Impersonator копировать файлы в каталог с правами доступа.

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

Этот код работает почти идеально. Проблема, с которой я сталкиваюсь, заключается в том, что sourceFullFileName представляет собой файл, расположенный в папке типа C:\Users\username\Documents , к которой исходный пользователь имеет доступ, но не имитатор.

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

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

1
ehh 20 Апр 2016 в 10:19

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 для временного изменения идентификатора текущего потока.
2
Uwe Keim 20 Апр 2016 в 13:34

Благодаря идее @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();
                 }
            }
        }
    }
1
ehh 20 Апр 2016 в 13:17