Как закрыть Word (или другое приложение), если в VBScript возникает ошибка? - PullRequest
2 голосов
/ 08 мая 2009

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

Какой разумный способ отловить ошибку и успешно завершить работу 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 оставляет себя открытым в фоновом режиме после того, как в некоторых случаях я закрыл графический интерфейс.

Ответы [ 4 ]

2 голосов
/ 14 мая 2009

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

если вам нужна дополнительная информация о правильном использовании «On Error Resume Next», перейдите к статье msdn об этом!

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

Пол

0 голосов
/ 06 мая 2015

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

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
0 голосов
/ 27 мая 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 закрыты и / или не установлены в ничто, прежде чем завершить процесс.

0 голосов
/ 08 мая 2009

Боюсь, что

WScript.Echo "..."

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

Редактировать: Word болтается в фоновом режиме, довольно часто. С одной стороны, если вы используете Outlook и используете Word в качестве редактора Outlook, Word не исчезнет, ​​пока не исчезнет Outlook.

...