.NET (C#) процессы и Adobe Acrobat
-
19-09-2019 - |
Вопрос
Хорошо, вот сделка ...
У меня есть программа Windows (XP) в .net 2.0 (C#), которая позволяет пользователям переименовать заданный файл .pdf. (Имя файла является «структурно описательным», поскольку оно излагает простую информацию о том, что в самом файле.) В единственной форме программы есть объект Linklabel, который позволяет пользователю открывать сам .pdf, чтобы они могли видеть что они переименовывают.
Хитрость заключается в том, что когда пользователь вносит соответствующие изменения (ы) и нажимает кнопку «Сохранить», я хочу, чтобы окно акробата, показывающее .pdf закрыть, выполняется сохранение, файл «следующий», чтобы быть полученным, и новое окно немедленно Откройте отображение этого следующего файла.
Вот соответствующие фрагменты кода:
private void OpenViewer()
{
// NOTE: pdfView is of type Process, in case you're not familiar with
// Process.Start().
pdfView = System.Diagnostics.Process.Start(lnkFile.Links[0].LinkData.ToString());
}
private bool KillViewer()
{
bool result = (pdfView != null);
if (pdfView != null)
{
pdfView.CloseMainWindow();
pdfView.Close();
pdfView.Dispose();
pdfView = null;
GC.Collect();
// Verify that the lock is available before you return, as returning basically says:
// "Yup, the file's available."
bool locked = false;
StreamWriter sw = null;
do
{
try
{
sw = new StreamWriter(new FileStream(lnkFile.Links[0].LinkData.ToString(), FileMode.Open));
locked = false;
}
catch (Exception)
{
locked = true;
}
} while (locked);
sw.Dispose();
}
return result;
}
private void SomeButtonEvent
{
// Record whether a viewer was open in the first place.
bool viewerActive = KillViewer();
PerformFileLockingMethod();
GetNextFile()
if(viewerActive)
{
OpenViewer();
}
}
Обратите внимание на Killviewer (), что в основном есть цикл с захватом блокировки, чтобы убедиться, что программа не пытается переименовать рабочий файл до тех пор, пока просмотрщик PDF полностью не выпустил блокировку.
Проблема заключается в следующем: иногда все работает прекрасно, а иногда Killviewer разрывается на вызове CloseMainWindow () с InvalidoperationException, Details = «Процесс вышел, поэтому запрошенная информация недоступна». Это было бы довольно просто, если бы не две вещи ...
1: pdfview.hasexited = true
А ТАКЖЕ
2: Проклятый PDF -зритель все еще открыт !!!
Как это возможно? Есть ли команда процесса, которую я должен использовать для обеспечения закрытия окна? К вашему сведению, программа ссылается на то, что ничто не за пределами системы.* Пространства имен или внутренне созданный класс, который также в конечном итоге ссылается только на систему.*.
Спасибо.
Решение 2
После дальнейшего расследования я думаю, что определил, что происходит.
Я не детализировал детали рабочего процесса, потому что я не мог надежно повторить ситуацию. После дальнейших попыток я нашел две надежные ситуации ...
- Нажмите на ссылку несколько раз, а затем нажмите «Сохранить».
- Нажмите на ссылку, закройте окно просмотра и нажмите «Сохранить».
В каждом из этих случаев проблема сводилась к процессу, на который PDFViewer не синхронизировался с тем, что делал пользователь.
Если ссылка нажимала несколько раз, то активный просмотрщик был на процессе, не связанном с процессом PDFViewer, следовательно, казалось бы, невозможной ситуации, подробно описанной выше.
Если ссылка была нажата, а окно было закрыто, переменная PDFViewer останется, оставив процесс с hasexited = true.
Урок «Возьми домой всего этого»: если вы запускаете отдельный процесс от своего основного пользовательского интерфейса, убедитесь, что вы охватываете каждую возможную ситуацию, которая может произойти с внешним процессом.
Для протокола Ник Геррера заслуживает очков за то, что он направил меня к идентификаторам процесса. Это в конечном итоге решило это.
Другие советы
Попробуйте вместо этого ..
pdfView.Kill();
pdfView.WaitForExit();