Bläddra i källkod

Merge pull request #5971 from GeorgeK1ng/future_installer_update

Installer improvements
Ivan Savenko 2 månader sedan
förälder
incheckning
6850f3d37c
1 ändrade filer med 154 tillägg och 51 borttagningar
  1. 154 51
      CI/wininstaller/installer.iss

+ 154 - 51
CI/wininstaller/installer.iss

@@ -1,19 +1,71 @@
-; VCMI Installer Script Instructions
-
-; Steps to Add a New Translation to the Installer:
-
-; 1. Download the ISL file for your language from the Inno Setup repository:
-;    https://github.com/jrsoftware/issrc/tree/main/Files/Languages
-; 
-; 2. Add the required VCMI custom messages to the downloaded ISL file.
-;    - Refer to the English.isl file for examples of the necessary custom messages.
-;    - Ensure all custom messages, including WindowsVersionNotSupported, are properly translated and aligned with the English version.
-; 3. Update the ConfirmUninstall message:
-;    - Custom Uninstall Wizard is used, ensure the ConfirmUninstall message is consistent with the English version and accurately reflects the intended functionality.
-; 4. Update the WindowsVersionNotSupported message:
-;    - Ensure the WindowsVersionNotSupported message is consistent with the English version and accurately reflects the intended functionality.
-; 5. Add the new language entry to the [Languages] section of the script:
-;    - Use the correct syntax to include the language and its corresponding ISL file in the installer configuration.
+; ============================================================================
+; VCMI Installer – Adding a New Translation
+; ============================================================================
+;
+; 1. Download the base ISL file for your language:
+;    - Get the appropriate .isl file from the official Inno Setup repository:
+;      https://github.com/jrsoftware/issrc/tree/main/Files/Languages
+;
+; 2. Add VCMI custom messages:
+;    - Open the downloaded .isl file and insert all VCMI-specific messages.
+;    - Use English.isl (VCMI version) as a reference.
+;    - Ensure translations keep placeholders (%1, %2, etc.) intact and match
+;      the format of the English version exactly.
+;
+; 3. Update/translate the following modified messages:
+;    These differ from the default Inno Setup language files and are required
+;    for VCMI's custom installer functionality.
+;
+;    ------------------------------------------------------------------------
+;    WindowsVersionNotSupported
+;    ------------------------------------------------------------------------
+;    Why: VCMI adds a more descriptive message for unsupported Windows versions.
+;    Original:
+;      WindowsVersionNotSupported=This program does not support the version of Windows your computer is running.
+;    VCMI version:
+;      WindowsVersionNotSupported=This program cannot run on your version of Windows. Please ensure you are using the correct Windows version.
+;
+;    ------------------------------------------------------------------------
+;    PrivilegesRequiredOverride* messages
+;    ------------------------------------------------------------------------
+;    Why: VCMI customizes privilege escalation messages to clarify installation
+;         for all users vs. current user and highlight administrative rights.
+;    Messages to add/update:
+;      PrivilegesRequiredOverrideTitle
+;      PrivilegesRequiredOverrideInstruction
+;      PrivilegesRequiredOverrideText1
+;      PrivilegesRequiredOverrideText2
+;      PrivilegesRequiredOverrideAllUsers
+;      PrivilegesRequiredOverrideAllUsersRecommended
+;      PrivilegesRequiredOverrideCurrentUser
+;      PrivilegesRequiredOverrideCurrentUserRecommended
+;
+;    Example (VCMI English):
+;      PrivilegesRequiredOverrideTitle=Administrator Privileges Required
+;      PrivilegesRequiredOverrideInstruction=Choose how to run the installer
+;      PrivilegesRequiredOverrideText1=%1 requires administrative rights to install for all users. You can also install just for your account (no administrative rights required) or for all users (administrator rights required).
+;      PrivilegesRequiredOverrideText2=%1 can be installed only for your account (no administrative rights required) or for all users (administrator rights required).
+;      PrivilegesRequiredOverrideAllUsers=Run as &Administrator (install for all users)
+;      PrivilegesRequiredOverrideAllUsersRecommended=Run as &Administrator (recommended)
+;      PrivilegesRequiredOverrideCurrentUser=Run as &Standard User (install for me only)
+;      PrivilegesRequiredOverrideCurrentUserRecommended=Run as &Standard User (recommended)
+;
+;    ------------------------------------------------------------------------
+;    ConfirmUninstall
+;    ------------------------------------------------------------------------
+;    Why: VCMI uses a custom uninstall wizard. The message must reflect this.
+;    Original:
+;      ConfirmUninstall=Are you sure you want to completely remove %1 and all of its components?
+;    VCMI version:
+;      ConfirmUninstall=Are you sure you want to run the %1 uninstall wizard?
+;
+; 4. Add the new language to the installer:
+;    - In the [Languages] section of the script, register your translation:
+;      Name: "YourLanguage"; MessagesFile: "{#LangPath}\YourLanguage.isl"
+;
+; 5. Verify consistency:
+;    - Check all custom messages against the English VCMI ISL file.
+;    - Test the installer to confirm all messages appear correctly.
 
 
 ; Manual preprocessor definitions are provided using ISCC.exe parameters.
@@ -123,14 +175,13 @@ Name: "{code:GetUserDesktopFolder}\{cm:ShortcutLauncher}"; Filename: "{app}\VCMI
 
 
 [Tasks]
-Name: "desktop"; Description: "{cm:CreateDesktopShortcuts}"; GroupDescription: "{cm:SystemIntegration}"
-Name: "startmenu"; Description: "{cm:CreateStartMenuShortcuts}"; GroupDescription: "{cm:SystemIntegration}"
-Name: "fileassociation_h3m"; Description: "{cm:AssociateH3MFiles}"; GroupDescription: "{cm:SystemIntegration}"; Flags: unchecked
-Name: "fileassociation_vcmimap"; Description: "{cm:AssociateVCMIMapFiles}"; GroupDescription: "{cm:SystemIntegration}"
-
-Name: "firewallrules"; Description: "{cm:AddFirewallRules}"; GroupDescription: "{cm:VCMISettings}"; Check: IsAdminInstallMode
-Name: "h3copyfiles"; Description: "{cm:CopyH3Files}"; GroupDescription: "{cm:VCMISettings}"; Check: IsHeroes3Installed and IsCopyFilesNeeded
+Name: "desktop"; Description: "{cm:CreateDesktopShortcuts}"; GroupDescription: "{cm:SystemIntegration}"; Check: not IsPRInstaller
+Name: "startmenu"; Description: "{cm:CreateStartMenuShortcuts}"; GroupDescription: "{cm:SystemIntegration}"; Check: not IsPRInstaller
+Name: "fileassociation_h3m"; Description: "{cm:AssociateH3MFiles}"; GroupDescription: "{cm:SystemIntegration}"; Flags: unchecked; Check: not IsPRInstaller
+Name: "fileassociation_vcmimap"; Description: "{cm:AssociateVCMIMapFiles}"; GroupDescription: "{cm:SystemIntegration}"; Check: not IsPRInstaller
 
+Name: "firewallrules"; Description: "{cm:AddFirewallRules}"; GroupDescription: "{cm:VCMISettings}"; Check: not IsPRInstaller and IsAdminInstallMode
+Name: "h3copyfiles"; Description: "{cm:CopyH3Files}"; GroupDescription: "{cm:VCMISettings}"; Check: not IsPRInstaller and IsHeroes3Installed and IsCopyFilesNeeded
 
 [Registry]
 Root: HKCU; Subkey: "Software\{#VCMIFolder}"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: uninsdeletekey
@@ -328,7 +379,7 @@ begin
       // For 32-bit installer on ARM64, return the 32-bit Program Files directory
       Result := ExpandConstant('{commonpf32}')
     else
-			// For AMR64 installer, return the Program Files directory
+      // For AMR64 installer, return the Program Files directory
       Result := ExpandConstant('{commonpf}')
   end
   else if IsWin64 then
@@ -382,21 +433,18 @@ end;
 
 procedure OnTaskCheck(Sender: TObject);
 var
-  i: Integer;
+  idx: Integer;
 begin
-  // Loop through all tasks in the tasks list
-  for i := 0 to WizardForm.TasksList.Items.Count - 1 do
+  // Get the index of the currently clicked task
+  idx := WizardForm.TasksList.ItemIndex;
+
+  // Check if the clicked task is the "AddFirewallRules" one
+  if WizardForm.TasksList.Items[idx] = ExpandConstant('{cm:AddFirewallRules}') then
   begin
-    // Check if the current task is "firewallrules"
-    if WizardForm.TasksList.Items[i] = ExpandConstant('{cm:AddFirewallRules}') then
+    // If it was just unchecked, show the warning
+    if not WizardForm.TasksList.Checked[idx] then
     begin
-      // Check if the "firewallrules" task is unchecked
-      if not WizardForm.TasksList.Checked[i] then
-      begin
-        // Show a custom warning message box
-        MsgBox(ExpandConstant('{cm:Warning}') + '!' + #13#10 + #13#10 + ExpandConstant('{cm:InstallForMeOnly1}') + #13#10 + ExpandConstant('{cm:InstallForMeOnly2}'), mbError, MB_OK);
-      end;
-      Exit; // Task found, exit the loop
+      MsgBox(ExpandConstant('{cm:Warning}') + '!' + #13#10 + #13#10 + ExpandConstant('{cm:InstallForMeOnly1}') + #13#10 + ExpandConstant('{cm:InstallForMeOnly2}'), mbError, MB_OK);
     end;
   end;
 end;
@@ -425,24 +473,27 @@ function IsUCRTNeeded: Boolean;
 var
   FileName: String;
 begin
-  Result := False; // Default to not copying files
+  Result := True; // Default to copy the file
 
-  // Normalize and extract the file name from CurrentFileName
   FileName := ExtractFileName(ExpandConstant(CurrentFileName));
 
-  // Check for file existence based on architecture
-  if IsWin64 then
+  // Only check system if the file name contains "api"
+  if Pos('API', UpperCase(FileName)) = 1 then
   begin
-    if ExpandConstant('{#InstallerArch}') = 'x64' then
-      // For 64-bit installer on 64-bit OS, check System32
-      Result := not FileExists(ExpandConstant('{win}\System32\' + FileName))
+    // Check existence based on architecture
+    if IsWin64 then
+    begin
+      if ExpandConstant('{#InstallerArch}') = 'x64' then
+        // For 64-bit installer on 64-bit OS, check System32
+        Result := not FileExists(ExpandConstant('{win}\System32\' + FileName))
+      else
+        // For 32-bit installer on 64-bit OS, check SysWOW64
+        Result := not FileExists(ExpandConstant('{win}\SysWOW64\' + FileName));
+    end
     else
-      // For 32-bit installer on 64-bit OS, check SysWOW64
-      Result := not FileExists(ExpandConstant('{win}\SysWOW64\' + FileName));
-  end
-  else
-    // For 32-bit OS, always check System32
-    Result := not FileExists(ExpandConstant('{win}\System32\' + FileName));
+      // For 32-bit OS, always check System32
+      Result := not FileExists(ExpandConstant('{win}\System32\' + FileName));
+  end;
 end;
 
 
@@ -464,6 +515,14 @@ begin
 end;
 
 
+function IsPRInstaller(): Boolean;
+begin
+  // Skip Tasks page if this is a PR build
+  Result := Pos('-PR-', ExpandConstant('{#InstallerName}')) > 0;
+
+end;
+
+
 function InitializeSetup(): Boolean;
 var
   InstallPath: String;
@@ -578,7 +637,21 @@ end;
 function ShouldSkipPage(PageID: Integer): Boolean;
 begin
   Result := False; // Default is not to skip the page
-  
+
+  // Don't skip Target page if this is a PR build and upgrade
+  if IsPRInstaller and IsUpgrade and (PageID = wpSelectDir) then
+  begin
+    Result := False;
+    Exit;
+  end;
+
+  // Skip Tasks page if this is a PR build
+  if IsPRInstaller and (PageID = wpSelectTasks) then
+  begin
+    Result := True;
+    Exit;
+  end;
+
   if IsUpgrade then
   begin
     if (PageID = wpLicense) or (PageID = wpSelectTasks) or (PageID = wpReady) then
@@ -594,7 +667,6 @@ procedure CurPageChanged(CurPageID: Integer);
 begin
   // Ensure the footer message is visible on every page
   FooterLabel.Visible := True;
-  
 end;
 
 
@@ -678,12 +750,42 @@ begin
 end;
 
 
+procedure CreateDefaultSettingsFile();
+var
+  ConfigDir, SettingsFile, Language, JSONContent: String;
+begin
+  ConfigDir := GlobalUserDocsFolder + '\' + '{#VCMIFilesFolder}' + '\config';
+  SettingsFile := ConfigDir + '\settings.json';
+
+  if not FileExists(SettingsFile) then
+  begin
+    Language := ActiveLanguage;
+    if Language = '' then
+      Language := 'english';
+
+      JSONContent :=
+        '{' + #13#10 +
+        Chr(9) + '"general" : {' + #13#10 +
+        Chr(9) + Chr(9) + '"language" : "' + Language + '"' + #13#10 +
+        Chr(9) + '}' + #13#10 +
+        '}';
+
+    if not DirExists(ConfigDir) then
+      ForceDirectories(ConfigDir);
+
+    SaveStringToFile(SettingsFile, JSONContent, False);
+  end;
+end;
+
+
 procedure RunPreInstallTasks();
 begin
   // Remove Legacy installer when needed
   RemoveLegacyInstaller();
   // Copy H3 files when needed
   PerformHeroes3FileCopy();
+  // Create default language JSON - for future use
+  // CreateDefaultSettingsFile();
 end;
 
 
@@ -863,3 +965,4 @@ begin
       Abort;
   end;
 end;
+