PowerShellスクリプトを使用して指定された.msiパッケージの無人取得とインストールを自動化していますが、コマンドが構文エラーで呼び出された場合、/ quietおよび/または/ passiveが存在するにもかかわらず、msiexecはヘルプ表示のOKクリックを無期限に待機します。
現時点では、次のように呼び出しています。
(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
UI要素を非表示にすることを検討してください。同様に、MSIは、処理されていない他のエラーをトリガーする可能性があり、実行の不貞を一時停止します。おそらくタイムアウト値が含まれていますか?そして、CustomActionテーブルから起動された外部プロセスはどうですか?すみません、もうすぐとりとめのないです...
msiexec.exeを経由することは完全に避けます。これは、スクリプトまたはコードを使用してWindows Installer APIを経由することで可能になります。
VBScript/VBA/VBを使用するか、C#などの.NET言語からの操作が簡単なWindowsインストーラAPIの.NETラッパーであるDTFを使用して、COMオートメーションを介して実行できます。
C++を介して生のWin32API呼び出しに直接アクセスすることもできますが、操作の一部として生のWin32 APIを呼び出すCOMと.NETの両方に相当するものがあるため、これは時間の無駄です。
自動化の使用がオプションである場合は、Windows InstallerCOM自動化を使用して、その方法でインストール/アンインストールを自動化できるはずです。これは、ファイルに入れて実行できる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)は、基本的にWindowsインストーラAPIの.NETラッパーです-アスペクトを直接操作するための.NETアセンブリの強力なコレクションを備えていますWindowsインストーラーの、管理上の問題を解決するために多くのきめ細かい展開制御を備えたソリューションを探している人のために、ここに追加したいと思います。 C#アプリケーション内の非常に単純なコードにより、インストールプロセスを完全に制御できます。大まかなモックアップは次のとおりです。
using Microsoft.Deployment.WindowsInstaller.Installer;
Installer.SetInternalUI(InstallUIOptions.Silent);
Installer.InstallProduct(msiFilename, "ACTION=INSTALL ALLUSERS=1");
WIXツールキット -を介してDTFを入手できます。これは、XMLソースファイルからMSIファイルを作成するための全体的なソリューションです。 DTF.chmおよびDTFAPI.chmに優れたドキュメントがあり、実際のファイルはメインのインストールフォルダーにあります。最後の2つは、通常、必要なものです。
C#プロジェクトを作成し、これらのファイルを参照して、必要なコントロールを使用して独自のデプロイメントアプリケーションをコーディングするだけです。現時点ではDTFのツールを設定していませんが、C#プログラムがどのように機能するかについての一般的な考え方については、 このサンプル を参照してください。
これを追加すると思いました。これは、私が信じているシステム管理者にはほとんど関係ありませんが、MSIテクノロジをよりよく理解するのに役立つ可能性があります。 COMの自動化に加えて、C++からアクセスできる関数を備えたWin32APIもあります。もちろん、はるかに優れたパフォーマンスです(COM自動化は明らかにこれらのWin32関数を内部で呼び出します-COMはもちろんこれらの「実際の」関数の単なるラッパーです)。
現在、これに使用できるC++サンプルはありませんが、SDKのドキュメントは次のとおりです。 Windowsインストーラーリファレンス 。そして 実際のインストーラー関数のリスト への直接リンク。この関数のリストから、このテクノロジーの使用方法を簡単に理解できます。
[〜#〜] update [〜#〜]:C++スニペットのサンプルを MSIパッケージをアンインストールするさまざまな方法に関するこのstackoverflowの回答 に追加しました=(回答の下部にあるセクション14)。
システム管理者はこのオプションを使用しませんが、商用ツールはシステムのMSIデータベース(レジストリ内のいくつかの場所に保存され、ディスク上のキャッシュフォルダとともに保存されます-%SystemRoot%\Installer
-およびいくつかの「作業フォルダー」)。たとえば、SCCMまたは同様の展開システムは、「内部」でそれらを使用します。
/ qnスイッチを試しましたか?すべてのユーザーインターフェイスプロンプトを抑制する必要があります。
http://technet.Microsoft.com/en-us/library/cc759262(v = ws.10).aspx#BKMK_SetUI