|
|
@@ -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;
|
|
|
+
|