Как открыть документ, который содержит макрос AutoOpen с PowerShell? - PullRequest
6 голосов
/ 17 мая 2010

Мой текущий скрипт PowerShell:

$document = "C:\\test.doc"
$word = new-object -comobject word.application
$word.Visible = $false
$word.DisplayAlerts = "wdAlertsNone"
$word.AutomationSecurity = "msoAutomationSecurityForceDisable"
$doc = $word.Documents.Open($document)
$word.ActivePrinter = "\\http://ptr-server:631\pdf-printer"
$background = $false
$doc.PrintOut([ref]$background)
$doc.close([ref]$false)
$word.quit()

Но в результате появляется окно с предупреждением Макросы в этом проекте отключены. Чтобы узнать, как включить макросы, обратитесь к интерактивной справке или документации хост-приложения.

Как открыть документ, не запуская макрос AutoOpen и не отображая какие-либо диалоговые окна?

Сведения об окружающей среде:

  • Word 2003 SP3
  • Windows Server 2003 R2 - Стандартная версия - Пакет обновления 2
  • Powershell Version 1.0

Ответы [ 6 ]

4 голосов
/ 08 июля 2010

Оказывается, это гораздо проще сделать в VB.NET, чем в C # (что я никогда не мог понять). Но все, что вам нужно сделать, это создать, скажем, консольное приложение с одной подпрограммой. Вот инструкции:

код

Imports word = Microsoft.Office.Interop.Word
Module Module1
    Sub Main()
        Dim args() As String = Environment.GetCommandLineArgs
        Dim path = args(1)
        Dim printer = args(2)
        Dim wordApp As word.Application = New word.Application
        wordApp.WordBasic.DisableAutoMacros(1)
        wordApp.Visible = False
        Dim doc As word.Document = wordApp.Documents.Open(path)
        wordApp.ActivePrinter = printer
        Dim background As Object = False
        doc.PrintOut(background)
        doc.Close(False)
        wordApp.WordBasic.DisableAutoMacros(0)
        wordApp.Quit()
    End Sub
End Module

Шаги для воссоздания решения:

  1. Откройте VS2008 и создайте новую консоль Приложение в VB.NET.
  2. Установить ссылку на Microsoft.Office.Interop.Word (версия 11)
  3. Удалите любой код в Module1 и вставьте код выше.
  4. Сохраните проект и назовите его «wordprinter». Постройте проект.
  5. Перейдите в папку Release, возьмите «wordprinter.exe» и поместите его в любое место. Это будет ваш $wordprinterpath.
  6. Запишите пути к вашему документу и принтеру. Это будут ваши $doc и $printer соответственно.
  7. Введите в PS следующее:
        $wordprinterpath = "C:\\path\\wordprinter.exe"
        $doc ="""C:\\Users\\me\\Documents\\Your doc.doc"""
        $printer = "\\http://ptr-server:631\pdf-printer"
        Invoke-Expression "$wordprinterpath $doc $printer" | out-Null

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

4 голосов
/ 24 июня 2010

Проблема, с которой вы столкнулись, задокументирована на KB-886633 (не говоря уже о Office для Mac - то же самое относится и к ПК):

Кроме того, если макрос пытается открыть файл, который содержит макрос, попытка потерпит неудачу, если оба выполняются следующие условия:

  • Для свойства Application.AutomationSecurity установлено значение
    msoAutomationSecurityForceDisable.
  • Попытка открыть файл осуществляется с помощью макроса Office API. Это включает макросы, которые написанный на VBA, XLM в Excel, и WordBasic в Word.

Обе маркированные точки применимы к вашему сценарию.

Единственный известный мне способ обойти это - пойти в школу - с WordBasic - отключить все автоматические макросы (AutoOpen, AutoExec и т. Д.). Вставьте $word.WordBasic.DisableAutoMacros прямо перед $word.AutomationSecurity = "msoAutomationSecurityForceDisable". Обратите внимание, что в VBA нет эквивалента этой процедуре.

2 голосов
/ 15 февраля 2012

Чтобы отключить макросы в C #, я наконец остановился на следующем, и, похоже, у меня работает ..

wordApp = new Microsoft.Office.Interop.Word.Application();
wordApp.Application.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;

Теперь я бы хотел иметь возможность запустить проверку компиляции (без sendkeys), но это другой вопрос;)

1 голос
/ 27 февраля 2012

Спасибо за указатели выше. Я смог решить эту проблему даже в C #, используя новую динамическую функцию .NET 4. Все, что я сделал, это:

var word = new Microsoft.Office.Interop.Word.Application();
word.WordBasic.DisableAutoMacros();

Очевидно, что нет поддержки intellisense, дающей подсказку для DisableAutoMacros (), так как WordBasic динамический . Но это сработало для меня; все сообщения об ошибках, которые появлялись из-за какой-либо ошибки в каком-либо макросе, исчезли.

1 голос
/ 07 июля 2010

Я пробовал несколько разных вещей ...

Предполагается, что вы сможете использовать $word.WordBasic.DisableAutoMacros(1), но PowerShell несчастен в COM, потому что вы не можете (действительно) приводить интерфейсы в PowerShell и, следовательно, приводить COM-объект к нужному интерфейсу IDispatch. кажется безнадежным, и я не вижу способа сделать это. Брэндон (BSonPosh) и я просто отказались от этого из-за сетевого интерфейса, который он пытался использовать, и прибегли к Add-Type, чтобы встроить C # для вызова метода в его случае. Это, скорее всего, сработало бы и здесь ...

То, что БУДЕТ работать (я уверен), автоматизирует нажатие на кнопку. Вы можете использовать System.Windows.UIAutomation или модуль PowerShell WASP, чтобы сделать это довольно просто.

1 голос
/ 30 июня 2010

Я не знаю, сработает ли это, просто идея: не могли бы вы загрузить и использовать Wordviewer ? Это не выполняет макросы, поэтому, вероятно, не будет отображать предупреждение. Однако я не знаю, можно ли вызвать его через API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...