Skip to content

Commit a17f80e

Browse files
committed
Added Inno Setup Script
1 parent dc515a8 commit a17f80e

File tree

4 files changed

+290
-0
lines changed

4 files changed

+290
-0
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
*.cls text eol=crlf linguist-language=VBA
44
*.frm text eol=crlf linguist-language=VBA
55
*.vbs text eol=crlf linguist-language=VBScript
6+
*.iss text eol=crlf

dist/tBUserformConverterSetup.exe

-414 Bytes
Binary file not shown.

src/tBUserformConverter.iss

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
// This installer script references Bill Stewart's UninsIS DLL.
2+
// see https://github.com/Bill-Stewart/UninsIS
3+
// With this installer, the user can (re)install the DLL in a location
4+
// of their choice (DisableDirPage=no). If the user had already
5+
// installed an older (or even same or newer) version compared to the one
6+
// user is currently installing, and then decides to change the
7+
// install location, this installer (with help from UninsIS) will first
8+
// uninstall the previously installed version from the old location,
9+
// so that there is only one version on the system at any one point in time.
10+
//
11+
#define AppName "twinBASIC Userform Converter"
12+
#define AppGUID "{ECF26FA9-EE79-104A-ADD2-5A0D56287D2A}"
13+
#define AppPublisher "GCUser99"
14+
#define AppURL "https://github.com/GCuser99/VBA-UserForm-to-twinBASIC"
15+
#define AppHelpURL "https://github.com/GCuser99/VBA-UserForm-to-twinBASIC#quick-how-to-use"
16+
#define InstallerName "tBUserformConverterSetup"
17+
#define DLL64FilePath "..\Build\tBUserFormConverter_win64.dll"
18+
#define DLL32FilePath "..\Build\tBUserFormConverter_win32.dll"
19+
#define LicenseFilePath "..\..\..\GitHub\VBA-UserForm-to-twinBASIC\LICENSE.txt"
20+
#define TestFolderPath "..\test_documents"
21+
#define LogoFilePath "..\logo\logo_setup.bmp"
22+
#define RequirementsFilePath ".\readme.rtf"
23+
#define SetupOutputFolderPath "..\..\..\GitHub\VBA-UserForm-to-twinBASIC\dist"
24+
#define AppVersion GetVersionNumbersString(DLL64FilePath)
25+
// The following definition points to the path of
26+
// Bill Stewart's UninsIS.dll
27+
#define UninstallDLLFilePath ".\UninsIS\UninsIS-1.0.1\UninsIS.dll"
28+
29+
[Setup]
30+
31+
AppId={{#AppGUID}
32+
AppName={#AppName}
33+
AppVersion={#AppVersion}
34+
AppPublisher={#AppPublisher}
35+
AppPublisherURL={#AppURL}
36+
AppSupportURL={#AppURL}
37+
AppUpdatesURL={#AppURL}
38+
; Set default install location
39+
DefaultDirName={localappdata}\{#AppName}
40+
DefaultGroupName={#AppName}
41+
; Remove the following line to run in administrative
42+
; install mode (install for all users.)
43+
PrivilegesRequired=lowest
44+
OutputBaseFilename={#InstallerName}
45+
LicenseFile={#LicenseFilePath}
46+
Compression=lzma
47+
SolidCompression=yes
48+
WizardStyle=modern
49+
SetupLogging=yes
50+
; Uninstallable determines if Inno Setup's
51+
; automatic uninstaller is to be included in
52+
; the installation folder - this must be set to
53+
; "yes" for PrepareToInstall code to function
54+
; correctly
55+
Uninstallable=yes
56+
ArchitecturesAllowed=x64
57+
ArchitecturesInstallIn64BitMode=x64
58+
WizardImageFile={#LogoFilePath}
59+
DisableWelcomePage=no
60+
DisableProgramGroupPage=yes
61+
InfoBeforeFile={#RequirementsFilePath}
62+
; DisableDirPage must be set to "no" to allow
63+
; User to select a different install location
64+
; if updating
65+
DisableDirPage=no
66+
OutputDir={#SetupOutputFolderPath}
67+
68+
[Languages]
69+
70+
Name: "english"; MessagesFile: "compiler:Default.isl"
71+
72+
[Components]
73+
74+
Name: "pkg_core"; Description: "Userform Converter ActiveX Dll"; Types: full compact custom; Flags: fixed;
75+
Name: "pkg_docs"; Description: "UserForm Test Files"; Types: full compact custom;
76+
77+
[Messages]
78+
79+
FinishedLabel=Setup has finished installing [name] on your computer. A shortcut to the Install folder can be found on your Desktop.
80+
81+
[Files]
82+
Source: {#DLL64FilePath}; DestDir: {app}; Flags: ignoreversion regserver ; Check: InstallX64; Components: pkg_core;
83+
Source: {#DLL32FilePath}; DestDir: {app}; Flags: ignoreversion regserver ; Check: InstallX32; Components: pkg_core;
84+
Source: {#TestFolderPath}\dlgAllMSControls.frm; DestDir: {app}\examples; Flags: ignoreversion; Components: pkg_docs;
85+
Source: {#TestFolderPath}\dlgAllMSControls.frx; DestDir: {app}\examples; Flags: ignoreversion; Components: pkg_docs;
86+
Source: {#TestFolderPath}\readme.txt; DestDir: {app}\examples; Flags: ignoreversion; Components: pkg_docs;
87+
Source: {#LicenseFilePath} ; DestDir: "{app}"; Flags: ignoreversion ; Components: pkg_core;
88+
Source: {#RequirementsFilePath} ; DestDir: "{app}"; Flags: ignoreversion ; Components: pkg_core;
89+
; Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme
90+
; For importing DLL functions at setup
91+
Source: {#UninstallDLLFilePath}; Flags: dontcopy
92+
93+
[Icons]
94+
Name: "{autodesktop}\tBUserFormConverter - Shortcut"; Filename: "{app}"
95+
Name: "{app}\GitHub help documentation"; Filename: "{#AppHelpURL}"
96+
97+
[Code]
98+
const
99+
AppPathsKey = 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths';
100+
OFFICE_UNKNOWN_BIT = -1;
101+
OFFICE_32_BIT = 0;
102+
OFFICE_64_BIT = 6;
103+
104+
// Office version detection notes
105+
// Only if 2007 then we can rule out 64 bit. 2010, 2013, 2016,
106+
// and 365 all have both 32 and 64 bit versions
107+
// MS not supporting 2013 after April 2023
108+
109+
// first get the path to executables:
110+
// HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe
111+
// HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\MSACCESS.EXE
112+
// The default key value of above should yield something like:
113+
// C:\Program Files\Microsoft Office\root\Office16\MSACCESS.EXE
114+
// C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE
115+
// then use GetBinaryType to discover bitness
116+
117+
Function GetBinaryType(ApplicationName: string; var BinaryType: Integer): Boolean;
118+
external 'GetBinaryTypeW@kernel32.dll stdcall';
119+
120+
// The function below is based on:
121+
// https://stackoverflow.com/questions/47431008/getting-the-version-and-platform-of-office-application-from-windows-registry#47443674
122+
Function GetOfficeBitness():Integer;
123+
Var OfficeApps: array[1..5] of string;
124+
Var i: Integer;
125+
Var OfficeAppPath: String;
126+
Var BinaryType: Integer;
127+
Var KeyFound: Boolean;
128+
Begin
129+
//find the Office app binary path from Registry -
130+
//first try Excel, and if that fails then Access, then Word, etc
131+
//once path is found, then use API to determine bitness of app
132+
Result := OFFICE_UNKNOWN_BIT;
133+
134+
OfficeApps[1]:= 'excel.exe';
135+
OfficeApps[2]:= 'MSACESS.EXE';
136+
OfficeApps[3]:= 'Winword.exe';
137+
OfficeApps[4]:= 'powerpnt.exe';
138+
OfficeApps[5]:= 'OUTLOOK.exe';
139+
140+
For i:=1 To High(OfficeApps) Do
141+
Begin
142+
KeyFound := RegQueryStringValue(HKLM, AppPathsKey + '\' + OfficeApps[i], '', OfficeAppPath);
143+
If KeyFound Then Break;
144+
End;
145+
146+
If KeyFound Then
147+
Begin
148+
// find the bitness of the application binary
149+
if GetBinaryType(OfficeAppPath, BinaryType) Then Result:=BinaryType;
150+
End;
151+
End;
152+
153+
Function InstallX64(): Boolean;
154+
Begin
155+
Result := (GetOfficeBitness = OFFICE_64_BIT);
156+
End;
157+
158+
Function InstallX32: Boolean;
159+
Begin
160+
Result := IsWin64 And (GetOfficeBitness = OFFICE_32_BIT);
161+
End;
162+
163+
// The following code is for implementation of Bill Stewart's
164+
// UninsIS DLL - see https://github.com/Bill-Stewart/UninsIS
165+
// Import IsISPackageInstalled() function from UninsIS.dll at setup time
166+
Function DLLIsISPackageInstalled(AppId: string; Is64BitInstallMode,
167+
IsAdminInstallMode: DWORD): DWORD;
168+
external 'IsISPackageInstalled@files:UninsIS.dll stdcall setuponly';
169+
170+
// Import CompareISPackageVersion() function from UninsIS.dll at setup time
171+
Function DLLCompareISPackageVersion(AppId, InstallingVersion: string;
172+
Is64BitInstallMode, IsAdminInstallMode: DWORD): LongInt;
173+
external 'CompareISPackageVersion@files:UninsIS.dll stdcall setuponly';
174+
175+
// Import UninstallISPackage() function from UninsIS.dll at setup time
176+
Function DLLUninstallISPackage(AppId: string; Is64BitInstallMode,
177+
IsAdminInstallMode: DWORD): DWORD;
178+
external 'UninstallISPackage@files:UninsIS.dll stdcall setuponly';
179+
180+
// Wrapper for UninsIS.dll IsISPackageInstalled() function
181+
// Returns true if package is detected as installed, or false otherwise
182+
Function IsISPackageInstalled(): Boolean;
183+
Begin
184+
result := DLLIsISPackageInstalled('{#AppGUID}', // AppId
185+
DWORD(Is64BitInstallMode()), // Is64BitInstallMode
186+
DWORD(IsAdminInstallMode())) = 1; // IsAdminInstallMode
187+
If result Then
188+
Log('UninsIS.dll - Package detected as installed')
189+
Else
190+
Log('UninsIS.dll - Package not detected as installed');
191+
End;
192+
193+
// Wrapper for UninsIS.dll CompareISPackageVersion() function
194+
// Returns:
195+
// < 0 if version we are installing is < installed version
196+
// 0 if version we are installing is = installed version
197+
// > 0 if version we are installing is > installed version
198+
Function CompareISPackageVersion(): LongInt;
199+
Begin
200+
result := DLLCompareISPackageVersion('{#AppGUID}', // AppId
201+
'{#AppVersion}', // InstallingVersion
202+
DWORD(Is64BitInstallMode()), // Is64BitInstallMode
203+
DWORD(IsAdminInstallMode())); // IsAdminInstallMode
204+
If result < 0 Then
205+
Log('UninsIS.dll - This version {#AppVersion} older than installed version')
206+
Else If result = 0 Then
207+
Log('UninsIS.dll - This version {#AppVersion} same as installed version')
208+
Else
209+
Log('UninsIS.dll - This version {#AppVersion} newer than installed version');
210+
End;
211+
212+
// Wrapper for UninsIS.dll UninstallISPackage() function
213+
// Returns 0 for success, non-zero for failure
214+
Function UninstallISPackage(): DWORD;
215+
Begin
216+
result := DLLUninstallISPackage('{#AppGUID}', // AppId
217+
DWORD(Is64BitInstallMode()), // Is64BitInstallMode
218+
DWORD(IsAdminInstallMode())); // IsAdminInstallMode
219+
If result = 0 Then
220+
Log('UninsIS.dll - Installed package uninstall completed successfully')
221+
Else
222+
Log('UninsIS.dll - installed package uninstall did not complete successfully');
223+
End;
224+
225+
Function PrepareToInstall(Var NeedsRestart: Boolean): string;
226+
Var oldInstallDir: String; newInstallDir: String;
227+
Var isDifferentLocation: Boolean;
228+
Var isDifferentVersion: Boolean;
229+
Var isInstalled: Boolean;
230+
Var alwaysUninstall: Boolean;
231+
Begin
232+
// set alwaysUninstall to true if uninstall
233+
// should run regardless of version and location compare
234+
alwaysUninstall := false;
235+
isDifferentLocation := false;
236+
isDifferentVersion := false;
237+
238+
oldInstallDir := WizardForm.PrevAppDir;
239+
newInstallDir := ExpandConstant('{app}');
240+
241+
If oldInstallDir <> newInstallDir Then isDifferentLocation := true;
242+
243+
If CompareISPackageVersion() <> 0 Then isDifferentVersion := true;
244+
245+
isInstalled := IsISPackageInstalled()
246+
247+
If isInstalled Then
248+
Begin
249+
If isDifferentLocation Or isDifferentVersion Or alwaysUninstall Then
250+
UninstallISPackage();
251+
End;
252+
253+
result := '';
254+
End;
255+
256+
// Check if the OS/Office requirements have been met - if not warn user
257+
Function InitializeSetup(): Boolean;
258+
Var OfficeBitness: Integer;
259+
Var answer: Integer;
260+
Begin
261+
if Not IsWin64 then
262+
Begin
263+
answer := MsgBox('Setup has determined that your OS is not 64-bit Windows, which is a requirement of this installation. Do you still want to proceed?', mbConfirmation, MB_YESNO);
264+
If answer = IDYES Then
265+
Begin
266+
Result:=True;
267+
End
268+
Else
269+
Begin
270+
Result := False;
271+
Exit;
272+
End;
273+
End;
274+
OfficeBitness:= GetOfficeBitness
275+
Case OfficeBitness of
276+
OFFICE_UNKNOWN_BIT : Begin
277+
answer := MsgBox('MS Office bitness could not be determined. Are you sure that you want to proceed with the installation?', mbConfirmation, MB_YESNO);
278+
if answer = IDYES then Result:=True else Result := False End;
279+
OFFICE_32_BIT : Begin
280+
Result:=True; End;
281+
OFFICE_64_BIT : Begin
282+
Result:=True; End;
283+
Else
284+
Begin
285+
answer := MsgBox('The installed version of MS Office was found but is not compatible with this installation. Are you sure that you want to proceed?', mbConfirmation, MB_YESNO);
286+
if answer = IDYES then Result:=True else Result := False;
287+
End;
288+
End;
289+
End;

src/tbUserFormConverter.twinproj

-1.04 KB
Binary file not shown.

0 commit comments

Comments
 (0)