Word Interop Document занимает время, чтобы закрыть, не может удалить временные файлы - PullRequest
0 голосов
/ 19 сентября 2019

Я создаю приложение C # WinForm для редактирования шаблона текстового документа (среди прочих функций).Поскольку мне нужно вставить пару изображений, я создаю их копию во временной папке компьютера (из запроса к базе данных) и хочу удалить все эти файлы при закрытии приложения.

Кажется,например, закрытие самого документа и ApplicationClass из Office.Interop.Word занимает некоторое время, и я хотел бы знать, есть ли способ вызвать событие или что-то подобное, когда приложение фактически закрыто.

Вот моя функция:

private void CloseDocument()
{
    if (_doc != null)
    {
        _doc.Close();
        _doc = null;
    }

    if (_appClass != null)
    {
        _appClass.Quit();
        _appClass = null;
    }

    File.Delete(tempFileName);

    foreach (string path in _imagePaths)
    {
        File.Delete(path);
    }
}

Эта функция связана с событием OnHandleDestroyed.К сожалению, когда документ содержит кучу изображений, кажется, что для того, чтобы объекты _doc и _appClass действительно закрылись, требуется некоторое время, в результате чего программа выдает System.IO.IOException: The process cannot access the file 'C:\Users\***\AppData\Local\Temp\alr1snsc.png' because it is being used by another process.

* 1014Есть ли способ вызвать функцию, когда документ или ApplicationClass правильно закрыты?Обратите внимание, что если я вставляю спящий режим перед тем, как пытаться удалить файлы, все работает нормально, поэтому я пришел к выводу, что действительно нужно правильно закрыть документ.

Ответы [ 2 ]

1 голос
/ 19 сентября 2019

Нет встроенного способа делать то, что вы хотите сделать.Несмотря на то, что это общая необходимость, Microsoft еще не решила ееИз-за этого есть несколько хаков, которые являются общими для достижения этой цели.

1) Проверьте временный файл в цикле.После того, как он ушел, вы можете удалить свои файлы.

string fileName = "~" + <YourDocumentFileName>
                do
                {

                } while (File.Exists(fileName));

2) Попробуйте ссылаться на что-то в документе, а в случае неудачи вы можете удалить файлы.

bool docClosed = false;
                string fileName;
                do
                {
                    try
                    {
                        fileName = _doc.OriginalDocumentTitle;
                    }
                    catch(Exception ex)
                    {
                        docClosed = true;
                    }
                } while (!docClosed);
1 голос
/ 19 сентября 2019

Это общая проблема с Word.Как таковое в объектной модели Word отсутствует событие, информирующее о снятии блокировок файлов.(Однако мне кажется странным, что это применимо к файлам изображений, обычно я связываю эту проблему только с файлами Word и связанным содержимым.)

Одна очень важная вещь заключается в том, что код явно освобождает COM-объектыи запустить GC.Если этого не произойдет, блокировки файлов не будут сняты до того, как вызывающее приложение выйдет из области действия (выйдет и очистится), если тогда.Код в вопросе, по-видимому, освобождает объекты, но не собирает мусор.Для примера см. этот ответ .

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

Другой возможностью было бы проверить наличие соответствующего «временного» файла Word, который открывается при открытии документа.Это будет в той же папке, что и документ, а имя файла начинается с тильды (~).Когда это исчезнет из папки, блокировка файла должна быть снята.Так что проверка цикла может сработать.

Я подозреваю, что Windows API (или даже .NET Framework) может предоставить функцию для обнаружения блокировок файлов ...

...