Skip to content

Commit 81f2b63

Browse files
authored
Create installers that support per-user installation (#75)
* Create installers that support per-user installation * Minor change * Add quick build flag /quick yes * Enable installer localization * Add Italian to installers
1 parent 394106f commit 81f2b63

File tree

8 files changed

+234
-158
lines changed

8 files changed

+234
-158
lines changed

.github/workflows/build.yml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ on:
4747
description: Publish release after build
4848
type: boolean
4949
required: false
50+
quick:
51+
description: Skip checks (not recommended, use only for quick testing)
52+
type: boolean
53+
required: false
5054

5155
permissions:
5256
contents: write
@@ -166,6 +170,7 @@ jobs:
166170
signatures-canbeinvalid: ${{ steps.resolve.outputs.signatures-canbeinvalid }}
167171
release-tag: ${{ steps.resolve.outputs.release-tag }}
168172
is-prerelease: ${{ steps.resolve.outputs.is-prerelease }}
173+
quick: ${{ steps.resolve.outputs.quick }}
169174
runs-on: windows-2025
170175
steps:
171176
-
@@ -186,6 +191,7 @@ jobs:
186191
-GettextVersion '${{ github.event.inputs.gettext-version }}'
187192
-Sign '${{ github.event.inputs.sign }}'
188193
-PublishRelease ${{ github.event.inputs.publish-release == 'true' && '$true' || '$false' }}
194+
-Quick ${{ github.event.inputs.quick == 'true' && '$true' || '$null' }}
189195
190196
build-iconv-tarball:
191197
name: Build iconv tarball
@@ -543,6 +549,7 @@ jobs:
543549
run: make --jobs=$(nproc)
544550
-
545551
name: Check iconv (1st time)
552+
if: needs.versions.outputs.quick != 'yes'
546553
working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build
547554
env:
548555
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
@@ -645,6 +652,7 @@ jobs:
645652
run: make --jobs=$(nproc)
646653
-
647654
name: Check gettext/gnulib-local
655+
if: needs.versions.outputs.quick != 'yes'
648656
working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gnulib-local
649657
env:
650658
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
@@ -666,6 +674,7 @@ jobs:
666674
run: make --jobs=$(nproc)
667675
-
668676
name: Check gettext/gettext-runtime
677+
if: needs.versions.outputs.quick != 'yes'
669678
working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gettext-runtime
670679
env:
671680
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
@@ -687,6 +696,7 @@ jobs:
687696
run: make --jobs=$(nproc)
688697
-
689698
name: Check gettext/libtextstyle
699+
if: needs.versions.outputs.quick != 'yes'
690700
working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\libtextstyle
691701
env:
692702
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
@@ -708,6 +718,7 @@ jobs:
708718
run: make --jobs=$(nproc)
709719
-
710720
name: Check gettext/gettext-tools
721+
if: needs.versions.outputs.quick != 'yes'
711722
working-directory: src\gettext-${{ needs.versions.outputs.gettext-version }}\build\gettext-tools
712723
env:
713724
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
@@ -723,6 +734,7 @@ jobs:
723734
-
724735
# We need to rebuild iconv because it depends on gettext's libintl in order to be localizable
725736
name: Configure iconv (2nd time)
737+
if: needs.versions.outputs.quick != 'yes'
726738
working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}
727739
env:
728740
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
@@ -735,20 +747,23 @@ jobs:
735747
--enable-extra-encodings
736748
-
737749
name: Compile iconv (2nd time)
750+
if: needs.versions.outputs.quick != 'yes'
738751
working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build
739752
env:
740753
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
741754
LIB: ${{ steps.vars.outputs.lib-env-var }}
742755
run: make --jobs=$(nproc)
743756
-
744757
name: Check iconv (2nd time)
758+
if: needs.versions.outputs.quick != 'yes'
745759
working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build
746760
env:
747761
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
748762
LIB: ${{ steps.vars.outputs.lib-env-var }}
749763
run: make --jobs=$(nproc) check
750764
-
751765
name: Install iconv (2nd time)
766+
if: needs.versions.outputs.quick != 'yes'
752767
working-directory: src\libiconv-${{ needs.versions.outputs.iconv-version }}\build
753768
env:
754769
INCLUDE: ${{ steps.vars.outputs.include-env-var }}
@@ -861,6 +876,7 @@ jobs:
861876
run: rm -rf installed
862877
-
863878
name: Check if iconv program load translations correctly
879+
if: needs.versions.outputs.quick != 'yes'
864880
shell: pwsh
865881
run: |
866882
$env:LANGUAGE = 'it'
@@ -1083,6 +1099,18 @@ jobs:
10831099
* iconv ${{ needs.versions.outputs.iconv-version-base }}
10841100
* libcurl ${{ needs.versions.outputs.curl-version-default }}
10851101
* libjson-c ${{ needs.versions.outputs.json-c-version-default }}
1086-
* CLDR ${{ needs.versions.outputs.cldr-version }}
1102+
* CLDR ${{ needs.versions.outputs.cldr-version }}
10871103
10881104
generate_release_notes: true
1105+
-
1106+
name: Final notes
1107+
run: |
1108+
cat >>"$GITHUB_STEP_SUMMARY" <<EOF
1109+
### Release ${{ needs.versions.outputs.release-tag }} published
1110+
1111+
Next steps:
1112+
1113+
* [Submit to VirusTotal](https://github.com/${{ github.repository }}/actions/workflows/virustotal.yml)
1114+
* [Submit to WinGet](https://github.com/${{ github.repository }}/actions/workflows/winget.yml)
1115+
1116+
EOF

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/.vscode/launch.json
2+
/service/create-installer.isi

service/create-installer.iss

Lines changed: 55 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,49 @@
1-
// Template file used by the create-installer.ps1 script
1+
// File used by the create-installer.ps1 script
22

3+
#include "create-installer.isi"
4+
// Must have:
35
// #define MyVersionShownName "<shared|static> (<32|64> bit)"
46
// #define MyVersionCodeName "<shared|static>-<32|64>"
57
// #define MyIs64bit <true|false>
68
// #define MyGettextVer "<gettext version>"
79
// #define MyIconvVer "<iconv version>"
810
// #define MyCompiledFolderPath "<path>"
11+
// #define MyOutputFolderPath "<path>"
12+
// #define MyLanguages "Entries of the [Languages] section"
913

1014
[Setup]
1115
AppId=gettext-iconv
1216
AppName="gettext + iconv"
1317
AppVerName="gettext {#MyGettextVer} + iconv {#MyIconvVer} - {#MyVersionShownName}"
14-
DefaultDirName={commonpf}\gettext-iconv
18+
WizardStyle=modern dynamic
19+
DefaultDirName={autopf}\gettext-iconv
1520
AppPublisher=Michele Locati
1621
AppPublisherURL=https://github.com/mlocati
17-
AppSupportURL=https://github.com/mlocati/gettext-iconv-windows
22+
AppSupportURL=https://github.com/mlocati/gettext-iconv-windows/issues
1823
AppUpdatesURL=https://github.com/mlocati/gettext-iconv-windows/releases
1924
#if MyIs64bit
2025
ArchitecturesAllowed=x64
2126
ArchitecturesInstallIn64BitMode=x64
2227
#endif
23-
ChangesEnvironment=yes
28+
ChangesEnvironment=WizardIsTaskSelected('modifypath') or WizardIsTaskSelected('setenvcldr')
29+
PrivilegesRequiredOverridesAllowed=commandline dialog
2430
Compression=lzma2/max
2531
LicenseFile={#MyCompiledFolderPath}\license.txt
26-
OutputDir=setup
32+
OutputDir={#MyOutputFolderPath}
2733
OutputBaseFilename=gettext{#MyGettextVer}-iconv{#MyIconvVer}-{#MyVersionCodeName}
2834
VersionInfoProductTextVersion=1.0
35+
ShowLanguageDialog=auto
2936

3037
[Files]
3138
Source: "{#MyCompiledFolderPath}\*.*"; DestDir: "{app}"; Flags: recursesubdirs
3239

3340
[Tasks]
34-
Name: modifypath; Description: &Add application directory to your environmental &PATH
35-
Name: setenvcldr; Description: Set GETTEXTCLDRDIR environment variable (useful for msginit)
41+
Name: modifypath; Description: "{cm:ModifyPath}"
42+
Name: setenvcldr; Description: "{cm:SetEnvCLDR}"
43+
44+
[Languages]
45+
{#MyLanguages}
46+
3647

3748
[Code]
3849
#ifdef UNICODE
@@ -46,7 +57,6 @@ const
4657
TASK_SETENVCLDR = 'setenvcldr';
4758
TASK_MODPATH_TYPE = 'system';
4859
TASK_SETENVCLDR_NAME = 'GETTEXTCLDRDIR';
49-
TASK_SETENVCLDR_TYPE = 'system';
5060
5161
function SetEnvironmentVariable(lpName: string; lpValue: string): BOOL;
5262
external 'SetEnvironmentVariable{#AW}@kernel32.dll stdcall';
@@ -74,7 +84,7 @@ var
7484
regroot: Integer;
7585
regpath: String;
7686
begin
77-
if TASK_SETENVCLDR_TYPE = 'system' then begin
87+
if IsAdminInstallMode then begin
7888
regroot := HKEY_LOCAL_MACHINE;
7989
regpath := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
8090
end else begin
@@ -97,17 +107,14 @@ var
97107
newpath: String;
98108
updatepath: Boolean;
99109
pathArr: TArrayOfString;
100-
aExecFile: String;
101-
aExecArr: TArrayOfString;
102110
i, d: Integer;
103111
pathdir: TArrayOfString;
104112
regroot: Integer;
105113
regpath: String;
106114
107115
begin
108116
// Get constants from main script and adjust behavior accordingly
109-
// TASK_MODPATH_TYPE MUST be 'system' or 'user'; force 'user' if invalid
110-
if TASK_MODPATH_TYPE = 'system' then begin
117+
if IsAdminInstallMode then begin
111118
regroot := HKEY_LOCAL_MACHINE;
112119
regpath := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
113120
end else begin
@@ -120,78 +127,41 @@ begin
120127
for d := 0 to GetArrayLength(pathdir)-1 do begin
121128
updatepath := true;
122129
123-
// Modify WinNT path
124-
if UsingWinNT() = true then begin
125-
126-
// Get current path, split into an array
127-
RegQueryStringValue(regroot, regpath, 'Path', oldpath);
128-
oldpath := oldpath + ';';
129-
i := 0;
130-
131-
while (Pos(';', oldpath) > 0) do begin
132-
SetArrayLength(pathArr, i+1);
133-
pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);
134-
oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath));
135-
i := i + 1;
136-
137-
// Check if current directory matches app dir
138-
if pathdir[d] = pathArr[i-1] then begin
139-
// if uninstalling, remove dir from path
140-
if IsUninstaller() = true then begin
141-
continue;
142-
// if installing, flag that dir already exists in path
143-
end else begin
144-
updatepath := false;
145-
end;
146-
end;
147-
148-
// Add current directory to new path
149-
if i = 1 then begin
150-
newpath := pathArr[i-1];
151-
end else begin
152-
newpath := newpath + ';' + pathArr[i-1];
153-
end;
154-
end;
155-
156-
// Append app dir to path if not already included
157-
if (IsUninstaller() = false) AND (updatepath = true) then
158-
newpath := newpath + ';' + pathdir[d];
159-
// Write new path
160-
RegWriteStringValue(regroot, regpath, 'Path', newpath);
161-
162-
// Modify Win9x path
163-
end else begin
164-
165-
// Convert to shortened dirname
166-
pathdir[d] := GetShortName(pathdir[d]);
167-
168-
// If autoexec.bat exists, check if app dir already exists in path
169-
aExecFile := 'C:\AUTOEXEC.BAT';
170-
if FileExists(aExecFile) then begin
171-
LoadStringsFromFile(aExecFile, aExecArr);
172-
for i := 0 to GetArrayLength(aExecArr)-1 do begin
173-
if IsUninstaller() = false then begin
174-
// If app dir already exists while installing, skip add
175-
if (Pos(pathdir[d], aExecArr[i]) > 0) then
176-
updatepath := false;
177-
break;
178-
end else begin
179-
// If app dir exists and = what we originally set, then delete at uninstall
180-
if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then
181-
aExecArr[i] := '';
182-
end;
183-
end;
184-
end;
185-
186-
// If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path
187-
if (IsUninstaller() = false) AND (updatepath = true) then begin
188-
SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True);
189-
190-
// If uninstalling, write the full autoexec out
191-
end else begin
192-
SaveStringsToFile(aExecFile, aExecArr, False);
193-
end;
194-
end;
130+
// Get current path, split into an array
131+
RegQueryStringValue(regroot, regpath, 'Path', oldpath);
132+
oldpath := oldpath + ';';
133+
i := 0;
134+
135+
while (Pos(';', oldpath) > 0) do begin
136+
SetArrayLength(pathArr, i+1);
137+
pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);
138+
oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath));
139+
i := i + 1;
140+
141+
// Check if current directory matches app dir
142+
if pathdir[d] = pathArr[i-1] then begin
143+
// if uninstalling, remove dir from path
144+
if IsUninstaller() = true then begin
145+
continue;
146+
// if installing, flag that dir already exists in path
147+
end else begin
148+
updatepath := false;
149+
end;
150+
end;
151+
152+
// Add current directory to new path
153+
if i = 1 then begin
154+
newpath := pathArr[i-1];
155+
end else begin
156+
newpath := newpath + ';' + pathArr[i-1];
157+
end;
158+
end;
159+
160+
// Append app dir to path if not already included
161+
if (IsUninstaller() = false) AND (updatepath = true) then
162+
newpath := newpath + ';' + pathdir[d];
163+
// Write new path
164+
RegWriteStringValue(regroot, regpath, 'Path', newpath);
195165
end;
196166
end;
197167
@@ -256,12 +226,3 @@ begin
256226
end;
257227
end;
258228
end;
259-
260-
function NeedRestart(): Boolean;
261-
begin
262-
if (WizardIsTaskSelected(TASK_MODPATH) or WizardIsTaskSelected(TASK_SETENVCLDR)) and not UsingWinNT() then begin
263-
Result := True;
264-
end else begin
265-
Result := False;
266-
end;
267-
end;

0 commit comments

Comments
 (0)