Ctrl K
ComunidadGuías…

HAMCTRL-installer.iss

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
; ============================================================================
;  HAMCTRL-installer.iss — instalator HAM RADIO CTRL (Inno Setup)
; ============================================================================
;  Buduje: HAMCTRL-Setup.exe
;
;  WYMAGA: Inno Setup 6+ (https://jrsoftware.org/isdl.php)
;
;  UZYCIE:
;    1. Zbuduj najpierw HAM-RADIO-CTRL.exe (py build_server.py)
;    2. Otworz ten plik w Inno Setup Compiler
;    3. Build -> Compile (albo F9)
;    4. Wynik: Output\HAMCTRL-Setup.exe
;
;  Instalator:
;    - instaluje HAM-RADIO-CTRL.exe do Program Files\HAM RADIO CTRL
;    - tworzy skroty (pulpit + menu Start)
;    - przy pierwszym uruchomieniu EXE otwiera przegladarke
;    - dane usera (config, users, .env) ida do %APPDATA%\HAMCTRL
;      (bo Program Files jest read-only - config.py to obsluguje)
;    - deinstalator w Panelu sterowania
; ============================================================================

#define AppName "HAM RADIO CTRL"
; Trzymaj zgodne z VERSION (root repo) i SERVER_VERSION w webapp.py -
; wszystkie trzy bumpowane razem tylko przy release, nie przy kazdym commicie
; (to inny numer niz znacznik [build] BUILD-YYYY-MM-DD-... w logu startowym,
; ktory zmienia sie prawie na kazdy commit i sluzy do potwierdzenia ze EXE
; spakowal najnowszy kod - nie do publicznego wersjonowania).
#define AppVersion "2.0.17"
#define AppPublisher "Franek (Claude.ai) & SQ3MZM Tom"
#define AppExeName "HAM-RADIO-CTRL.exe"
#define AppURL "https://github.com/SQ3MZM/HAMCTRL"

[Setup]
; AppId: unikalny identyfikator (nie zmieniaj miedzy wersjami tego samego produktu)
AppId={{A7F3C2E1-8B4D-4E6A-9C1F-HAMCTRL000001}
AppName={#AppName}
AppVersion={#AppVersion}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
DefaultDirName={autopf}\HAM RADIO CTRL
DefaultGroupName=HAM RADIO CTRL
; Pozwol userowi wybrac katalog
DisableProgramGroupPage=yes
; Instalacja do Program Files wymaga admina
PrivilegesRequired=admin
OutputBaseFilename=HAMCTRL-Setup
OutputDir=Output
Compression=lzma2/max
SolidCompression=yes
WizardStyle=modern
; Ikona instalatora (icon.ico obok skryptu budowania)
SetupIconFile=icon.ico
; Minimalne wersje Windows (Win10+)
MinVersion=10.0

[Languages]
Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
; Auto-odnawianie certyfikatu Let's Encrypt co 60 dni (zalecane dla serwera
; dzialajacego 24/7 ze zdalnym dostepem). Domyslnie WLACZONE.
Name: "autocert"; Description: "Automatyczne odnawianie certyfikatu Let's Encrypt (co 60 dni, w tle)"; GroupDescription: "Zdalny dostep:"

[Files]
; Glowny EXE (spakowany serwer). Sciezka wzgledna - popraw jesli EXE gdzie indziej.
Source: "dist\{#AppExeName}"; DestDir: "{app}"; Flags: ignoreversion
; Opcjonalnie README/instrukcja dla klubu
; Source: "README-KLUB.txt"; DestDir: "{app}"; Flags: ignoreversion isreadme

[Icons]
; Menu Start
Name: "{group}\HAM RADIO CTRL"; Filename: "{app}\{#AppExeName}"
; Reset hasla admina (gdy klub zapomni) - uruchamia EXE z flaga
Name: "{group}\Reset hasla admina"; Filename: "{app}\{#AppExeName}"; Parameters: "--reset-admin"
; Generowanie certyfikatu Let's Encrypt - win-acme wymaga admina. EXE sam
; prosi o podniesienie uprawnien (UAC) przy --gen-cert, wiec wystarczy
; kliknac skrot i potwierdzic monit. Osobny skrot uruchamiany raz na ~90 dni.
; Serwer na co dzien dziala BEZ admina.
Name: "{group}\Wygeneruj certyfikat (jako admin)"; Filename: "{app}\{#AppExeName}"; Parameters: "--gen-cert"
Name: "{group}\Odinstaluj HAM RADIO CTRL"; Filename: "{uninstallexe}"
; Pulpit (opcjonalny - task desktopicon)
Name: "{autodesktop}\HAM RADIO CTRL"; Filename: "{app}\{#AppExeName}"; Tasks: desktopicon

[Run]
; Regula firewall (raz przy instalacji) - pozwala na nasluch portow serwera,
; zeby Defender nie pytal o dostep do sieci przy KAZDYM uruchomieniu.
; Obejmuje porty: 8000/8001 (HTTP/HTTPS), 9400-9444 (audio/FT8), 2238 (WSJT-X).
Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""HAM RADIO CTRL"" dir=in action=allow program=""{app}\{#AppExeName}"" enable=yes profile=any"; Flags: runhidden waituntilterminated; StatusMsg: "Konfiguracja zapory sieciowej..."
; Osobna regula PORTOWA dla ham_audio.exe. Ten plik jest spakowany w bundlu
; PyInstaller i rozpakowywany przy KAZDYM starcie do losowej sciezki _MEIPASS,
; wiec regula "na program" nie zadziala (sciezka za kazdym razem inna) i zapora
; pytalaby w kolko. Regula na PORTY (9400 ctrl, 9401 WS audio, 9443 WSS audio)
; dziala niezaleznie od sciezki pliku. Port 9444 to polaczenie wychodzace do
; Pythona - nie wymaga reguly wejsciowej.
Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""HAM RADIO CTRL Audio"" dir=in action=allow protocol=TCP localport=9400,9401,9443 enable=yes profile=any"; Flags: runhidden waituntilterminated; StatusMsg: "Konfiguracja zapory (audio)..."
; Zadanie w Harmonogramie: automatyczne odnawianie certyfikatu Let's Encrypt
; co 60 dni (cert wazny 90 dni - odnawiamy z zapasem). Uruchamia --gen-cert
; z najwyzszymi uprawnieniami (win-acme wymaga admina), w tle. Serwer sam
; podchwyci nowy cert przez hot-reload (bez restartu). PELNA bezobslugowosc.
; Uruchamiane tylko jesli user wybral zadanie autocert (domyslnie tak).
Filename: "{sys}\schtasks.exe"; Parameters: "/Create /TN ""HAMCTRL Cert Renewal"" /TR ""\""{app}\{#AppExeName}\"" --gen-cert"" /SC DAILY /MO 60 /RL HIGHEST /F /RU SYSTEM"; Flags: runhidden waituntilterminated; StatusMsg: "Konfiguracja auto-odnawiania certyfikatu..."; Tasks: autocert
; Auto-uruchomienie po instalacji USUNIETE celowo. Powodowalo blad 740
; (niezgodnosc kontekstu elevacji: instalator dziala jako admin, aplikacja
; jako asInvoker). Na roznych maszynach klubowych bylo zawodne. User uruchamia
; aplikacje ze skrotu w menu Start / na pulpicie - to dziala niezawodnie.

[UninstallRun]
; Przy deinstalacji usun zadanie odnawiania certu
Filename: "{sys}\schtasks.exe"; Parameters: "/Delete /TN ""HAMCTRL Cert Renewal"" /F"; Flags: runhidden; RunOnceId: "DelCertTask"

[UninstallRun]
; Przy deinstalacji usun regule firewall
Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""HAM RADIO CTRL"""; Flags: runhidden; RunOnceId: "DelFwRule"
Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""HAM RADIO CTRL Audio"""; Flags: runhidden; RunOnceId: "DelFwRuleAudio"

[UninstallDelete]
; Przy deinstalacji NIE usuwamy danych usera z APPDATA (konfiguracja, konta,
; logi QSO) - user moze chciec je zachowac. Jesli chcesz czyscic, odkomentuj:
; Type: filesandordirs; Name: "{userappdata}\HAMCTRL"

[Messages]
; Komunikat koncowy - kieruje usera do skrotu (auto-uruchomienie usuniete).
; FIX: this used to be ONE unscoped block, so it stayed in Polish even when
; the user picked "english" as the installer language - the [Languages]
; picker only translated Inno Setup's OWN stock wizard text, never this
; custom message. Split into [Messages.polish]/[Messages.english] sections
; so it actually follows the chosen language, same fix as the app's own
; startup language below.
[Messages.polish]
FinishedLabelNoIcons=Instalacja HAM RADIO CTRL zakonczona.%n%nUruchom aplikacje ze skrotu "HAM RADIO CTRL" w menu Start. Przy pierwszym uruchomieniu ustawisz haslo administratora, a nastepnie otworzy sie przegladarka z panelem.
FinishedLabel=Instalacja HAM RADIO CTRL zakonczona.%n%nUruchom aplikacje ze skrotu "HAM RADIO CTRL" w menu Start lub na pulpicie. Przy pierwszym uruchomieniu ustawisz haslo administratora, a nastepnie otworzy sie przegladarka z panelem.

[Messages.english]
FinishedLabelNoIcons=HAM RADIO CTRL installation complete.%n%nLaunch the app from the "HAM RADIO CTRL" shortcut in the Start menu. On first run you'll set the admin password, then a browser window with the panel will open.
FinishedLabel=HAM RADIO CTRL installation complete.%n%nLaunch the app from the "HAM RADIO CTRL" shortcut in the Start menu or on the desktop. On first run you'll set the admin password, then a browser window with the panel will open.

[Code]
function InitializeSetup(): Boolean;
begin
  Result := True;
end;

// FIX: the app's UI always started in Polish regardless of which language
// was picked in this installer's own [Languages] picker - the picker only
// ever controlled the INSTALLER's wizard text, nothing carried the choice
// through to the app itself. This writes a small marker file that
// data.py::get_cfg() reads ONCE, on the app's very first start (before
// config.json exists), to seed the server-wide default UI language - see
// the matching comment there and in index.html's inline bootstrap script.
procedure CurStepChanged(CurStep: TSetupStep);
var
  LangCode: String;
  MarkerDir: String;
  MarkerFile: String;
  RuntimeDir: String;
begin
  if CurStep = ssPostInstall then
  begin
    if ActiveLanguage() = 'polish' then
      LangCode := 'pl'
    else
      LangCode := 'en';
    MarkerDir := ExpandConstant('{userappdata}\HAMCTRL');
    ForceDirectories(MarkerDir);
    MarkerFile := MarkerDir + '\install_lang.txt';
    SaveStringToFile(MarkerFile, LangCode, False);

    // FIX (2026-10-20, live report: new favicon.ico shipped in a new EXE
    // build never appeared on a running server - [static] MISSING FILE in
    // the log despite the console confirming the latest [build] marker).
    // hamctrl.spec uses a PERSISTENT PyInstaller onefile extraction folder
    // (runtime_tmpdir=%APPDATA%\HAMCTRL\_runtime, see its own comment there)
    // instead of a fresh %TEMP%\_MEIxxxxxx each run, specifically so a 24/7
    // server's files survive Windows' temp-cleanup. The flip side: on an
    // UPGRADE, a stale extraction from the OLD build can stick around and
    // the new EXE doesn't necessarily get a fully fresh folder. Clearing
    // this cache on every install/update forces a clean re-extraction on
    // next launch - safe, it holds zero user data (config.json/users.json/
    // qso.db live directly under %APPDATA%\HAMCTRL, untouched by this).
    RuntimeDir := ExpandConstant('{userappdata}\HAMCTRL\_runtime');
    if DirExists(RuntimeDir) then
      DelTree(RuntimeDir, True, True, True);
  end;
end;

// Przy DEINSTALACJI pytamy czy usunac dane uzytkownika (konta, konfiguracja,
// logi QSO w %APPDATA%\HAMCTRL). Domyslnie NIE - zeby reinstalacja/aktualizacja
// nie kasowala kont. User moze wybrac pelne czyszczenie.
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
  DataDir: String;
begin
  if CurUninstallStep = usUninstall then
  begin
    DataDir := ExpandConstant('{userappdata}\HAMCTRL');
    if DirExists(DataDir) then
    begin
      if MsgBox('Czy usunac takze dane uzytkownika?' + #13#10 + #13#10 +
                'Obejmuje: konta i hasla, konfiguracje radia, logi QSO.' + #13#10 +
                'Lokalizacja: ' + DataDir + #13#10 + #13#10 +
                'TAK = pelne czyszczenie (wszystko znika)' + #13#10 +
                'NIE = zachowaj dane (przydatne przy reinstalacji)',
                mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES then
      begin
        DelTree(DataDir, True, True, True);
      end;
    end;
  end;
end;