2015-04-07 3 views
0

У меня есть приложение Windows (в C#), которое отправляет файл DOC на принтер PDF, создает PDF и считывает байты. Приложение использует автоматику слова для печати PDF с помощью следующего кодаПроцесс не может получить доступ к файлу, используемому другим процессом

object Background = false; //to make sure the pdf file is created before continuing 
wordApp.Visible = true; 
wordApp.ActivePrinter = printerName;/*pdf printer*/ 
wordDoc = wordApp.Documents.Open(ref objFileName, 
ref missing, ref objFalse, ref missing, ref missing, ref missing, 
ref missing, ref missing, ref missing, ref missing, ref missing, 
ref missing, ref missing, ref missing, ref missing, ref missing); 
wordDoc.Activate(); 

wordDoc.PrintOut(Background, ref missing, ref Range, ref missing, 
    ref missing, ref missing, ref missing, ref Copies, 
    ref missing, ref PageType, ref PrintToFile, ref Collate, 
    ref missing, ref ManualDuplexPrint, ref PrintZoomColumn, 
    ref PrintZoomRow, ref missing, ref missing); 

do 
{System.Threading.Thread.Sleep(10); 
} while (wordApp.BackgroundPrintingStatus > 0); 
wordDoc.Close(ref objFalse, ref missing, ref missing); 

После создания PDF, я прочитал байты с помощью

bytes = System.IO.File.ReadAllBytes(Path.ChangeExtension(fileName, "pdf")); 

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

while (!File.Exists(Path.ChangeExtension(fileName, "pdf"))) 
{ 
System.Threading.Thread.Sleep(1000); 
} 
bytes = System.IO.File.ReadAllBytes(Path.ChangeExtension(fileName, "pdf")); 

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

+0

Если вы используете 'Microsoft.Interop', я бы предложил вам изучить, как использовать' System.Runtime.InteropServices.Marshal.ReleaseComObject ('метод вы можете попробовать: GC.Collect(); GC.WaitForPendingFinalizers () ' – MethodMan

+0

Я делаю это в блоке finally, который выглядит как' Marshal.ReleaseComObject (wordapp) ' –

+0

, который хорошо знать, так как вы на самом деле не показываете это. Не большое дело, я бы предложил использовать FileSystemWatcher .. и там это несколько вещей, которые вам нужно будет установить при использовании одного .one, в частности, это отключить событие listner и вернуть его обратно .. с той же проблемой 3 недели назад, и я сделал простое изменение, чтобы отключить событие, которое прослушивает Я был полностью закончен с файлом, а затем снова включил его. – MethodMan

ответ

1

Вместо того, чтобы делать это с помощью Thread.Sleep, я предлагаю вам использовать объект FileSystemWatcher для наблюдения за папкой для вновь созданных или вновь переименованных файлов. Это позволит вам настроить событие для запуска кода для последующей обработки, когда файл будет готов.

+0

В любом случае, кроме использования FileSystemWatcher, я не хочу иметь отдельный поток для проверки файл существует, потому что файлы генерируются все время, и это может вызвать некоторую проблему, если неправильные файлы выбраны и выполнены в делегате. Я устанавливаю background = false в автоматизацию слова, что означает, что код переместится на следующую строку только после создания файла, который происходит, но файл занимает небольшое количество времени, чтобы появиться в каталоге, и readallbytes терпят неудачу, если файл не там. –

+0

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