Я автоматизирую автоматическое извлечение и установку указанных пакетов .msi с помощью сценария powershell, но если команда вызывается с синтаксическими ошибками, msiexec будет бесконечно ждать, пока щелкнет OK на его отображении справки, несмотря на наличие / quiet и / или / passive .
На данный момент я вызываю его с помощью:
(start-process -FilePath "msiexec" -ArgumentList "/i <path_to_package> /quiet /passive" -PassThru -Wait).ExitCode
Есть ли способ отключить отображение справки msiexec?
Невозможно отключить это поведение для msiexec
команда, содержащая синтаксическую ошибку. Вы можете обернуть команду примерно так. Он использует .NET Automation для поиска окна "использования" и обработки его в сценарии.
Add-Type -AssemblyName UIAutomationClient
Add-Type -AssemblyName UIAutomationTypes
# Note the invalid argument '/badswitch'
$mse = Start-Process -FilePath 'msiexec' -ArgumentList "/i package.msi /badswitch /quiet /passive" -PassThru
# Let msiexec at least get off the ground
[void] $mse.WaitForInputIdle()
# Create an AutomationElement from $mse's handle
$mseAuto = [Windows.Automation.AutomationElement]::FromHandle($mse.MainWindowHandle)
# A PropertyCondition for findAll()
$pane = New-Object Windows.Automation.PropertyCondition -ArgumentList (
[Windows.Automation.AutomationElement]::ControlTypeProperty,
[Windows.Automation.ControlType]::Pane
)
# Search for a child $pane element.
$findResult = $mseAuto.FindFirst(
[System.Windows.Automation.TreeScope]::Children,
$pane
)
# If there's a pane element in $mseAuto, and it contains "usage" string, it's an msiexec syntax issue, so close $mse's window.
if ( $findResult.Current.Name -match 'msiexec /Option <Required Parameter>' ) {
[void] $mse.CloseMainWindow()
} else {
# You should put something more sane here to handle waiting for "good" installs to complete.
$mse.WaitForExit()
}
$mse.ExitCode
Это тоже имеет проблемы. С участием /quiet
во время установки все еще отображается диалоговое окно выполнения. Вы можете рассмотреть возможность использования /qn
вместо этого скроет все msiexec
Элементы пользовательского интерфейса. Также MSI может вызвать другие необработанные ошибки, которые могут приостановить неверное выполнение. Возможно, включить значение тайм-аута? А что за внешний процесс, запущенный из таблицы CustomAction? Извините, я уже близок к бессвязному ...
Я бы вообще не стал использовать msiexec.exe. Это возможно, перейдя через API установщика Windows используя скрипты или код.
Вы можете пройти через автоматизацию COM с помощью VBScript / VBA / VB или с помощью DTF, который представляет собой .NET-оболочку для Windows Installer API, с которой проще работать с такими языками .NET, как C #.
Вы даже можете напрямую перейти через C ++ к необработанным вызовам Win32 API, но это просто пустая трата времени, поскольку у вас есть эквиваленты COM и .NET, которые вызывают необработанный Win32 API как часть своей работы.
Если можно использовать автоматизацию, вы сможете использовать Автоматизация COM установщика Windows и таким образом автоматизировать установку / удаление. Вот сценарий VBScript, который вы можете поместить в файл и запустить (очевидно, обновите путь MSI):
Const msiUILevelEndDialog = 128
Set msi = CreateObject("WindowsInstaller.Installer")
msi.UILevel = msiUILevelEndDialog
msi.InstallProduct( "C:\msifile.msi")
Set msi = Nothing
DTF (Deployment Tools Foundation) - это, по сути, оболочка .NET для API установщика Windows - в нем есть такая мощная коллекция сборок .NET для работы непосредственно с аспектами установщика Windows, что я просто хочу добавить его сюда для справки для тех, кто ищет для решения с большим количеством детализированного управления развертыванием для решения их проблемы администрирования. Очень простой код внутри приложения C # обеспечивает полный контроль над процессом установки. Вот примерный макет:
using Microsoft.Deployment.WindowsInstaller.Installer;
Installer.SetInternalUI(InstallUIOptions.Silent);
Installer.InstallProduct(msiFilename, "ACTION=INSTALL ALLUSERS=1");
Вы можете получить DTF через Набор инструментов WIX - это комплексное решение для создания файлов MSI из исходных файлов XML. Вы найдете отличную документацию в DTF.chm и DTFAPI.chm а сами файлы находятся в основной папке установки. Обычно вам нужны два последних:
Просто создайте проект C #, создайте ссылку на эти файлы и создайте собственное приложение развертывания с любым контролем, который вам нужен и который вам нужен. Я не использую инструменты для DTF на данный момент, но вижу этот образец для общего представления о том, как будет работать программа на C #.
Я просто подумал, что добавлю это - я считаю, что это в значительной степени не имеет отношения к системным администраторам, но может помочь лучше понять технологию MSI. Помимо автоматизации COM, есть еще Win32 API с функциями, доступными из C ++. Конечно, гораздо лучшая производительность (автоматизация COM, очевидно, вызывает эти функции Win32 под капотом - COM, конечно, всего лишь оболочка над этими «настоящими» функциями).
У меня сейчас нет доступных примеров C ++ для этого, но вот документация SDK: Справочник по установщику Windows. И прямая ссылка на список актуальных функций установщика. Этот список функций должен дать вам быстрое представление о том, каково использовать эту технологию.
ОБНОВИТЬ: Я добавил образец фрагмента кода C ++ в этот ответ stackoverflow о разных способах удаления пакета MSI (раздел 14 внизу ответа).
Системные администраторы не будут использовать эту опцию, но коммерческие инструменты будут использовать для доступа к базе данных MSI системы (хранящейся в нескольких местах в реестре и с папкой кеша на диске - %SystemRoot%\Installer
- и несколько "рабочих папок"). Например, ваша SCCM или аналогичная система развертывания будет использовать их «под капотом».
Просто добавим, что есть несколько классов WMI, которые можно использовать для автоматизации и запросов MSI. Win32_Product и еще пара.
К сожалению, я думаю, что единственный способ избежать отображения справки - это ...
... не допускать опечаток / синтаксических ошибок.
Хотел бы я дать вам лучший ответ, но ...
Вы пробовали использовать переключатель / qn? он должен подавлять все запросы пользовательского интерфейса.
http://technet.microsoft.com/en-us/library/cc759262(v=ws.10).aspx#BKMK_SetUI