Gibt es sowieso eine Möglichkeit, msiexec dazu zu bringen, zu stdout zurückzukehren, anstatt sich in einer Datei anzumelden?

8

Als Teil einer Continuous Delivery-Pipeline möchte ich eine MSI auf einem bestimmten Computer installieren. msiexec plus psexec macht das perfekt, aber es scheint, dass msiexec nur in einer Datei protokollieren kann und ich brauche es, um mich bei stdout / stderr zu protokollieren.

Um die Ausgabe wieder in unsere CI-Software zu übertragen, muss ich einen zweiten Schritt hinzufügen, um den Inhalt des Protokolls wiederzugeben, was etwas sinnlos erscheint.

Hat sich schon jemand mit diesem Problem befasst (und es überwunden?)

Vielen Dank im Voraus für jede Hilfe hier.

Kennzeichen

mrmrcoleman
quelle
Verwenden Sie die in msiexec integrierte Dateiprotokollierung und lesen Sie sie von der Festplatte zurück. Während der Installation können mehrere msiexec.exe-Prozesse gestartet werden, und ich denke, es wird Ihnen schwer fallen, die Ausgabe aller Prozesse umzuleiten. Möglicherweise werden automatisch erzeugte msiexec.exe-Prozesse angezeigt, die in verschiedenen Sicherheitskontexten ausgeführt werden und auch um benutzerdefinierte Aktionen auszuführen. Eine Dose Würmer, mit denen ich mich befassen würde.
Stein Åsmul

Antworten:

5

Ich habe dies erneut überprüft und hier einige aktualisierte Informationen :

Es ist möglich, die MSI-GUI zu unterdrücken und eine externe GUI festzulegen, die von einem Dritten implementiert wurde. Diese externe GUI kann während der Installation Nachrichten von msiexec.exe empfangen . Dies dient hauptsächlich zur Implementierung eines benutzerdefinierten Fortschrittsbalkens. Sie können jedoch anscheinend auch die meisten anderen Fehlermeldungen und Statusmeldungen abfangen: die MsiSetExternalUI-Funktion .

Der interessante Parameter ist der dwMessageFilter . Wenn Sie dies einstellen, können Sie beispielsweise nur die Fehlermeldungen erhalten, die während der Installation auftreten - oder so scheint es. Ich nehme an, das kann für die meisten Zwecke ausreichen.

INSTALLUI_HANDLER MsiSetExternalUI(
  _In_  INSTALLUI_HANDLER puiHandler,
  _In_  DWORD dwMessageFilter,
  _In_  LPVOID pvContext
);

Leider habe ich momentan keinen Beispielcode dafür. Ich werde dies später testen, wenn ich mein System richtig eingerichtet habe. Die MsiEnableLog-Funktion ist ein verwandter Funktionsaufruf, der die Protokollierung in einer Datei ermöglicht. Update: Hier ist ein funktionierendes SDK-Beispiel .

Auf der Ebene der Befehlszeilenschnittstelle können Sie die Protokollierung auch so einstellen, dass der Puffer sofort in die Datei geleert wird, indem Sie das ! Parameter:

msiexec.exe /I "IsWiX.msi" /QN /L*V! "C:\msilog.log" 

Dies bedeutet, dass die Protokolldatei kontinuierlich geschrieben wird, sodass bei einem Absturz von msiexec.exe kein Protokollpuffer verloren geht. Die Kosten sind aufgrund des E / A-Overheads erheblich langsamer.

Stein Åsmul
quelle
3

MsiExec kann sich nur in einer Datei anmelden, daher müssen Sie den Inhalt dieser Datei nach Abschluss des Installationsprogramms weiter wiederholen.

Ansgar Wiechers
quelle
1

Ich würde die MSI-Protokolldatei auf dem lokalen System lieber dauerhaft an einem gemeinsamen Speicherort für jede Installation zwischenspeichern und dann einfach den Exit-Code des gesamten Setups registrieren. Wenn das Setup Erfolg meldet, ist die Protokolldatei ziemlich uninteressant? Nur mehr "Lärm"?

Abgesehen davon gibt es mehrere Software-Bereitstellungssysteme, die die Protokollinformationen für eine MSI-Installation erfassen und zentral speichern. Ein Beispiel ist SCCM (Microsoft umbenannt in Systems Management Server - SMS).

Einrichten der Protokollierung für alle MSI-Dateien finden Sie im Abschnitt "Global für alle Setups auf einem Computer": http://www.installsite.org/pages/en/msifaq/a/1022.htm

Stein Åsmul
quelle
0

Ich benutze das folgende Powershell-Skript. Das Protokoll muss weiterhin in eine Datei geschrieben werden, der Inhalt wird jedoch auch live in stdout geschrieben:

$main_process = Start-Process -FilePath ".\installer.exe" -ArgumentList "/S /V`"/qn /l*! output.log`"" -NoNewWindow -PassThru
$log_process = Start-Process "powershell" "Get-Content -Path output.log -Wait" -NoNewWindow -PassThru
$main_process.WaitForExit()
$log_process.Kill()
exit $main_process.ExitCode
Inkychris
quelle