video_monitor/deploy/windows/Monitor.iss

168 lines
6.2 KiB
Plaintext
Raw Normal View History

2026-09-04 18:16:14 +08:00
#ifndef Payload
#error Payload is required
#endif
#ifndef Output
#error Output is required
#endif
[Setup]
AppId={{65B3E62C-937C-4FAA-B1F0-2F1C3D2B9955}
AppName=Monitor
AppVersion=1.003.1
DefaultDirName={autopf}\Monitor
DefaultGroupName=Monitor
OutputDir={#Output}
OutputBaseFilename=Monitor-Setup-x64
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
MinVersion=10.0
PrivilegesRequired=admin
Compression=zip/7
SolidCompression=no
WizardStyle=modern
UninstallDisplayIcon={app}\Monitor.exe
CloseApplications=no
RestartApplications=no
[Files]
Source: "{#Payload}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
[Dirs]
Name: "{commonappdata}\Monitor"
[Icons]
Name: "{autodesktop}\Monitor"; Filename: "{app}\Monitor.exe"; WorkingDir: "{app}"
Name: "{group}\Monitor"; Filename: "{app}\Monitor.exe"; WorkingDir: "{app}"
[Run]
Filename: "{app}\Monitor.exe"; Description: "Start Monitor"; Flags: nowait postinstall skipifsilent runasoriginaluser
[Code]
var OwnerPage: TInputQueryWizardPage;
procedure InitializeWizard();
begin
OwnerPage := CreateInputQueryPage(wpSelectDir, 'Monitor Windows account',
'Choose the Windows account that will run Monitor',
'Only this account, Administrators and SYSTEM can access the database and keys. Use DOMAIN\username or COMPUTER\username.');
OwnerPage.Add('Runtime account:', False);
OwnerPage.Values[0] := GetPreviousData('MonitorOwner', GetEnv('USERDOMAIN') + '\' + GetUserNameString);
end;
procedure RegisterPreviousData(PreviousDataKey: Integer);
begin
SetPreviousData(PreviousDataKey, 'MonitorOwner', OwnerPage.Values[0]);
end;
procedure ConfigureDataAcl();
var Code: Integer; UserName: String;
begin
UserName := Trim(OwnerPage.Values[0]);
if UserName = '' then RaiseException('A runtime Windows account is required');
if Pos('"', UserName) > 0 then RaiseException('Unsupported Windows user name');
if not Exec(ExpandConstant('{sys}\icacls.exe'),
'"' + ExpandConstant('{commonappdata}\Monitor') + '" /inheritance:r /grant:r "' +
UserName + ':(OI)(CI)M" "*S-1-5-18:(OI)(CI)F" "*S-1-5-32-544:(OI)(CI)F"',
'', SW_HIDE, ewWaitUntilTerminated, Code) or (Code <> 0) then
RaiseException('Unable to restrict Monitor data directory permissions');
end;
procedure AddFirewallRule(Arguments: String);
var Code: Integer;
begin
if not Exec(ExpandConstant('{sys}\netsh.exe'), Arguments, '', SW_HIDE, ewWaitUntilTerminated, Code) or (Code <> 0) then
RaiseException('Unable to configure Monitor firewall rules. Check Windows Firewall and the installation log.');
end;
procedure Firewall(AddRules: Boolean);
var Code: Integer; ExePath: String;
begin
Exec(ExpandConstant('{sys}\netsh.exe'),'advfirewall firewall delete rule name="Monitor Web SIP"','',SW_HIDE,ewWaitUntilTerminated,Code);
Exec(ExpandConstant('{sys}\netsh.exe'),'advfirewall firewall delete rule name="Monitor ZLM TCP"','',SW_HIDE,ewWaitUntilTerminated,Code);
Exec(ExpandConstant('{sys}\netsh.exe'),'advfirewall firewall delete rule name="Monitor ZLM UDP"','',SW_HIDE,ewWaitUntilTerminated,Code);
if not AddRules then Exit;
ExePath := ExpandConstant('{app}\Monitor.exe');
AddFirewallRule(
'advfirewall firewall add rule name="Monitor Web SIP" dir=in action=allow program="' + ExePath +
'" protocol=TCP localport=10001,15060 profile=private,domain remoteip=localsubnet');
AddFirewallRule(
'advfirewall firewall add rule name="Monitor Web SIP" dir=in action=allow program="' + ExePath +
'" protocol=UDP localport=15060 profile=private,domain remoteip=localsubnet');
ExePath := ExpandConstant('{app}\_internal\zlm\monitor_zlm.exe');
AddFirewallRule(
'advfirewall firewall add rule name="Monitor ZLM TCP" dir=in action=allow program="' + ExePath +
'" protocol=TCP localport=10002,10554,10935,20002-40000 profile=private,domain remoteip=localsubnet');
AddFirewallRule(
'advfirewall firewall add rule name="Monitor ZLM UDP" dir=in action=allow program="' + ExePath +
'" protocol=UDP localport=20002-40000 profile=private,domain remoteip=localsubnet');
end;
function BackupRuntimeData(): String;
var Root, Backup, Base: String; Files: TArrayOfString; I, Counter: Integer;
begin
Result := '';
Root := ExpandConstant('{commonappdata}\Monitor');
if not DirExists(Root) then Exit;
if not FileExists(Root + '\monitor.sqlite3') then Exit;
Base := Root + '\backups\installer-' + GetDateTimeString('yyyymmdd-hhnnss', '-', ':');
Backup := Base;
Counter := 0;
while DirExists(Backup) do begin
Counter := Counter + 1;
Backup := Base + '-' + IntToStr(Counter);
end;
if not ForceDirectories(Backup) then begin
Result := 'Cannot create the pre-upgrade data backup directory.';
Exit;
end;
SetArrayLength(Files, 11);
Files[0] := 'monitor.sqlite3';
Files[1] := 'monitor.sqlite3-wal';
Files[2] := 'monitor.sqlite3-shm';
Files[3] := 'config.json';
Files[4] := 'settings.json';
Files[5] := 'network.json';
Files[6] := '.runtime-secrets.json';
Files[7] := '.trusted-models.json';
Files[8] := 'license.json';
Files[9] := 'license-clock.json';
Files[10] := 'zlm-template.ini';
for I := 0 to GetArrayLength(Files)-1 do
if FileExists(Root + '\' + Files[I]) then
if not CopyFile(Root + '\' + Files[I], Backup + '\' + Files[I], True) then begin
Result := 'Pre-upgrade backup failed for ' + Files[I] + '. Installation stopped to protect existing data.';
Exit;
end;
end;
function PrepareToInstall(var NeedsRestart: Boolean): String;
var Code: Integer;
begin
Result := '';
if FileExists(ExpandConstant('{app}\Monitor.exe')) then begin
if not Exec(ExpandConstant('{app}\Monitor.exe'),'--stop','',SW_HIDE,ewWaitUntilTerminated,Code) or (Code <> 0) then begin
Result := 'Please exit Monitor before upgrading.';
Exit;
end;
end;
Result := BackupRuntimeData();
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then begin
ConfigureDataAcl();
Firewall(True);
end;
end;
function InitializeUninstall(): Boolean;
var Code: Integer;
begin
Result := Exec(ExpandConstant('{app}\Monitor.exe'),'--stop','',SW_HIDE,ewWaitUntilTerminated,Code) and (Code = 0);
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usUninstall then Firewall(False);
end;