Запуск процесса, чтобы открыть файл Temp PDF и удалить его, когда это будет сделано - PullRequest
0 голосов
/ 25 сентября 2018

Что я пытаюсь получить

У меня есть байт [], содержащий данные документа в формате PDF.Я хочу показать это моему пользователю, временно записав файл на диск и используя Process.Start для запуска программы просмотра PDF.После того, как пользователь просмотрел файл и закрыл его, я хочу удалить его, чтобы не загромождать временную папку пользователя.

Что я получил прямо сейчас

В данный момент мойкод выглядит следующим образом

public WritePdfDataToFile(byte[] pdfData, string tmpFileName)
{
    using (var pdfFileStream = File.OpenWrite(tmpFileName))
    {
        pdfFileStream.Write(pdfData,0,pdfData.Length);
    } 

    var process = Process.Start(tmpFileName);
    process.EnableRaisingEvents = true;
    process.Exited += (o,e) => File.Delete(tmpFileName);
}

Теперь это прекрасно работает, и мой установленный просмотрщик PDF выскакивает, и я вижу свой pdf, и когда я его закрываю, файл исчезает как нужно.

Однако, если у меня уже открыт выбранный просмотрщик PDF, могут произойти две разные вещи.

  1. Process.Start возвращает значение NULL, поскольку файл уже обрабатывается уже запущенным процессом (это задокументировано здесь )

    • Проблема здесь очевидна, процесс нулевой, поэтому я не могу использовать объект для присоединения моего обработчика событий тоже
  2. Process.Start возвращает процесс, который почти сразу же завершается - это то, что происходит локально на моем компьютере, и я могу только предположить, что в программе Acrobat Reader есть некоторый дочерний процесс, обрабатывающий другой файл и помещающий его во вкладку в уже существующемindow.Затем он закрывает этот дочерний процесс и оставляет временный файл открытым в программе чтения Acrobat.

    • Здесь происходит то, что прикрепленное событие Exited преждевременно срабатывает и пытается удалить файл, пока он открыт, вызывая исключение.

Мне кажется, что я исчерпал свои возможности, используя Process.Я не вижу способа справиться с этим.Я не хочу блокировать и ждать завершения процесса, и если процесс нулевой, потому что он уже существует, я не хочу искать процесс по имени, так как я не знаю, какой процесс будет выполнять пользовательская машинаначать обрабатывать файл PDF.

Другой вариант - явное создание FileStream и использование конструктора, позволяющего указать, что файл следует удалять при закрытии потока

using (var pdfStream = new FileStream(tempFileName,FileMode.Create, FileAccess.Write, FileShare.ReadWrite|FileShare.Delete,1024, FileOptions.DeleteOnClose))
{
    pdfFileStream.Write(pdfData,0,pdfData.Length);
    Process.Start(tempFileName);
}

Здесь 2 большие проблемы

  1. Оператор using завершается (и поэтому dispose вызывается в FileStream и файл удаляется) перед запуском процесса, поэтому он говорит, что не может найтифайл.Я мог бы вставить Thread.Sleep после запуска процесса, но перед выходом из области применения using, но тот, который заблокирует поток, и два, кто знает, насколько медленной может быть машина конечного пользователя, так что я действительно не фанат этого.

  2. (по крайней мере, на моем компьютере с Acrobat Reader) файл не откроется, пока мое приложение все еще имеет дескриптор потока

Что мне нужна помощь Точно (пожалуйста)

Любые предложения о том, как я могу сделать это красиво?Я чувствую, что не могу быть единственным, кто попробовал это еще, я не могу найти безопасное, не хакерское предложение нигде.

...