Skip to content

packaging: Windows GUI installer (Inno Setup)#94

Merged
Admnwk merged 2 commits into
FiveTechSoft:mainfrom
Admnwk:feat/windows-inno-installer
Jun 26, 2026
Merged

packaging: Windows GUI installer (Inno Setup)#94
Admnwk merged 2 commits into
FiveTechSoft:mainfrom
Admnwk:feat/windows-inno-installer

Conversation

@Admnwk

@Admnwk Admnwk commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

What & why

A classic Windows setup.exe — the clicky front door ex-Advantage users expect — as a thin GUI shell over the same machinery as the console wizard (openads_serverd --setup). It asks for the data directory, wire port, Studio console and auto-start, writes openads.ini, and optionally registers the Windows service via openads_serverd --install-service --config <ini>. No install logic is duplicated; Linux/macOS use the console wizard directly.

  • packaging/windows/openads-setup.iss — Inno Setup script: custom settings/options pages, port validation, the ini writer and service registration in CurStepChanged(ssPostInstall); uninstall drops the service first. Version is a build-time define (/DAppVer) so it is not hard-coded; binaries come from a staging folder (/DSrcDir, e.g. an extracted release zip or cpack output).
  • packaging/windows/README.md — how to build it (ISCC) and what it does.

Pairs with the --setup wizard (#89) and the CPack packaging (#91): point /DSrcDir at the CPack ZIP and iscc wraps it into a setup.exe.

Honest caveat

This is Windows-only and is not wired into CI here. I reviewed it carefully but could not compile it in my environment (no Inno Setup toolchain). Please run iscc on a Windows box / CI to verify before shipping a release.

Naming

Only nominative references to Advantage/ARC for compatibility; no third-party brand claimed.

The clicky setup.exe ex-Advantage users expect, as a thin GUI shell over
the same machinery as the console wizard: it asks for data directory,
wire port, Studio console and auto-start, writes openads.ini, and
optionally registers the Windows service via
`openads_serverd --install-service --config <ini>`. No install logic is
duplicated — Linux/macOS use the console wizard directly.

- packaging/windows/openads-setup.iss: Inno Setup script with custom
  settings/options pages, port validation, ini writer and service
  registration in CurStepChanged(ssPostInstall); uninstall drops the
  service first. Version is a build-time define (/DAppVer) so it is not
  hard-coded; binaries come from a staging folder (/DSrcDir).
- packaging/windows/README.md: how to build it (ISCC) and what it does.

Windows-only by nature; not wired into CI here. Reviewed but not
compiled in this environment (no Inno Setup toolchain available) —
verify with iscc on a Windows box / CI before shipping.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a Windows installer using Inno Setup (openads-setup.iss) along with a supporting README.md to guide users through the build and installation process. The installer provides a GUI wizard to configure server settings, write the configuration file, and register the application as a Windows service. The feedback recommends defaulting the data directory to {commonappdata} instead of {autopf} to avoid write-permission issues, adding validation to prevent port conflicts, starting the service automatically post-install, and stopping the service synchronously during uninstallation to prevent file-in-use locks.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packaging/windows/openads-setup.iss Outdated
CfgPage.Add('Studio web console port:', False);
CfgPage.Add('Studio admin user (leave blank for an open console):', False);
CfgPage.Add('Studio admin password:', True);
CfgPage.Values[0] := ExpandConstant('{autopf}\OpenADS\data');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Storing dynamic database files under Program Files ({autopf}) is discouraged on Windows due to write-permission restrictions and standard directory layouts. It is highly recommended to default the data directory to {commonappdata} (which resolves to C:\ProgramData), where the service will have appropriate write permissions.

  CfgPage.Values[0] := ExpandConstant('{commonappdata}\OpenADS\data');

Comment on lines +124 to +130
p := StrToIntDef(CfgPage.Values[2], -1);
if (p < 0) or (p > 65535) then
begin
MsgBox('The Studio port must be a number between 0 and 65535.',
mbError, MB_OK);
Result := False;
end;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add a validation check to ensure that the wire port and the Studio port are not configured to the same value, which would cause a port binding conflict and prevent the server from starting.

    p := StrToIntDef(CfgPage.Values[2], -1);
    if (p < 0) or (p > 65535) then
    begin
      MsgBox('The Studio port must be a number between 0 and 65535.',
             mbError, MB_OK);
      Result := False;
      Exit;
    end;
    if CfgPage.Values[1] = CfgPage.Values[2] then
    begin
      MsgBox('The wire port and the Studio port cannot be the same.',
             mbError, MB_OK);
      Result := False;
    end;

Comment on lines +175 to +186
if ServiceWanted then
begin
if not Exec(ExpandConstant('{app}\openads_serverd.exe'),
'--install-service --config "' + iniPath + '"',
ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, rc) then
MsgBox('Could not launch the service installer.', mbError, MB_OK)
else if rc <> 0 then
MsgBox('Service registration returned code ' + IntToStr(rc) +
'. You can register it later with:'#13#10 +
' openads_serverd --install-service --config "' + iniPath + '"',
mbInformation, MB_OK);
end;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

After successfully registering the Windows service, it is a better user experience to start the service immediately so the user doesn't have to manually start it or reboot the system.

    if ServiceWanted then
    begin
      if not Exec(ExpandConstant('{app}\openads_serverd.exe'),
                  '--install-service --config "' + iniPath + '"',
                  ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, rc) then
        MsgBox('Could not launch the service installer.', mbError, MB_OK)
      else if rc <> 0 then
        MsgBox('Service registration returned code ' + IntToStr(rc) +
               '. You can register it later with:'#13#10 +
               '  openads_serverd --install-service --config "' + iniPath + '"',
               mbInformation, MB_OK)
      else
      begin
        Exec('net.exe', 'start openads_serverd', '', SW_HIDE, ewWaitUntilTerminated, rc);
      end;
    end;

Comment on lines +63 to +65
[UninstallRun]
; Drop the service (best effort) before files are removed.
Filename: "{app}\openads_serverd.exe"; Parameters: "--uninstall-service"; Flags: runhidden; RunOnceId: "DelOpenadsSvc"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

During uninstallation, stopping the service via --uninstall-service is asynchronous and might not finish before the uninstaller attempts to delete the executable, leading to 'file in use' errors. Running net stop openads_serverd synchronously first ensures the service is fully stopped before file deletion begins.

[UninstallRun]
; Stop the service synchronously to prevent file-in-use locks, then uninstall it.
Filename: "net.exe"; Parameters: "stop openads_serverd"; Flags: runhidden; RunOnceId: "StopOpenadsSvc"
Filename: "{app}\openads_serverd.exe"; Parameters: "--uninstall-service"; Flags: runhidden; RunOnceId: "DelOpenadsSvc"

Incorporate the four review suggestions on the Inno Setup installer:

- Default the data directory under {commonappdata} (C:\ProgramData)
  instead of {autopf} (Program Files): the service needs write access to
  where the tables live, and Program Files is read-only / UAC-virtualised
  for non-elevated processes.
- Reject a configuration where the wire port and the Studio port are the
  same (the server can't bind both).
- Start the service immediately after registering it, so the user
  doesn't have to reboot or start it by hand.
- On uninstall, stop the service synchronously (net stop) before
  deregistering it, to avoid a file-in-use lock while deleting the .exe.

Also add README.es.md so the packaging docs are available in English and
Spanish.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Admnwk Admnwk merged commit 14c213d into FiveTechSoft:main Jun 26, 2026
5 checks passed
Admnwk added a commit that referenced this pull request Jun 26, 2026
The installer script from #94 did not compile with ISCC: a {autopf} constant
inside a { } brace comment closed the comment early (Inno comments don't nest),
and ArchitecturesInstallIn64BitMode=x64 is deprecated. Rewrote the comment as
// lines and switched to x64compatible. ISCC now builds openads-<ver>-setup.exe
with zero warnings/errors. No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant