Some checks are pending
CI / Integration (mcr.microsoft.com/mssql/server:2019-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2022-latest) (push) Blocked by required conditions
CI / Build og unit tests (push) Waiting to run
CI / MSI-installer (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2017-latest) (push) Blocked by required conditions
CI / Integration (mcr.microsoft.com/mssql/server:2025-latest) (push) Blocked by required conditions
installer/SQLInsight.wxs (WiX 3 syntax) builds on Linux with wixl (installer/build-msi.sh) and in Forgejo CI on every v* tag. Agent and Web are installed self-contained as Windows services under virtual service accounts (or a gMSA), with a settings page in the wizard or MSI properties for silent installs; the values go to sqlinsight.ini, read after appsettings.json. The data folder is locked to SYSTEM, Administrators and the agent account, the event log source is registered, the web port is opened in the firewall, and the automatic update task is an optional feature. Upgrades happen in place, keep edited settings and the chosen features; uninstall keeps the settings. msi-tables.py writes what wixl lacks (component and feature conditions, Permanent/NeverOverwrite, vital services, REG_EXPAND_SZ) and verify-msi.py checks the result (sequencing, deferred actions, ASCII only). test-msi-wine.sh runs install, upgrade and uninstall under Wine. Installations made with the MSI get new versions as MSI packages run by the update task, so Windows Installer stays in charge of the files. The example instance is removed from the shipped appsettings.json, and the CLI writes UTF-8 to the console. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK
208 lines
14 KiB
XML
208 lines
14 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
SQLInsight Pro: Agent and Web as Windows services.
|
|
Built with wixl (msitools) by installer/build-msi.sh; WiX 3 syntax, so WiX 3 on Windows can build it too.
|
|
|
|
Properties (msiexec /i SQLInsight-Pro.msi PROPERTY=value ... /qn):
|
|
REPOSITORY_CONNECTION Connection string to the repository database (required for the services to start)
|
|
MONITOR_SERVER Optional first SQL Server to monitor (name, or name\instance, or name,port)
|
|
AGENT_ACCOUNT Account for SQLInsight Agent. Default the virtual account NT SERVICE\SQLInsight Agent,
|
|
which reaches other servers as the computer account (DOMAIN\SERVER$). A gMSA: DOMAIN\svc-sqlinsight$
|
|
WEB_ACCOUNT Account for SQLInsight Web. Default NT SERVICE\SQLInsight Web
|
|
WEB_PORT Port for the web UI (default 5080)
|
|
Features: Agent, Web (both by default) and UpdateTask under Agent (ADDLOCAL=ALL: installs downloaded updates hourly as SYSTEM).
|
|
An upgrade keeps the features that were installed.
|
|
-->
|
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
|
<Product Id="*" Name="SQLInsight Pro" Language="1033" Version="$(var.Version)" Manufacturer="SEOSoft"
|
|
UpgradeCode="91D05A67-4470-4C4F-9422-15CEF1B559BB">
|
|
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" Platform="x64"
|
|
Description="SQLInsight Pro $(var.Version)" Comments="SQL Server monitoring with deep expertise" Manufacturer="SEOSoft" />
|
|
<Media Id="1" Cabinet="sqlinsight.cab" EmbedCab="yes" CompressionLevel="high" />
|
|
|
|
<!-- Newer versions replace older ones in place; a downgrade is refused. -->
|
|
<Upgrade Id="91D05A67-4470-4C4F-9422-15CEF1B559BB">
|
|
<UpgradeVersion OnlyDetect="no" MigrateFeatures="yes" Property="OLDVERSIONFOUND" Minimum="0.0.0" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" />
|
|
<UpgradeVersion OnlyDetect="yes" Property="NEWERVERSIONFOUND" Minimum="$(var.Version)" IncludeMinimum="no" />
|
|
</Upgrade>
|
|
<Condition Message="A newer version of SQLInsight Pro is already installed.">NOT NEWERVERSIONFOUND</Condition>
|
|
<Condition Message="SQLInsight Pro requires 64-bit Windows Server 2016 / Windows 10 or later.">VersionNT64 >= 603</Condition>
|
|
<Condition Message="Installing SQLInsight Pro requires administrator rights.">Privileged</Condition>
|
|
|
|
<Property Id="REPOSITORY_CONNECTION" Secure="yes" />
|
|
<Property Id="MONITOR_SERVER" Secure="yes" />
|
|
<Property Id="AGENT_ACCOUNT" Value="NT SERVICE\SQLInsight Agent" Secure="yes" />
|
|
<Property Id="WEB_ACCOUNT" Value="NT SERVICE\SQLInsight Web" Secure="yes" />
|
|
<Property Id="WEB_PORT" Value="5080" Secure="yes" />
|
|
<!-- Set when the update task was installed by an earlier version, so an upgrade keeps it (see the UpdateTask feature). -->
|
|
<Property Id="UPDATETASK_INSTALLED">
|
|
<RegistrySearch Id="UpdateTaskInstalled" Root="HKLM" Key="SOFTWARE\SEOSoft\SQLInsight" Name="UpdateTask" Type="raw" Win64="yes" />
|
|
</Property>
|
|
<Property Id="ARPURLINFOABOUT" Value="https://git.seosoft.dk/seo/sqlinsight-pro" />
|
|
<Property Id="ARPHELPLINK" Value="https://git.seosoft.dk/seo/sqlinsight-pro/src/branch/main/docs" />
|
|
|
|
<Directory Id="TARGETDIR" Name="SourceDir">
|
|
<Directory Id="ProgramFiles64Folder">
|
|
<Directory Id="INSTALLFOLDER" Name="SQLInsight">
|
|
<Directory Id="AGENTDIR" Name="Agent" />
|
|
<Directory Id="WEBDIR" Name="Web" />
|
|
</Directory>
|
|
</Directory>
|
|
<Directory Id="CommonAppDataFolder">
|
|
<Directory Id="DATADIR" Name="SQLInsight">
|
|
<Directory Id="RULESDIR" Name="rules" />
|
|
</Directory>
|
|
</Directory>
|
|
</Directory>
|
|
|
|
<!-- Agent: service, settings from the installer, data folder, event log source. -->
|
|
<DirectoryRef Id="AGENTDIR">
|
|
<Component Id="AgentService" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A01" Win64="yes">
|
|
<File Id="AgentExe" Source="$(var.AgentDir)/SQLInsight.Agent.exe" KeyPath="yes" />
|
|
<ServiceInstall Id="AgentServiceInstall" Name="SQLInsight Agent" DisplayName="SQLInsight Agent"
|
|
Description="Monitors SQL Server and stores findings in the SQLInsight repository."
|
|
Type="ownProcess" Start="auto" ErrorControl="normal" Account="[AGENT_ACCOUNT]" Vital="yes" />
|
|
<ServiceControl Id="AgentServiceStop" Name="SQLInsight Agent" Stop="both" Remove="uninstall" Wait="yes" />
|
|
</Component>
|
|
<Component Id="AgentSettings" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A02" Win64="yes" NeverOverwrite="yes" Permanent="yes">
|
|
<File Id="AgentAppSettings" Source="$(var.AgentDir)/appsettings.json" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="AgentIni" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A03" Win64="yes" Permanent="yes">
|
|
<Condition>REPOSITORY_CONNECTION</Condition>
|
|
<CreateFolder />
|
|
<IniFile Id="AgentIniRepository" Name="sqlinsight.ini" Directory="AGENTDIR" Action="addLine"
|
|
Section="SQLInsight:Repository" Key="ConnectionString" Value="[REPOSITORY_CONNECTION]" />
|
|
</Component>
|
|
<Component Id="AgentIniInstance" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A04" Win64="yes" Permanent="yes">
|
|
<Condition>MONITOR_SERVER</Condition>
|
|
<CreateFolder />
|
|
<IniFile Id="AgentIniInstanceName" Name="sqlinsight.ini" Directory="AGENTDIR" Action="createLine"
|
|
Section="SQLInsight:Instances:0" Key="Name" Value="[MONITOR_SERVER]" />
|
|
<IniFile Id="AgentIniInstanceServer" Name="sqlinsight.ini" Directory="AGENTDIR" Action="createLine"
|
|
Section="SQLInsight:Instances:0" Key="Server" Value="[MONITOR_SERVER]" />
|
|
</Component>
|
|
<!-- Started only when there is something to connect to, so a plain install never fails on a missing setting. -->
|
|
<Component Id="AgentServiceStart" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A05" Win64="yes">
|
|
<Condition>REPOSITORY_CONNECTION OR OLDVERSIONFOUND</Condition>
|
|
<CreateFolder />
|
|
<ServiceControl Id="AgentServiceStartControl" Name="SQLInsight Agent" Start="install" Wait="no" />
|
|
</Component>
|
|
<!-- Tells the updater that Windows Installer owns the files: new versions are then installed as MSI packages. -->
|
|
<Component Id="InstallInfo" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A09" Win64="yes">
|
|
<RegistryKey Root="HKLM" Key="SOFTWARE\SEOSoft\SQLInsight">
|
|
<RegistryValue Name="Installer" Type="string" Value="msi" KeyPath="yes" />
|
|
<RegistryValue Name="Version" Type="string" Value="[ProductVersion]" />
|
|
</RegistryKey>
|
|
</Component>
|
|
<Component Id="EventSource" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A06" Win64="yes">
|
|
<RegistryKey Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\EventLog\Application\SQLInsight Pro">
|
|
<RegistryValue Name="EventMessageFile" Type="expandable" Value="%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\EventLogMessages.dll" KeyPath="yes" />
|
|
</RegistryKey>
|
|
</Component>
|
|
</DirectoryRef>
|
|
<DirectoryRef Id="INSTALLFOLDER">
|
|
<!-- Only here so the UpdateTask feature has something to install; the task itself is made by schtasks. -->
|
|
<Component Id="UpdateTaskMarker" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A08" Win64="yes">
|
|
<RegistryValue Root="HKLM" Key="SOFTWARE\SEOSoft\SQLInsight" Name="UpdateTask" Type="integer" Value="1" KeyPath="yes" />
|
|
</Component>
|
|
</DirectoryRef>
|
|
<DirectoryRef Id="RULESDIR">
|
|
<Component Id="DataFolder" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A07" Win64="yes" Permanent="yes">
|
|
<CreateFolder />
|
|
</Component>
|
|
</DirectoryRef>
|
|
|
|
<!-- Web: service on its own Kestrel port with Windows authentication. -->
|
|
<DirectoryRef Id="WEBDIR">
|
|
<Component Id="WebService" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A11" Win64="yes">
|
|
<File Id="WebExe" Source="$(var.WebDir)/SQLInsight.Web.exe" KeyPath="yes" />
|
|
<ServiceInstall Id="WebServiceInstall" Name="SQLInsight Web" DisplayName="SQLInsight Web"
|
|
Description="Web interface for SQLInsight Pro."
|
|
Type="ownProcess" Start="auto" ErrorControl="normal" Account="[WEB_ACCOUNT]" Vital="yes" />
|
|
<ServiceControl Id="WebServiceStop" Name="SQLInsight Web" Stop="both" Remove="uninstall" Wait="yes" />
|
|
</Component>
|
|
<Component Id="WebSettings" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A12" Win64="yes" NeverOverwrite="yes" Permanent="yes">
|
|
<File Id="WebAppSettings" Source="$(var.WebDir)/appsettings.json" KeyPath="yes" />
|
|
</Component>
|
|
<Component Id="WebIni" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A13" Win64="yes" Permanent="yes">
|
|
<Condition>REPOSITORY_CONNECTION</Condition>
|
|
<CreateFolder />
|
|
<IniFile Id="WebIniRepository" Name="sqlinsight.ini" Directory="WEBDIR" Action="addLine"
|
|
Section="SQLInsight:Repository" Key="ConnectionString" Value="[REPOSITORY_CONNECTION]" />
|
|
<IniFile Id="WebIniUrl" Name="sqlinsight.ini" Directory="WEBDIR" Action="addLine"
|
|
Section="Kestrel:Endpoints:Http" Key="Url" Value="http://*:[WEB_PORT]" />
|
|
</Component>
|
|
<Component Id="WebServiceStart" Guid="0B7E3E43-2C42-4F55-9A4C-6D1E0B6F2A14" Win64="yes">
|
|
<Condition>REPOSITORY_CONNECTION OR OLDVERSIONFOUND</Condition>
|
|
<CreateFolder />
|
|
<ServiceControl Id="WebServiceStartControl" Name="SQLInsight Web" Start="install" Wait="no" />
|
|
</Component>
|
|
</DirectoryRef>
|
|
|
|
<!-- System tools run by the deferred custom actions below (their paths are set first, as properties). -->
|
|
<CustomAction Id="SetIcaclsPath" Property="ICACLS_EXE" Value="[System64Folder]icacls.exe" />
|
|
<CustomAction Id="SetNetshPath" Property="NETSH_EXE" Value="[System64Folder]netsh.exe" />
|
|
<CustomAction Id="SetSchtasksPath" Property="SCHTASKS_EXE" Value="[System64Folder]schtasks.exe" />
|
|
|
|
<!-- The data folder: only SYSTEM, Administrators and the agent's account; nobody else may drop rules or updates there. -->
|
|
<CustomAction Id="SetDataFolderAcl" Property="ICACLS_EXE" Execute="deferred" Impersonate="no" Return="ignore"
|
|
ExeCommand=""[DATADIR]." /inheritance:r /grant:r *S-1-5-18:(OI)(CI)F *S-1-5-32-544:(OI)(CI)F "[AGENT_ACCOUNT]:(OI)(CI)M"" />
|
|
|
|
<!-- Windows Firewall: open the web port while Web is installed. -->
|
|
<CustomAction Id="OpenFirewall" Property="NETSH_EXE" Execute="deferred" Impersonate="no" Return="ignore"
|
|
ExeCommand="advfirewall firewall add rule name="SQLInsight Web" dir=in action=allow protocol=TCP localport=[WEB_PORT]" />
|
|
<CustomAction Id="ReplaceFirewallRule" Property="NETSH_EXE" Execute="deferred" Impersonate="no" Return="ignore"
|
|
ExeCommand="advfirewall firewall delete rule name="SQLInsight Web"" />
|
|
<CustomAction Id="CloseFirewall" Property="NETSH_EXE" Execute="deferred" Impersonate="no" Return="ignore"
|
|
ExeCommand="advfirewall firewall delete rule name="SQLInsight Web"" />
|
|
|
|
<!-- Update task: installs updates the agent has downloaded and verified, hourly, as SYSTEM (see docs/opdatering.md). -->
|
|
<CustomAction Id="CreateUpdateTask" Property="SCHTASKS_EXE" Execute="deferred" Impersonate="no" Return="ignore"
|
|
ExeCommand="/Create /F /TN "SQLInsight Update" /SC HOURLY /RU SYSTEM /RL HIGHEST /TR "\"[AGENTDIR]SQLInsight.Agent.exe\" apply-update"" />
|
|
<CustomAction Id="DeleteUpdateTask" Property="SCHTASKS_EXE" Execute="deferred" Impersonate="no" Return="ignore"
|
|
ExeCommand="/Delete /F /TN "SQLInsight Update"" />
|
|
|
|
<InstallExecuteSequence>
|
|
<RemoveExistingProducts After="InstallExecute" />
|
|
<Custom Action="SetIcaclsPath" Before="LaunchConditions">1</Custom>
|
|
<Custom Action="SetNetshPath" After="SetIcaclsPath">1</Custom>
|
|
<Custom Action="SetSchtasksPath" After="SetNetshPath">1</Custom>
|
|
<!-- Removal: not when an upgrade removes the old version, or it would undo what the new one just set up. -->
|
|
<Custom Action="DeleteUpdateTask" Sequence="3400">&UpdateTask=2 AND NOT UPGRADINGPRODUCTCODE</Custom>
|
|
<Custom Action="CloseFirewall" Sequence="3401">&Web=2 AND NOT UPGRADINGPRODUCTCODE</Custom>
|
|
<!-- After InstallServices: the virtual account NT SERVICE\SQLInsight Agent only exists once the service does. -->
|
|
<Custom Action="SetDataFolderAcl" Sequence="5804">&Agent=3</Custom>
|
|
<Custom Action="CreateUpdateTask" Sequence="5801">&UpdateTask=3</Custom>
|
|
<Custom Action="ReplaceFirewallRule" Sequence="5802">&Web=3</Custom>
|
|
<Custom Action="OpenFirewall" Sequence="5803">&Web=3</Custom>
|
|
</InstallExecuteSequence>
|
|
|
|
<Feature Id="Agent" Title="SQLInsight Agent" Description="Monitors the SQL Server instances." Level="1" Absent="allow">
|
|
<ComponentRef Id="AgentService" />
|
|
<ComponentRef Id="AgentSettings" />
|
|
<ComponentRef Id="AgentIni" />
|
|
<ComponentRef Id="AgentIniInstance" />
|
|
<ComponentRef Id="AgentServiceStart" />
|
|
<ComponentRef Id="EventSource" />
|
|
<ComponentRef Id="InstallInfo" />
|
|
<ComponentRef Id="DataFolder" />
|
|
<ComponentGroupRef Id="AgentFiles" />
|
|
<Feature Id="UpdateTask" Title="Automatic updates" Description="Scheduled task that installs downloaded, verified updates." Level="1000" Absent="allow">
|
|
<ComponentRef Id="UpdateTaskMarker" />
|
|
<Condition Level="1">UPDATETASK_INSTALLED</Condition>
|
|
</Feature>
|
|
</Feature>
|
|
<Feature Id="Web" Title="SQLInsight Web" Description="The web interface (Windows authentication)." Level="1" Absent="allow">
|
|
<ComponentRef Id="WebService" />
|
|
<ComponentRef Id="WebSettings" />
|
|
<ComponentRef Id="WebIni" />
|
|
<ComponentRef Id="WebServiceStart" />
|
|
<ComponentGroupRef Id="WebFiles" />
|
|
</Feature>
|
|
|
|
<Icon Id="SQLInsight.ico" SourceFile="$(var.InstallerDir)/sqlinsight.ico" />
|
|
<Property Id="ARPPRODUCTICON" Value="SQLInsight.ico" />
|
|
<UIRef Id="SQLInsightUI" />
|
|
<WixVariable Id="WixUILicenseRtf" Value="$(var.InstallerDir)/License.rtf" />
|
|
</Product>
|
|
</Wix>
|