Как закрыть Word (или другое приложение), если в VBScript возникает ошибка?

Я написал приложение VBScript для открытия документов Word и Excel, поиска и замены блоков текста и различных разделов, извлекая новый текст из обычного текстового файла. Я намеренно избегал проверки ошибок, в первую очередь потому, что в то время я не мог этого понять (и сценарий в любом случае работал надежно). Спустя несколько месяцев на моем локальном компьютере я по необъяснимым причинам получаю сообщения об ошибках об изменении Normal.dot и окно сообщения с вопросом, что я хочу с этим сделать (для окончательного ответа требуется еще три диалоговых окна). Конечно, это убивает мою способность запустить сценарий и просто уйти, поскольку это приводит к сбою сценария. В настоящее время, когда это происходит, мне нужно открыть диспетчер задач, найти Winword.exe (графический интерфейс которого не работает) и убить его, а затем повторно запустить мой скрипт.

Какой разумный способ обнаружить ошибку и успешно закрыть Word (или Excel). Основываясь на этом вопросе, я пробую это:

Set objDoc = objWord.Documents.Open(curDir1 + "\docs\template_spec.dot")

If Err.Number <> 0 Then
WScript.Echo "Error in Word Open:" & Err.Description
objWord.Quit
Else
Set objSelection = objWord.Selection

'Do replacement activities'
ReplaceText(objSelection)

objDoc.SaveAs(curDir1 + "\docs\mynewdocument.doc")
objWord.Quit
End If

Set objShell = Nothing
Set objWord = Nothing
Set objExcel = Nothing

Конечно, волею судеб, я не могу воспроизвести проблему, поэтому все работает как обычно. Это решение кажется разумным? И побочный вопрос: как, черт возьми, мне заставить Word перестать жаловаться на Normal.dot (или заставить скрипт справиться с этим)? Как будто Word остается открытым в фоновом режиме после того, как я закрыл графический интерфейс в некоторых случаях.


person Adam    schedule 07.05.2009    source источник


Ответы (4)


Рассматривали ли вы возможность обернуть все в оператор «On Error Resume Next», чтобы ваш скрипт игнорировал все ошибки и продолжал работать в максимально возможной степени перед вызовом objWord.quit независимо от успеха или неудачи.

если вам нужна дополнительная информация о правильном использовании «При ошибке возобновить следующий», перейдите на статья об этом msdn!

Надеюсь это поможет!

Павел

person Paul Harris    schedule 13.05.2009
comment
это стандартный практический метод для этого, у меня есть длинный сценарий, который работает из книги Excel. любая ошибка в скрипте, из-за которой он выйдет из строя и оставит рабочую книгу открытой. Можете ли вы иметь несколько вложенных сообщений об ошибках? - person DevilWAH; 22.06.2011
comment
посмотрев эту ссылку на самом деле я понял, что теперь понял :) ура - person DevilWAH; 22.06.2011

Боюсь, что

WScript.Echo "..."

если он когда-нибудь сработает, ваш скрипт остановится. В остальном все выглядит правильно. Я поиграю с ним, когда вернусь домой.

Изменить: Word довольно часто зависает в фоновом режиме. Во-первых, если вы используете Outlook и Word в качестве редактора Outlook, Word не исчезнет, ​​пока не исчезнет Outlook.

person Adrien    schedule 07.05.2009

Я согласен с использованием "следующего возобновления при ошибке".

Если вам действительно нужно принудительно завершить Word, вы можете использовать WMI и класс Win32_Process, чтобы найти и остановить процесс. Это должно быть крайней мерой, если все остальное не поможет.

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process Where Name = 'winword.exe'")
For Each objProcess in colProcess
  objProcess.Terminate()
Next 

Это измененный пример из: http://www.computerperformance.co.uk/vbscript/wmi_process_stop.htm

Кроме того, перед завершением процесса убедитесь, что все ваши ссылки на объект автоматизации Word закрыты и / или равны нулю.

person Chris Sears    schedule 27.05.2009

Самый надежный способ завершить работу всех экземпляров ActiveX, очистить мусор и освободить ресурсы - это поместить код для этой цели в Sub Class_Terminate() фиктивного класса, созданный экземпляр класса позволяет обрабатывать событие выхода из скрипта.

Option Explicit
Dim objBeforeQuitHandler, objWord

' create a dummy class instance
Set objBeforeQuitHandler = New clsBeforeQuitHandler

' create word app instance
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Add.ActiveWindow.Selection.TypeText "80040000 error was raised. About to terminate the script." & vbCrLf & "Word will be quitted without saving before script termination just you close popped up error message."

' your code here...

' raise an error
Err.Raise vbObjectError

Class clsBeforeQuitHandler
    ' dummy class for wrapping script quit event handler
    Private Sub Class_Terminate()
        Dim objDoc
        On Error Resume Next ' to prevent errors in case of unexpected word app termination
        If TypeName(objWord) <> "Object" Then ' word app has not been closed yet
            objWord.DisplayAlerts = False
            For Each objDoc In objWord.Documents
                objDoc.Saved = True ' to prevent save as dialog popping up
                objDoc.Close
            Next
            objWord.Quit
        End If
    End Sub
End Class
person omegastripes    schedule 06.05.2015
comment
См. Также: stackoverflow.com/a/21206112/603855, stackoverflow.com/a/20382898/603855 - person Ekkehard.Horner; 06.05.2015