Windows installer fixes

Windows installer fixes

; C S O U N D   6   I N N O   S E T U P   S C R I P T
;
; Copyright (C) 2013 by Michael Gogins.
; This software is licensed under the terms of the
; Lesser (or Library) GNU Public License.
;
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
;
; INSTALLED DIRECTORY STRUCTURE
;
; C:\Program Files\Csound6
;     bin (copy Csound, PortAudio, libsndfile binary trees here including runtime
;     libraries and dependency libraries; but not Csound opcodes)
;     doc (copy tree)
;     examples (copy tree but exclude .wav files)
;     include
;         csound (copy include and interfaces dirs *.h and *.hpp)
;     plugins64 (all Csound plugin opcodes)
;     samples (copy tree)
;

[setup]
#define AppName "Csound6_x64"
#define AppVersion "6"
#define AppMinVersion GetEnv("CSOUND_VERSION")
#define BuildNumber GetEnv("GITHUB_RUN_NUMBER")
#define AppPublisher "Csound"
#define AppURL "https://csound.com/"
#define ManualSourceDir "html"
#define BuildRoot "build"
#define ReleaseDir "build\Release"

; Set the default folder to be the Csound root (otherwise defaults to where the script is located)
SourceDir="../../"

; Microsoft C/C++ runtime libraries
#define VCREDIST_CRT_DIR GetEnv("VCREDIST_CRT_DIR")
#define VCREDIST_CXXAMP_DIR GetEnv("VCREDIST_CXXAMP_DIR")
#define VCREDIST_OPENMP_DIR GetEnv("VCREDIST_OPENMP_DIR")

[Components]
Name: "core"; Description: "Core Csound"; Types: full custom; Flags: fixed
Name: "python"; Description: "Python features (requires Python 2.7)"; Types: full;

[Dirs]
; ALL programs and shared libraries (except opcodes and other Csound modules) go here.
Name: "{app}\bin"; Permissions: users-modify
#define APP_BIN "{app}\bin\"
; ALL static and import libraries for the Csound and CsoundAC SDKs go here.
Name: "{app}\lib"; Permissions: users-modify
#define APP_LIB "{app}\lib\"
; ALL Csound opcodes and other Csound modules go here.
Name: "{app}\plugins64"; Permissions: users-modify
#define APP_PLUGINS64 "{app}\plugins64\"
; All C or C++ include files for Csound and other components used by Csound go here.
; This is a convenience for people like me who program in C or C++ and might use
; features of these third party components.
Name: "{app}\include"
#define APP_INCLUDE "{app}\include\"
; All Csound examples go here.
Name: "{app}\examples"; Permissions: users-modify
#define APP_EXAMPLES "{app}\examples\"

; Csound manual
Name: "{app}\doc\manual"
#define APP_MANUAL "{app}\doc\manual\"

; Any SoundFonts or sound samples used by Csound examples go here.
Name: "{app}\samples"
#define APP_SAMPLES "{app}\samples\"

; Tutorials go here.
Name: "{app}\doc\tutorial"
#define APP_TUTORIAL "{app}\doc\tutorial\"

; These are the Csound environment variables related to directories.
#define SFDIR
#define SSDIR
#define SADIR
#define INCDIR
#define OPCODE6DIR64
#define SNAPDIR
#define RAWWAVE_PATH
#define MFDIR
#define PYTHONPATH

[Setup]
ChangesEnvironment=yes
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{180B4E5B-9A2F-4DA8-8692-97A174ACB74E}
AppName={#AppName}
AppVersion={#AppVersion}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
DefaultDirName={pf64}\{#AppName}
DefaultGroupName=Csound
AllowNoIcons=yes
LicenseFile="README.md"
OutputDir="installer\windows"
OutputBaseFilename="{#AppName}-{#AppMinVersion}-{#BuildNumber}"
Compression=lzma
SolidCompression=yes

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

[Files]
Source: "*.md"; DestDir: "{app}"; Flags: ignoreversion; Components: core;
Source: "installer\windows\INSTALLER.md"; DestDir: "{app}"; Flags: ignoreversion; Components: core;
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

Source: "{#VCREDIST_CRT_DIR}\*"; DestDir: "{#APP_BIN}"; Flags: recursesubdirs; Components: core;
Source: "{#VCREDIST_CXXAMP_DIR}\*"; DestDir: "{#APP_BIN}"; Flags: recursesubdirs; Components: core;
Source: "{#VCREDIST_OPENMP_DIR}\*"; DestDir: "{#APP_BIN}"; Flags: recursesubdirs; Components: core;

Source: "interfaces\ctcsound.py"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#BuildRoot}\csnd6.jar"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;

Source: "{#ReleaseDir}\_jcsound6.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\ampmidid.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\arrayops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\atsa.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\buchla.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\cellular.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\chua.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\cs.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\cs_date.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csanalyze.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csb64enc.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\csbeats.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\csdebugger.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csnd6.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csound.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csnd6.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csound64.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csound64.lib"; DestDir: "{#APP_LIB}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\libcsound64.lib"; DestDir: "{#APP_LIB}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\cvanal.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\dnoise.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\doppler.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\emugens.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\envext.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\exciter.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\extract.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\extractor.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\fareygen.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\fluidOpcodes.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\fractalnoise.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\framebuffer.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\ftsamplebank.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\getftargs.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\hdf5ops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\het_export.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\het_import.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\hetro.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core
Source: "{#ReleaseDir}\ipmidi.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\liveconv.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\lpanal.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\lpc_export.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\lpc_import.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\luaCsnd6.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\makecsd.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\mixer.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\mixer.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\osc.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\padsynth.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\platerev.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pv_export.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pv_import.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pvanal.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pvlook.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pvsops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pmidi.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\quadbezier.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\rtpa.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\rtwinmm.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\scale.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\scansyn.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\scot.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\scsort.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\scugens.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\sdif2ad.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\select.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\serial.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\signalflowgraph.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\sndinfo.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\srconv.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\src_conv.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\stackops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\stdutil.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\stkops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\system_call.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\virtual.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\widgets.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;

Source: "{#ReleaseDir}\glib-2.0-0.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\gtf.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\lfsr.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\libfluidsynth-3.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\iconv-2.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\intl-8.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\liblo.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pcre.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\portaudio.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\portmidi.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\zlib1.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;

;Source: "{#ReleaseDir}\FLAC.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\hdf5.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\jpeg62.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libcharset.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libfltk_forms_SHARED.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libfltk_images_SHARED.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libfltk_SHARED.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libpng16.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libsamplerate-0.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libsndfile-1.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\ogg.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\portaudio.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\vorbis.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\vorbisenc.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;

Source: "include\*.h"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "include\*.hpp"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "H\pffft.h"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "interfaces\*.h*"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "interfaces\csPerfThread.*"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "interfaces\*.py"; DestDir: "{#APP_BIN}"; Flags: ignoreversion;  Components: core
Source: "examples\*.*"; DestDir: "{#APP_EXAMPLES}"; Excludes: "*.wav *.html"; Flags: ignoreversion recursesubdirs;  Components: core
Source: "samples\*.*"; DestDir: "{#APP_SAMPLES}"; Flags: ignoreversion recursesubdirs;  Components: core

Source: "build\vcpkg_installed\x64-windows-csound\share\libstk\rawwaves\*.*"; DestDir: "{#APP_SAMPLES}"; Flags: ignoreversion recursesubdirs;  Components: core
Source: "{#BuildRoot}\include\float-version.h"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "{#ManualSourceDir}\*.*"; DestDir: "{#APP_MANUAL}"; Flags: ignoreversion recursesubdirs; Components: core

[Icons]
Name: "{group}\{cm:ProgramOnTheWeb,Csound}"; Filename: "{#AppURL}";  Components: core;
Name: "{group}\{cm:UninstallProgram,{#AppName}}"; Filename: "{uninstallexe}"
Name: "{group}\Csound"; Filename: "cmd.exe"; Parameters: "/K csound.exe"; WorkingDir: "{#APP_BIN}"; Flags: dontcloseonexit;  Components: core
Name: "{group}\Csound Reference Manual"; Filename: "http://csound.github.io/docs/manual/indexframes.html";  Components: core
Name: "{group}\Csound API Reference Manual"; Filename: "http://csound.github.io/docs/api/index.html";  Components: core

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType:string; ValueName:"OPCODE6DIR64"; ValueData:"{#APP_PLUGINS64}"; Flags: preservestringtype uninsdeletevalue;  Components: core
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType:string; ValueName:"PYTHONPATH"; ValueData:"{#APP_BIN};{olddata}"; Flags: preservestringtype uninsdeletevalue;  Components: python
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType:string; ValueName:"RAWWAVE_PATH"; ValueData:"{#APP_SAMPLES}"; Flags: preservestringtype uninsdeletevalue;  Components: core

[Tasks]
Name: modifypath; Description: &Add application directory to your PATH environment variable; Components: core;

[Code]
//	ModPathName defines the name of the task defined above
//	ModPathType defines whether the 'user' or 'system' path will be modified;
//		this will default to user if anything other than system is set
//	setArrayLength must specify the total number of dirs to be added
//	Result[0] contains first directory, Result[1] contains second, etc.
const ModPathName = 'modifypath';
ModPathType = 'system';

function ModPathDir(): TArrayOfString;
begin
	setArrayLength(Result, 1);
	Result[0] := ExpandConstant('{app}\bin');
end;

procedure ModPath();
var
	oldpath:	String;
	newpath:	String;
	updatepath:	Boolean;
	pathArr:	TArrayOfString;
	aExecFile:	String;
	aExecArr:	TArrayOfString;
	i, d:		Integer;
	pathdir:	TArrayOfString;
	regroot:	Integer;
	regpath:	String;
begin
	// Get constants from main script and adjust behavior accordingly
	// ModPathType MUST be 'system' or 'user'; force 'user' if invalid
	if ModPathType = 'system' then begin
		regroot := HKEY_LOCAL_MACHINE;
		regpath := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
	end else begin
		regroot := HKEY_CURRENT_USER;
		regpath := 'Environment';
	end;

	// Get array of new directories and act on each individually
	pathdir := ModPathDir();
	for d := 0 to GetArrayLength(pathdir)-1 do begin
		updatepath := true;

		// Modify WinNT path
		if UsingWinNT() = true then begin

			// Get current path, split into an array
			RegQueryStringValue(regroot, regpath, 'Path', oldpath);
			oldpath := oldpath + ';';
			i := 0;

			while (Pos(';', oldpath) > 0) do begin
				SetArrayLength(pathArr, i+1);
				pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);
				oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath));
				i := i + 1;

				// Check if current directory matches app dir
				if pathdir[d] = pathArr[i-1] then begin
					// if uninstalling, remove dir from path
					if IsUninstaller() = true then begin
						continue;
					// if installing, flag that dir already exists in path
					end else begin
						updatepath := false;
					end;
				end;

				// Add current directory to new path
				if i = 1 then begin
					newpath := pathArr[i-1];
				end else begin
					newpath := newpath + ';' + pathArr[i-1];
				end;
			end;

			// Append app dir to path if not already included
			if (IsUninstaller() = false) AND (updatepath = true) then
				newpath := newpath + ';' + pathdir[d];

			// Write new path
			RegWriteStringValue(regroot, regpath, 'Path', newpath);

		// Modify Win9x path
		end else begin

			// Convert to shortened dirname
			pathdir[d] := GetShortName(pathdir[d]);

			// If autoexec.bat exists, check if app dir already exists in path
			aExecFile := 'C:\AUTOEXEC.BAT';
			if FileExists(aExecFile) then begin
				LoadStringsFromFile(aExecFile, aExecArr);
				for i := 0 to GetArrayLength(aExecArr)-1 do begin
					if IsUninstaller() = false then begin
						// If app dir already exists while installing, skip add
						if (Pos(pathdir[d], aExecArr[i]) > 0) then
							updatepath := false;
							break;
					end else begin
						// If app dir exists and = what we originally set, then delete at uninstall
						if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then
							aExecArr[i] := '';
					end;
				end;
			end;

			// If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path
			if (IsUninstaller() = false) AND (updatepath = true) then begin
				SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True);

			// If uninstalling, write the full autoexec out
			end else begin
				SaveStringsToFile(aExecFile, aExecArr, False);
			end;
		end;
	end;
end;

// Split a string into an array using passed delimeter
procedure MPExplode(var Dest: TArrayOfString; Text: String; Separator: String);
var
	i: Integer;
begin
	i := 0;
	repeat
		SetArrayLength(Dest, i+1);
		if Pos(Separator,Text) > 0 then	begin
			Dest[i] := Copy(Text, 1, Pos(Separator, Text)-1);
			Text := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text));
			i := i + 1;
		end else begin
			 Dest[i] := Text;
			 Text := '';
		end;
	until Length(Text)=0;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
	taskname:	String;
begin
	taskname := ModPathName;
	if CurStep = ssPostInstall then
		if IsTaskSelected(taskname) then
			ModPath();
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
	aSelectedTasks:	TArrayOfString;
	i:				Integer;
	taskname:		String;
	regpath:		String;
	regstring:		String;
	appid:			String;
begin
	// only run during actual uninstall
	if CurUninstallStep = usUninstall then begin
		// get list of selected tasks saved in registry at install time
		appid := '{#emit SetupSetting("AppId")}';
		if appid = '' then appid := '{#emit SetupSetting("AppName")}';
		regpath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+appid+'_is1');
		RegQueryStringValue(HKLM, regpath, 'Inno Setup: Selected Tasks', regstring);
		if regstring = '' then RegQueryStringValue(HKCU, regpath, 'Inno Setup: Selected Tasks', regstring);

		// check each task; if matches modpath taskname, trigger patch removal
		if regstring <> '' then begin
			taskname := ModPathName;
			MPExplode(aSelectedTasks, regstring, ',');
			if GetArrayLength(aSelectedTasks) > 0 then begin
				for i := 0 to GetArrayLength(aSelectedTasks)-1 do begin
					if comparetext(aSelectedTasks[i], taskname) = 0 then
						ModPath();
				end;
			end;
		end;
	end;
end;

function NeedRestart(): Boolean;
var
	taskname:	String;
begin
	taskname := ModPathName;
	if IsTaskSelected(taskname) and not UsingWinNT() then begin
		Result := True;
	end else begin
		Result := False;
	end;
end;

; C S O U N D   6   I N N O   S E T U P   S C R I P T
;
; Copyright (C) 2013 by Michael Gogins.
; This software is licensed under the terms of the
; Lesser (or Library) GNU Public License.
;
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
;
; INSTALLED DIRECTORY STRUCTURE
;
; C:\Program Files\Csound6
;     bin (copy Csound, PortAudio, libsndfile binary trees here including runtime
;     libraries and dependency libraries; but not Csound opcodes)
;     doc (copy tree)
;     examples (copy tree but exclude .wav files)
;     include
;         csound (copy include and interfaces dirs *.h and *.hpp)
;     plugins64 (all Csound plugin opcodes)
;     samples (copy tree)
;

[setup]
#define AppName "Csound6_x64"
#define AppVersion "6"
#define AppMinVersion GetEnv("CSOUND_VERSION")
#define BuildNumber GetEnv("GITHUB_RUN_NUMBER")
#define AppPublisher "Csound"
#define AppURL "https://csound.com/"
#define ManualSourceDir "c:\html"
#define BuildRoot "build"
#define ReleaseDir "build\Release"

; Set the default folder to be the Csound root (otherwise defaults to where the script is located)
SourceDir="../../"

; Microsoft C/C++ runtime libraries
#define VCREDIST_CRT_DIR GetEnv("VCREDIST_CRT_DIR")
#define VCREDIST_CXXAMP_DIR GetEnv("VCREDIST_CXXAMP_DIR")
#define VCREDIST_OPENMP_DIR GetEnv("VCREDIST_OPENMP_DIR")

[Components]
Name: "core"; Description: "Core Csound"; Types: full custom; Flags: fixed
Name: "python"; Description: "Python features (requires Python 2.7)"; Types: full;

[Dirs]
; ALL programs and shared libraries (except opcodes and other Csound modules) go here.
Name: "{app}\bin"; Permissions: users-modify
#define APP_BIN "{app}\bin\"
; ALL static and import libraries for the Csound and CsoundAC SDKs go here.
Name: "{app}\lib"; Permissions: users-modify
#define APP_LIB "{app}\lib\"
; ALL Csound opcodes and other Csound modules go here.
Name: "{app}\plugins64"; Permissions: users-modify
#define APP_PLUGINS64 "{app}\plugins64\"
; All C or C++ include files for Csound and other components used by Csound go here.
; This is a convenience for people like me who program in C or C++ and might use
; features of these third party components.
Name: "{app}\include"
#define APP_INCLUDE "{app}\include\"
; All Csound examples go here.
Name: "{app}\examples"; Permissions: users-modify
#define APP_EXAMPLES "{app}\examples\"

; Csound manual
Name: "{app}\doc\manual"
#define APP_MANUAL "{app}\doc\manual\"

; Any SoundFonts or sound samples used by Csound examples go here.
Name: "{app}\samples"
#define APP_SAMPLES "{app}\samples\"

; Tutorials go here.
Name: "{app}\doc\tutorial"
#define APP_TUTORIAL "{app}\doc\tutorial\"

; These are the Csound environment variables related to directories.
#define SFDIR
#define SSDIR
#define SADIR
#define INCDIR
#define OPCODE6DIR64
#define SNAPDIR
#define RAWWAVE_PATH
#define MFDIR
#define PYTHONPATH

[Setup]
ChangesEnvironment=yes
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{180B4E5B-9A2F-4DA8-8692-97A174ACB74E}
AppName={#AppName}
AppVersion={#AppVersion}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
DefaultDirName={pf64}\{#AppName}
DefaultGroupName=Csound
AllowNoIcons=yes
LicenseFile="README.md"
OutputDir="installer\windows"
OutputBaseFilename="{#AppName}-{#AppMinVersion}-{#BuildNumber}"
Compression=lzma
SolidCompression=yes

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

[Files]
Source: "*.md"; DestDir: "{app}"; Flags: ignoreversion; Components: core;
Source: "installer\windows\INSTALLER.md"; DestDir: "{app}"; Flags: ignoreversion; Components: core;
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

Source: "{#VCREDIST_CRT_DIR}\*"; DestDir: "{#APP_BIN}"; Flags: recursesubdirs; Components: core;
Source: "{#VCREDIST_CXXAMP_DIR}\*"; DestDir: "{#APP_BIN}"; Flags: recursesubdirs; Components: core;
Source: "{#VCREDIST_OPENMP_DIR}\*"; DestDir: "{#APP_BIN}"; Flags: recursesubdirs; Components: core;

Source: "interfaces\ctcsound.py"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#BuildRoot}\csnd6.jar"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;

Source: "{#ReleaseDir}\*jcsound6.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\ampmidid.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\arrayops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\atsa.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\buchla.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\cellular.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\chua.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\cs.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\cs_date.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csanalyze.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csb64enc.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\csbeats.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\csdebugger.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csnd6.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csound.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csnd6.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csound64.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\csound64.lib"; DestDir: "{#APP_LIB}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\libcsound64.lib"; DestDir: "{#APP_LIB}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\cvanal.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\dnoise.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\doppler.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\emugens.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\envext.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\exciter.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\extract.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\extractor.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\fareygen.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\fluidOpcodes.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\fractalnoise.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\framebuffer.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\ftsamplebank.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\getftargs.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\hdf5ops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\het_export.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\het_import.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\hetro.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core
Source: "{#ReleaseDir}\ipmidi.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\liveconv.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\lpanal.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\lpc_export.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\lpc_import.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\luaCsnd6.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\makecsd.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\mixer.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\mixer.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\osc.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\padsynth.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\platerev.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pv_export.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pv_import.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pvanal.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pvlook.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pvsops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pmidi.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\quadbezier.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\rtpa.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\rtwinmm.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\scale.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\scansyn.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\scot.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\scsort.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion skipifsourcedoesntexist; Components: core;
Source: "{#ReleaseDir}\scugens.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\sdif2ad.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\select.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\serial.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\signalflowgraph.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\sndinfo.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\srconv.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\src_conv.exe"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\stackops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\stdutil.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\stkops.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\system_call.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\virtual.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\widgets.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;

Source: "{#ReleaseDir}\glib-2.0-0.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\gtf.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\lfsr.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\libfluidsynth-3.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\iconv-2.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\intl-8.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\liblo.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\pcre.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\portaudio.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\portmidi.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
Source: "{#ReleaseDir}\zlib1.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;

;Source: "{#ReleaseDir}\FLAC.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\hdf5.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\jpeg62.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libcharset.dll"; DestDir: "{#APP_BIN}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libfltk_forms_SHARED.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libfltk_images_SHARED.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libfltk_SHARED.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libpng16.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libsamplerate-0.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\libsndfile-1.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\ogg.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\portaudio.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\vorbis.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;
;Source: "{#ReleaseDir}\vorbisenc.dll"; DestDir: "{#APP_PLUGINS64}"; Flags: ignoreversion; Components: core;

Source: "include\*.h"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "include\*.hpp"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "H\pffft.h"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "interfaces\*.h*"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "interfaces\csPerfThread.*"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "interfaces\*.py"; DestDir: "{#APP_BIN}"; Flags: ignoreversion;  Components: core
Source: "examples\*.*"; DestDir: "{#APP_EXAMPLES}"; Excludes: "*.wav *.html"; Flags: ignoreversion recursesubdirs;  Components: core
Source: "samples\*.*"; DestDir: "{#APP_SAMPLES}"; Flags: ignoreversion recursesubdirs;  Components: core

Source: "build\vcpkg_installed\x64-windows-csound\share\libstk\rawwaves\*.*"; DestDir: "{#APP_SAMPLES}"; Flags: ignoreversion recursesubdirs;  Components: core
Source: "{#BuildRoot}\include\float-version.h"; DestDir: "{#APP_INCLUDE}\csound"; Flags: ignoreversion;  Components: core
Source: "{#ManualSourceDir}\*.*"; DestDir: "{#APP_MANUAL}"; Flags: ignoreversion recursesubdirs; Components: core

[Icons]
Name: "{group}\{cm:ProgramOnTheWeb,Csound}"; Filename: "{#AppURL}";  Components: core;
Name: "{group}\{cm:UninstallProgram,{#AppName}}"; Filename: "{uninstallexe}"
Name: "{group}\Csound"; Filename: "cmd.exe"; Parameters: "/K csound.exe"; WorkingDir: "{#APP_BIN}"; Flags: dontcloseonexit;  Components: core
Name: "{group}\Csound Reference Manual"; Filename: "http://csound.github.io/docs/manual/indexframes.html";  Components: core
Name: "{group}\Csound API Reference Manual"; Filename: "http://csound.github.io/docs/api/index.html";  Components: core

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType:string; ValueName:"OPCODE6DIR64"; ValueData:"{#APP_PLUGINS64}"; Flags: preservestringtype uninsdeletevalue;  Components: core
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType:string; ValueName:"PYTHONPATH"; ValueData:"{#APP_BIN};{olddata}"; Flags: preservestringtype uninsdeletevalue;  Components: python
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType:string; ValueName:"RAWWAVE_PATH"; ValueData:"{#APP_SAMPLES}"; Flags: preservestringtype uninsdeletevalue;  Components: core

[Tasks]
Name: modifypath; Description: &Add application directory to your PATH environment variable; Components: core;

[Code]
//	ModPathName defines the name of the task defined above
//	ModPathType defines whether the 'user' or 'system' path will be modified;
//		this will default to user if anything other than system is set
//	setArrayLength must specify the total number of dirs to be added
//	Result[0] contains first directory, Result[1] contains second, etc.
const ModPathName = 'modifypath';
ModPathType = 'system';

function ModPathDir(): TArrayOfString;
begin
	setArrayLength(Result, 1);
	Result[0] := ExpandConstant('{app}\bin');
end;

procedure ModPath();
var
	oldpath:	String;
	newpath:	String;
	updatepath:	Boolean;
	pathArr:	TArrayOfString;
	aExecFile:	String;
	aExecArr:	TArrayOfString;
	i, d:		Integer;
	pathdir:	TArrayOfString;
	regroot:	Integer;
	regpath:	String;
begin
	// Get constants from main script and adjust behavior accordingly
	// ModPathType MUST be 'system' or 'user'; force 'user' if invalid
	if ModPathType = 'system' then begin
		regroot := HKEY_LOCAL_MACHINE;
		regpath := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
	end else begin
		regroot := HKEY_CURRENT_USER;
		regpath := 'Environment';
	end;

	// Get array of new directories and act on each individually
	pathdir := ModPathDir();
	for d := 0 to GetArrayLength(pathdir)-1 do begin
		updatepath := true;

		// Modify WinNT path
		if UsingWinNT() = true then begin

			// Get current path, split into an array
			RegQueryStringValue(regroot, regpath, 'Path', oldpath);
			oldpath := oldpath + ';';
			i := 0;

			while (Pos(';', oldpath) > 0) do begin
				SetArrayLength(pathArr, i+1);
				pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);
				oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath));
				i := i + 1;

				// Check if current directory matches app dir
				if pathdir[d] = pathArr[i-1] then begin
					// if uninstalling, remove dir from path
					if IsUninstaller() = true then begin
						continue;
					// if installing, flag that dir already exists in path
					end else begin
						updatepath := false;
					end;
				end;

				// Add current directory to new path
				if i = 1 then begin
					newpath := pathArr[i-1];
				end else begin
					newpath := newpath + ';' + pathArr[i-1];
				end;
			end;

			// Append app dir to path if not already included
			if (IsUninstaller() = false) AND (updatepath = true) then
				newpath := newpath + ';' + pathdir[d];

			// Write new path
			RegWriteStringValue(regroot, regpath, 'Path', newpath);

		// Modify Win9x path
		end else begin

			// Convert to shortened dirname
			pathdir[d] := GetShortName(pathdir[d]);

			// If autoexec.bat exists, check if app dir already exists in path
			aExecFile := 'C:\AUTOEXEC.BAT';
			if FileExists(aExecFile) then begin
				LoadStringsFromFile(aExecFile, aExecArr);
				for i := 0 to GetArrayLength(aExecArr)-1 do begin
					if IsUninstaller() = false then begin
						// If app dir already exists while installing, skip add
						if (Pos(pathdir[d], aExecArr[i]) > 0) then
							updatepath := false;
							break;
					end else begin
						// If app dir exists and = what we originally set, then delete at uninstall
						if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then
							aExecArr[i] := '';
					end;
				end;
			end;

			// If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path
			if (IsUninstaller() = false) AND (updatepath = true) then begin
				SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True);

			// If uninstalling, write the full autoexec out
			end else begin
				SaveStringsToFile(aExecFile, aExecArr, False);
			end;
		end;
	end;
end;

// Split a string into an array using passed delimeter
procedure MPExplode(var Dest: TArrayOfString; Text: String; Separator: String);
var
	i: Integer;
begin
	i := 0;
	repeat
		SetArrayLength(Dest, i+1);
		if Pos(Separator,Text) > 0 then	begin
			Dest[i] := Copy(Text, 1, Pos(Separator, Text)-1);
			Text := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text));
			i := i + 1;
		end else begin
			 Dest[i] := Text;
			 Text := '';
		end;
	until Length(Text)=0;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
	taskname:	String;
begin
	taskname := ModPathName;
	if CurStep = ssPostInstall then
		if IsTaskSelected(taskname) then
			ModPath();
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
	aSelectedTasks:	TArrayOfString;
	i:				Integer;
	taskname:		String;
	regpath:		String;
	regstring:		String;
	appid:			String;
begin
	// only run during actual uninstall
	if CurUninstallStep = usUninstall then begin
		// get list of selected tasks saved in registry at install time
		appid := '{#emit SetupSetting("AppId")}';
		if appid = '' then appid := '{#emit SetupSetting("AppName")}';
		regpath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+appid+'_is1');
		RegQueryStringValue(HKLM, regpath, 'Inno Setup: Selected Tasks', regstring);
		if regstring = '' then RegQueryStringValue(HKCU, regpath, 'Inno Setup: Selected Tasks', regstring);

		// check each task; if matches modpath taskname, trigger patch removal
		if regstring <> '' then begin
			taskname := ModPathName;
			MPExplode(aSelectedTasks, regstring, ',');
			if GetArrayLength(aSelectedTasks) > 0 then begin
				for i := 0 to GetArrayLength(aSelectedTasks)-1 do begin
					if comparetext(aSelectedTasks[i], taskname) = 0 then
						ModPath();
				end;
			end;
		end;
	end;
end;

function NeedRestart(): Boolean;
var
	taskname:	String;
begin
	taskname := ModPathName;
	if IsTaskSelected(taskname) and not UsingWinNT() then begin
		Result := True;
	end else begin
		Result := False;
	end;
end;


build(windows): specify name of app in list of installed apps (#638)

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "ActivityWatch"
#define MyAppVersion GetEnv('AW_VERSION')
#define MyAppPublisher "ActivityWatch Contributors"
#define MyAppURL "https://activitywatch.net/"
#define MyAppExeName "aw-qt.exe"
#define RootDir "..\.."
#define DistDir "..\..\dist"

#pragma verboselevel 9

[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{F226B8F4-3244-46E6-901D-0CE8035423E4}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL="https://github.com/ActivityWatch/activitywatch/issues"
AppUpdatesURL="https://github.com/ActivityWatch/activitywatch/releases"
DefaultDirName={autopf}\{#MyAppName}
DisableProgramGroupPage=yes
; Uncomment the following line to run in non administrative install mode (install for current user only.)
PrivilegesRequired=lowest
PrivilegesRequiredOverridesAllowed=dialog
OutputDir={#DistDir}
OutputBaseFilename=activitywatch-setup
SetupIconFile="{#RootDir}\aw-qt\media\logo\logo.ico"
UninstallDisplayName={#MyAppName}
UninstallDisplayIcon={app}\{#MyAppExeName}
Compression=lzma
SolidCompression=yes
WizardStyle=modern

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "StartMenuEntry" ; Description: "Start ActivityWatch when Windows starts"; GroupDescription: "Windows Startup"; MinVersion: 4,4;

[Files]
Source: "{#DistDir}\activitywatch\aw-qt.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#DistDir}\activitywatch\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userstartup}\(#MyAppName)"; Filename: "{app}\{#MyAppExeName}"; Tasks: StartMenuEntry;

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

; Removes the previously installed version before installing the new one
; NOTE: Doesn't work? And also discouraged by the docs
;[InstallDelete]
;Type: filesandordirs; Name: "{app}\"

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "ActivityWatch"
#define MyAppVersion GetEnv('AW_VERSION')
#define MyAppPublisher "ActivityWatch Contributors"
#define MyAppURL "https://activitywatch.net/"
#define MyAppExeName "aw-qt.exe"
#define RootDir "..\.."
#define DistDir "..\..\dist"

#pragma verboselevel 9

[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{F226B8F4-3244-46E6-901D-0CE8035423E4}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL="https://github.com/ActivityWatch/activitywatch/issues"
AppUpdatesURL="https://github.com/ActivityWatch/activitywatch/releases"
DefaultDirName={autopf}\{#MyAppName}
DisableProgramGroupPage=yes
; Uncomment the following line to run in non administrative install mode (install for current user only.)
PrivilegesRequired=lowest
PrivilegesRequiredOverridesAllowed=dialog
OutputDir={#DistDir}
OutputBaseFilename=activitywatch-setup
SetupIconFile="{#RootDir}\aw-qt\media\logo\logo.ico"
UninstallDisplayIcon={app}\{#MyAppExeName}
Compression=lzma
SolidCompression=yes
WizardStyle=modern

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "StartMenuEntry" ; Description: "Start ActivityWatch when Windows starts"; GroupDescription: "Windows Startup"; MinVersion: 4,4;

[Files]
Source: "{#DistDir}\activitywatch\aw-qt.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#DistDir}\activitywatch\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userstartup}\(#MyAppName)"; Filename: "{app}\{#MyAppExeName}"; Tasks: StartMenuEntry;

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

; Removes the previously installed version before installing the new one
; NOTE: Doesn't work? And also discouraged by the docs
;[InstallDelete]
;Type: filesandordirs; Name: "{app}\"


Added athena_batch.exe to the windows installer script

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Athena"
#define MyAppVersion "6.3.0a1"
#define MyAppPublisher "Jet Propulsion Laboratory, California Institute of Technology"
#define MyAppExeName "athena.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{C6674C4E-EA24-4564-A280-DF3FEF793FAA}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultDirName={pf}\Athena {#MyAppVersion}
DefaultGroupName=Athena {#MyAppVersion}
LicenseFile=..\LICENSE
;InfoBeforeFile=before.txt
InfoAfterFile=after.txt
;OutputDir=
OutputBaseFilename=Athena{#MyAppVersion}_Installer
SetupIconFile=athena.ico
Compression=lzma
SolidCompression=yes
ChangesAssociations=yes
WizardImageFile=WizardLogo.bmp
WizardImageStretch=no
WizardSmallImageFile=SmallWizardLogo.bmp

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "..\bin\athena-{#MyAppVersion}-win32-ix86.exe"; DestDir: "{app}"; DestName: "athena.exe"; Flags: ignoreversion
Source: "..\bin\athena_batch-{#MyAppVersion}-win32-ix86.exe"; DestDir: "{app}"; DestName: "athena_batch.exe"; Flags: ignoreversion
Source: "..\docs\build_notes.html"; DestDir: "{app}\docs"; Flags: ignoreversion
Source: "..\docs\index.html"; DestDir: "{app}\docs"; Flags: ignoreversion
Source: "..\docs\*.png"; DestDir: "{app}\docs"; Flags: ignoreversion
Source: "..\docs\athena.helpdb"; DestDir: "{app}\docs"; Flags: ignoreversion
Source: "..\docs\man1\athena.html"; DestDir: "{app}\docs\man1"; Flags: ignoreversion
Source: "..\docs\man1\athena_batch.html"; DestDir: "{app}\docs\man1"; Flags: ignoreversion
Source: "..\docs\*.docx"; DestDir: "{app}\docs\dev"; Flags: ignoreversion
Source: "..\docs\*.pptx"; DestDir: "{app}\docs\dev"; Flags: ignoreversion skipifsourcedoesntexist
Source: "..\docs\*.pdf"; DestDir: "{app}\docs\dev"; Flags: ignoreversion skipifsourcedoesntexist
Source: "..\maps\*.png"; DestDir: "{app}\maps"; Flags: ignoreversion skipifsourcedoesntexist
Source: "..\maps\*.tif"; DestDir: "{app}\maps"; Flags: ignoreversion skipifsourcedoesntexist
Source: "..\data\polygons\*.npf"; DestDir: "{app}\data\polygons"; Flags: ignoreversion
Source: "..\data\polygons\*.kml"; DestDir: "{app}\data\polygons"; Flags: ignoreversion
Source: "..\data\messages\*.xml"; DestDir: "{app}\data\messages"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Dirs]
Name: "{app}\mods"
Name: "{userdocs}\Athena"

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; WorkingDir: "{userdocs}\Athena"
Name: "{group}\Athena Documentation"; Filename: "{app}\docs\index.html"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; WorkingDir: "{userdocs}\Athena"; Tasks: desktopicon

[Registry]
Root: HKCR; Subkey: ".adb"; ValueType: string; ValueName: ""; ValueData: "AthenaScenarioFile"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "AthenaScenarioFile"; ValueType: string; ValueName: ""; ValueData: "Athena Scenario File"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "AthenaScenarioFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\ATHENA.EXE,0"
Root: HKCR; Subkey: "AthenaScenarioFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\ATHENA.EXE"" ""%1"""

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; WorkingDir: "{userdocs}\Athena"; Flags: nowait postinstall skipifsilent

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Athena"
#define MyAppVersion "6.3.0a1"
#define MyAppPublisher "Jet Propulsion Laboratory, California Institute of Technology"
#define MyAppExeName "athena.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{C6674C4E-EA24-4564-A280-DF3FEF793FAA}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultDirName={pf}\Athena {#MyAppVersion}
DefaultGroupName=Athena {#MyAppVersion}
LicenseFile=..\LICENSE
;InfoBeforeFile=before.txt
InfoAfterFile=after.txt
;OutputDir=
OutputBaseFilename=Athena{#MyAppVersion}_Installer
SetupIconFile=athena.ico
Compression=lzma
SolidCompression=yes
ChangesAssociations=yes
WizardImageFile=WizardLogo.bmp
WizardImageStretch=no
WizardSmallImageFile=SmallWizardLogo.bmp

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "..\bin\athena-{#MyAppVersion}-win32-ix86.exe"; DestDir: "{app}"; DestName: "athena.exe"; Flags: ignoreversion
Source: "..\docs\build_notes.html"; DestDir: "{app}\docs"; Flags: ignoreversion
Source: "..\docs\index.html"; DestDir: "{app}\docs"; Flags: ignoreversion
Source: "..\docs\*.png"; DestDir: "{app}\docs"; Flags: ignoreversion
Source: "..\docs\athena.helpdb"; DestDir: "{app}\docs"; Flags: ignoreversion
Source: "..\docs\man1\athena.html"; DestDir: "{app}\docs\man1"; Flags: ignoreversion
Source: "..\docs\man1\athena_batch.html"; DestDir: "{app}\docs\man1"; Flags: ignoreversion
Source: "..\docs\*.docx"; DestDir: "{app}\docs\dev"; Flags: ignoreversion
Source: "..\docs\*.pptx"; DestDir: "{app}\docs\dev"; Flags: ignoreversion skipifsourcedoesntexist
Source: "..\docs\*.pdf"; DestDir: "{app}\docs\dev"; Flags: ignoreversion skipifsourcedoesntexist
Source: "..\maps\*.png"; DestDir: "{app}\maps"; Flags: ignoreversion skipifsourcedoesntexist
Source: "..\maps\*.tif"; DestDir: "{app}\maps"; Flags: ignoreversion skipifsourcedoesntexist
Source: "..\data\polygons\*.npf"; DestDir: "{app}\data\polygons"; Flags: ignoreversion
Source: "..\data\polygons\*.kml"; DestDir: "{app}\data\polygons"; Flags: ignoreversion
Source: "..\data\messages\*.xml"; DestDir: "{app}\data\messages"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Dirs]
Name: "{app}\mods"
Name: "{userdocs}\Athena"

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; WorkingDir: "{userdocs}\Athena"
Name: "{group}\Athena Documentation"; Filename: "{app}\docs\index.html"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; WorkingDir: "{userdocs}\Athena"; Tasks: desktopicon

[Registry]
Root: HKCR; Subkey: ".adb"; ValueType: string; ValueName: ""; ValueData: "AthenaScenarioFile"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "AthenaScenarioFile"; ValueType: string; ValueName: ""; ValueData: "Athena Scenario File"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "AthenaScenarioFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\ATHENA.EXE,0"
Root: HKCR; Subkey: "AthenaScenarioFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\ATHENA.EXE"" ""%1"""

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; WorkingDir: "{userdocs}\Athena"; Flags: nowait postinstall skipifsilent


installers.windows: Update Python installation detection

#define PLUGIN_TITLE "Export Layers"
#define INSTALLER_NAME PLUGIN_TITLE + " for GIMP"

[Setup]
AppName={#INSTALLER_NAME}
AppVersion={#PLUGIN_VERSION}
AppVerName={#INSTALLER_NAME} {#PLUGIN_VERSION}
AppPublisher={#AUTHOR_NAME}
DefaultDirName={code:GetPluginsDirpath}
DefaultGroupName=GIMP
DisableProgramGroupPage=Yes
DisableDirPage=Yes
UninstallFilesDir={app}\{#PLUGIN_NAME}
PrivilegesRequired=lowest
DirExistsWarning=no
OutputDir={#OUTPUT_DIRPATH}
OutputBaseFilename={#OUTPUT_FILENAME_PREFIX}
WizardSmallImageFile=logo_wizard.bmp
WizardImageFile=menu_path.bmp
SetupIconFile=icon_installer.ico
UninstallDisplayIcon=logo.ico

[Files]
Source: {#INPUT_DIRPATH}\*; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
Source: logo_wizard.bmp; Flags: dontcopy
Source: menu_path.bmp; Flags: dontcopy
Source: icon_installer.ico; Flags: dontcopy
Source: logo.ico; DestDir: "{app}\{#PLUGIN_NAME}"

[Icons]
Name: "{group}\Uninstall {#INSTALLER_NAME}"; Filename: "{uninstallexe}"; Flags: preventpinning

[Messages]
ReadyLabel2b=Click Install to continue with the installation of {#PLUGIN_TITLE}, or click Customize to modify the installation.
FinishedLabelNoIcons={#PLUGIN_TITLE} successfully installed. To run the plug-in, start GIMP (or restart if already running) and go to File → Export Layers.

[Code]

const
  GIMP_REG_PATH = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\GIMP-2_is1';
  GIMP_NOT_FOUND_MESSAGE = (
    'Could not find GIMP installation path.'
    + ' Please specify the path to GIMP and GIMP plug-ins manually.'
    + ' If GIMP is not installed, abort this installation and install GIMP first.');
  PYTHON_NOT_FOUND_IN_GIMP_MESSAGE = (
    'It appears that your GIMP installation does not support Python scripting.'
    + ' Please install GIMP with enabled support for Python scripting before proceeding.');
  MIN_REQUIRED_GIMP_VERSION_MAJOR = 2;
  MIN_REQUIRED_GIMP_VERSION_MINOR = 8;
  MIN_REQUIRED_GIMP_VERSION = '2.8';

type
  TVersionArray = array [0..1] of integer;

var
  PluginsDirpath: string;
  GimpDirpath: string;

  SelectDirsPage: TInputDirWizardPage;
  PluginsDirpathEdit: TEdit;
  GimpDirpathEdit: TEdit;

  IsGimpDirpathDetected: boolean;

  InstallerState: (Initialized, Customizing, ReadyToInstall);

  CustomizeButton: TNewButton;

procedure AddCustomizeToInstallPage; forward;
procedure OnCustomizeClicked(sender: TObject); forward;
function GetButtonWidthFitToCaption(caption: string; xSpacing: integer) : integer; forward;
procedure CreateSelectDirsPage; forward;

procedure CheckPythonScriptingEnabled; forward;
function GetLocalPluginsDirpath (const gimpVersionMajorMinor: TVersionArray; const gimpVersionMajorMinorStr: string) : string; forward;
function GetGimpVersionMajorMinor (const gimpVersion: string) : TVersionArray; forward;

function GetPluginsDirpath(value: string) : string;
begin
  Result := PluginsDirpath;
end;

function InitializeSetup() : boolean;
var
  gimpVersion: string;
  gimpVersionMajorMinor: TVersionArray;
  gimpVersionMajorMinorStr: string;
begin
  Result := True;

  InstallerState := Initialized;
  IsGimpDirpathDetected := True;

  if (not RegQueryStringValue(HKLM64, GIMP_REG_PATH, 'DisplayVersion', gimpVersion)
      and not RegQueryStringValue(HKLM32, GIMP_REG_PATH, 'DisplayVersion', gimpVersion)) then begin
    MsgBox(GIMP_NOT_FOUND_MESSAGE, mbInformation, MB_OK);
    IsGimpDirpathDetected := False;
    Exit;
  end;

  gimpVersionMajorMinor := GetGimpVersionMajorMinor(gimpVersion);
  gimpVersionMajorMinorStr := IntToStr(gimpVersionMajorMinor[0]) + '.' + IntToStr(gimpVersionMajorMinor[1]);

  if (gimpVersionMajorMinor[0] <= MIN_REQUIRED_GIMP_VERSION_MAJOR) and (gimpVersionMajorMinor[1] < MIN_REQUIRED_GIMP_VERSION_MINOR) then begin
    MsgBox(
      'GIMP version ' + gimpVersionMajorMinorStr + ' detected.'
      + ' To use {#PLUGIN_TITLE}, install GIMP ' + MIN_REQUIRED_GIMP_VERSION + ' or later.'
      + ' If you do have GIMP ' + MIN_REQUIRED_GIMP_VERSION + ' or later installed, '
      + 'specify the path to GIMP and GIMP plug-ins manually.'
      + ' Otherwise, abort this installation and install GIMP with a sufficient version first.',
      mbInformation,
      MB_OK);

      IsGimpDirpathDetected := False;
      Exit;
  end;

  PluginsDirpath := GetLocalPluginsDirpath(gimpVersionMajorMinor, gimpVersionMajorMinorStr);

  if (not RegQueryStringValue(HKLM64, GIMP_REG_PATH, 'InstallLocation', GimpDirpath)
      and not RegQueryStringValue(HKLM32, GIMP_REG_PATH, 'InstallLocation', GimpDirpath)) then begin
    MsgBox(GIMP_NOT_FOUND_MESSAGE, mbInformation, MB_OK);
    IsGimpDirpathDetected := False;
    Exit;
  end;

  CheckPythonScriptingEnabled();
end;

procedure InitializeWizard;
begin
  WizardForm.BackButton.visible := False;

  AddCustomizeToInstallPage();

  CreateSelectDirsPage();
end;

function NextButtonClick(curPageID: integer) : boolean;
begin
  Result := True;

  if curPageID = SelectDirsPage.ID then begin
    GimpDirpath := GimpDirpathEdit.Text;
    PluginsDirpath := PluginsDirpathEdit.Text;

    // `DefaultDirName` may be empty at this point, causing the installer to fail.
    WizardForm.DirEdit.Text := PluginsDirpath;

    CheckPythonScriptingEnabled();
  end;
end;

function BackButtonClick(curPageID: integer) : boolean;
begin
  Result := True;

  if curPageID = wpReady then
    InstallerState := Customizing;
end;

function ShouldSkipPage(pageID: Integer): Boolean;
begin
  Result := False;

  if (pageID <> wpReady) and IsGimpDirpathDetected and (InstallerState = Initialized) then
    Result := True
end;

procedure CurPageChanged(curPageID: Integer);
begin
  WizardForm.BackButton.visible := False;
  CustomizeButton.visible := curPageID = wpReady;

  if curPageID = wpReady then
    InstallerState := ReadyToInstall;
end;

procedure AddCustomizeToInstallPage;
begin
  CustomizeButton := TNewButton.Create(WizardForm);

  with CustomizeButton do begin
    Caption := 'Customize';
    Parent := WizardForm;
    Width := GetButtonWidthFitToCaption(Caption, 12);
    Height := WizardForm.NextButton.Height;
    Left := WizardForm.ClientWidth - (WizardForm.CancelButton.Left + WizardForm.CancelButton.Width);
    Top := WizardForm.NextButton.Top;

    OnClick := @OnCustomizeClicked;
  end;
end;

procedure OnCustomizeClicked(sender: TObject);
begin
  WizardForm.BackButton.OnClick(TNewButton(sender).Parent);
end;

function GetButtonWidthFitToCaption(caption: string; xSpacing: integer) : integer;
var
  dummyLabel: TNewStaticText;
  defaultWidth: integer;
begin
  dummyLabel := TNewStaticText.Create(WizardForm);

  dummyLabel.Autosize := True;
  dummyLabel.Caption := caption;

  defaultWidth := WizardForm.NextButton.Width;

  if defaultWidth >= dummyLabel.Width + ScaleX(xSpacing) then
    Result := defaultWidth
  else
    Result := dummyLabel.Width + ScaleX(xSpacing);

  dummyLabel.Free;
end;

procedure CreateSelectDirsPage;
var
  lastAddedDirIndex: integer;
begin
  SelectDirsPage := CreateInputDirPage(
    wpWelcome,
    'Select Location for GIMP and GIMP Plug-ins',
    '',
    'Specify the directory path to a working GIMP installation and the path to GIMP plug-ins (for the current user or system-wide).',
    False,
    'New Folder');

  lastAddedDirIndex := SelectDirsPage.Add('Path to GIMP installation');
  GimpDirpathEdit := SelectDirsPage.Edits[lastAddedDirIndex];
  SelectDirsPage.Values[0] := GimpDirpath;

  lastAddedDirIndex := SelectDirsPage.Add('Path to GIMP plug-ins');
  PluginsDirpathEdit := SelectDirsPage.Edits[lastAddedDirIndex];
  SelectDirsPage.Values[1] := PluginsDirpath;
end;

procedure CheckPythonScriptingEnabled;
var
  possiblePythonDirpaths: TStringList;
  i: integer;
  pythonPathFound: boolean;
begin
  pythonPathFound := False;

  possiblePythonDirpaths := TStringList.Create;
  possiblePythonDirpaths.Add(GimpDirpath + '\Python');
  possiblePythonDirpaths.Add(GimpDirpath + '\32\lib\python2.7');
  possiblePythonDirpaths.Add(GimpDirpath + '\lib\python2.7');

  for i := 0 to possiblePythonDirpaths.Count - 1 do begin
    if DirExists(possiblePythonDirpaths[i]) then begin
      pythonPathFound := True;
      break;
    end;
  end;

  possiblePythonDirpaths.Free;

  if not pythonPathFound then begin
    MsgBox(PYTHON_NOT_FOUND_IN_GIMP_MESSAGE, mbInformation, MB_OK);
    Abort();
  end;
end;

function GetLocalPluginsDirpath (const gimpVersionMajorMinor: TVersionArray; const gimpVersionMajorMinorStr: string) : string;
begin
  if (gimpVersionMajorMinor[0] <= 2) and (gimpVersionMajorMinor[1] < 9) then
    Result := ExpandConstant('{%USERPROFILE}') + '\.gimp-' + gimpVersionMajorMinorStr + '\plug-ins'
  else
    Result := ExpandConstant('{userappdata}') + '\GIMP\' + gimpVersionMajorMinorStr + '\plug-ins';
end;

function GetGimpVersionMajorMinor (const gimpVersion: string) : TVersionArray;
var
  versionNumberMajorMinor: TVersionArray;
  i: integer;
  versionNumberFields: array of integer;
  versionNumberFieldCurrentArrayIndex: integer;
  versionNumberFieldStartIndex: integer;
begin
  versionNumberFieldCurrentArrayIndex := 0;
  versionNumberFieldStartIndex := 1;

  for i := 1 to Length(gimpVersion) do begin
    if gimpVersion[i] = '.' then begin
      SetArrayLength(versionNumberFields, GetArrayLength(versionNumberFields) + 1);
      versionNumberFields[versionNumberFieldCurrentArrayIndex] := (
        StrToIntDef(
          Copy(
            gimpVersion, versionNumberFieldStartIndex, i - versionNumberFieldStartIndex), -1));
      versionNumberFieldCurrentArrayIndex := versionNumberFieldCurrentArrayIndex + 1;
      versionNumberFieldStartIndex := i + 1;
    end;
  end;

  if versionNumberFieldStartIndex <= Length(gimpVersion) then begin
    SetArrayLength(versionNumberFields, GetArrayLength(versionNumberFields) + 1);
    versionNumberFields[versionNumberFieldCurrentArrayIndex] := (
      StrToIntDef(
        Copy(
          gimpVersion, versionNumberFieldStartIndex, Length(gimpVersion) + 1 - versionNumberFieldStartIndex), -1));
  end;

  versionNumberMajorMinor[0] := versionNumberFields[0];
  versionNumberMajorMinor[1] := versionNumberFields[1];

  Result := versionNumberMajorMinor;
end;

#define PLUGIN_TITLE "Export Layers"
#define INSTALLER_NAME PLUGIN_TITLE + " for GIMP"

[Setup]
AppName={#INSTALLER_NAME}
AppVersion={#PLUGIN_VERSION}
AppVerName={#INSTALLER_NAME} {#PLUGIN_VERSION}
AppPublisher={#AUTHOR_NAME}
DefaultDirName={code:GetPluginsDirpath}
DefaultGroupName=GIMP
DisableProgramGroupPage=Yes
DisableDirPage=Yes
UninstallFilesDir={app}\{#PLUGIN_NAME}
PrivilegesRequired=lowest
DirExistsWarning=no
OutputDir={#OUTPUT_DIRPATH}
OutputBaseFilename={#OUTPUT_FILENAME_PREFIX}
WizardSmallImageFile=logo_wizard.bmp
WizardImageFile=menu_path.bmp
SetupIconFile=icon_installer.ico
UninstallDisplayIcon=logo.ico

[Files]
Source: {#INPUT_DIRPATH}\*; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
Source: logo_wizard.bmp; Flags: dontcopy
Source: menu_path.bmp; Flags: dontcopy
Source: icon_installer.ico; Flags: dontcopy
Source: logo.ico; DestDir: "{app}\{#PLUGIN_NAME}"

[Icons]
Name: "{group}\Uninstall {#INSTALLER_NAME}"; Filename: "{uninstallexe}"; Flags: preventpinning

[Messages]
ReadyLabel2b=Click Install to continue with the installation of {#PLUGIN_TITLE}, or click Customize to modify the installation.
FinishedLabelNoIcons={#PLUGIN_TITLE} successfully installed. To run the plug-in, start GIMP (or restart if already running) and go to File → Export Layers.

[Code]

const
  GIMP_REG_PATH = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\GIMP-2_is1';
  GIMP_NOT_FOUND_MESSAGE = (
    'Could not find GIMP installation path.'
    + ' Please specify the path to GIMP and GIMP plug-ins manually.'
    + ' If GIMP is not installed, abort this installation and install GIMP first.');
  PYTHON_NOT_FOUND_IN_GIMP_MESSAGE = (
    'It appears that your GIMP installation does not support Python scripting.'
    + ' Please install GIMP with enabled support for Python scripting before proceeding.');
  MIN_REQUIRED_GIMP_VERSION_MAJOR = 2;
  MIN_REQUIRED_GIMP_VERSION_MINOR = 8;
  MIN_REQUIRED_GIMP_VERSION = '2.8';

type
  TVersionArray = array [0..1] of integer;

var
  PluginsDirpath: string;
  GimpDirpath: string;

  SelectDirsPage: TInputDirWizardPage;
  PluginsDirpathEdit: TEdit;
  GimpDirpathEdit: TEdit;

  IsGimpDirpathDetected: boolean;

  InstallerState: (Initialized, Customizing, ReadyToInstall);

  CustomizeButton: TNewButton;

procedure AddCustomizeToInstallPage; forward;
procedure OnCustomizeClicked(sender: TObject); forward;
function GetButtonWidthFitToCaption(caption: string; xSpacing: integer) : integer; forward;
procedure CreateSelectDirsPage; forward;

procedure CheckPythonScriptingEnabled; forward;
function GetLocalPluginsDirpath (const gimpVersionMajorMinor: TVersionArray; const gimpVersionMajorMinorStr: string) : string; forward;
function GetGimpVersionMajorMinor (const gimpVersion: string) : TVersionArray; forward;

function GetPluginsDirpath(value: string) : string;
begin
  Result := PluginsDirpath;
end;

function InitializeSetup() : boolean;
var
  gimpVersion: string;
  gimpVersionMajorMinor: TVersionArray;
  gimpVersionMajorMinorStr: string;
begin
  Result := True;

  InstallerState := Initialized;
  IsGimpDirpathDetected := True;

  if (not RegQueryStringValue(HKLM64, GIMP_REG_PATH, 'DisplayVersion', gimpVersion)
      and not RegQueryStringValue(HKLM32, GIMP_REG_PATH, 'DisplayVersion', gimpVersion)) then begin
    MsgBox(GIMP_NOT_FOUND_MESSAGE, mbInformation, MB_OK);
    IsGimpDirpathDetected := False;
    Exit;
  end;

  gimpVersionMajorMinor := GetGimpVersionMajorMinor(gimpVersion);
  gimpVersionMajorMinorStr := IntToStr(gimpVersionMajorMinor[0]) + '.' + IntToStr(gimpVersionMajorMinor[1]);

  if (gimpVersionMajorMinor[0] <= MIN_REQUIRED_GIMP_VERSION_MAJOR) and (gimpVersionMajorMinor[1] < MIN_REQUIRED_GIMP_VERSION_MINOR) then begin
    MsgBox(
      'GIMP version ' + gimpVersionMajorMinorStr + ' detected.'
      + ' To use {#PLUGIN_TITLE}, install GIMP ' + MIN_REQUIRED_GIMP_VERSION + ' or later.'
      + ' If you do have GIMP ' + MIN_REQUIRED_GIMP_VERSION + ' or later installed, '
      + 'specify the path to GIMP and GIMP plug-ins manually.'
      + ' Otherwise, abort this installation and install GIMP with a sufficient version first.',
      mbInformation,
      MB_OK);

      IsGimpDirpathDetected := False;
      Exit;
  end;

  PluginsDirpath := GetLocalPluginsDirpath(gimpVersionMajorMinor, gimpVersionMajorMinorStr);

  if (not RegQueryStringValue(HKLM64, GIMP_REG_PATH, 'InstallLocation', GimpDirpath)
      and not RegQueryStringValue(HKLM32, GIMP_REG_PATH, 'InstallLocation', GimpDirpath)) then begin
    MsgBox(GIMP_NOT_FOUND_MESSAGE, mbInformation, MB_OK);
    IsGimpDirpathDetected := False;
    Exit;
  end;

  CheckPythonScriptingEnabled();
end;

procedure InitializeWizard;
begin
  WizardForm.BackButton.visible := False;

  AddCustomizeToInstallPage();

  CreateSelectDirsPage();
end;

function NextButtonClick(curPageID: integer) : boolean;
begin
  Result := True;

  if curPageID = SelectDirsPage.ID then begin
    GimpDirpath := GimpDirpathEdit.Text;
    PluginsDirpath := PluginsDirpathEdit.Text;

    // `DefaultDirName` may be empty at this point, causing the installer to fail.
    WizardForm.DirEdit.Text := PluginsDirpath;

    CheckPythonScriptingEnabled();
  end;
end;

function BackButtonClick(curPageID: integer) : boolean;
begin
  Result := True;

  if curPageID = wpReady then
    InstallerState := Customizing;
end;

function ShouldSkipPage(pageID: Integer): Boolean;
begin
  Result := False;

  if (pageID <> wpReady) and IsGimpDirpathDetected and (InstallerState = Initialized) then
    Result := True
end;

procedure CurPageChanged(curPageID: Integer);
begin
  WizardForm.BackButton.visible := False;
  CustomizeButton.visible := curPageID = wpReady;

  if curPageID = wpReady then
    InstallerState := ReadyToInstall;
end;

procedure AddCustomizeToInstallPage;
begin
  CustomizeButton := TNewButton.Create(WizardForm);

  with CustomizeButton do begin
    Caption := 'Customize';
    Parent := WizardForm;
    Width := GetButtonWidthFitToCaption(Caption, 12);
    Height := WizardForm.NextButton.Height;
    Left := WizardForm.ClientWidth - (WizardForm.CancelButton.Left + WizardForm.CancelButton.Width);
    Top := WizardForm.NextButton.Top;

    OnClick := @OnCustomizeClicked;
  end;
end;

procedure OnCustomizeClicked(sender: TObject);
begin
  WizardForm.BackButton.OnClick(TNewButton(sender).Parent);
end;

function GetButtonWidthFitToCaption(caption: string; xSpacing: integer) : integer;
var
  dummyLabel: TNewStaticText;
  defaultWidth: integer;
begin
  dummyLabel := TNewStaticText.Create(WizardForm);

  dummyLabel.Autosize := True;
  dummyLabel.Caption := caption;

  defaultWidth := WizardForm.NextButton.Width;

  if defaultWidth >= dummyLabel.Width + ScaleX(xSpacing) then
    Result := defaultWidth
  else
    Result := dummyLabel.Width + ScaleX(xSpacing);

  dummyLabel.Free;
end;

procedure CreateSelectDirsPage;
var
  lastAddedDirIndex: integer;
begin
  SelectDirsPage := CreateInputDirPage(
    wpWelcome,
    'Select Location for GIMP and GIMP Plug-ins',
    '',
    'Specify the directory path to a working GIMP installation and the path to GIMP plug-ins (for the current user or system-wide).',
    False,
    'New Folder');

  lastAddedDirIndex := SelectDirsPage.Add('Path to GIMP installation');
  GimpDirpathEdit := SelectDirsPage.Edits[lastAddedDirIndex];
  SelectDirsPage.Values[0] := GimpDirpath;

  lastAddedDirIndex := SelectDirsPage.Add('Path to GIMP plug-ins');
  PluginsDirpathEdit := SelectDirsPage.Edits[lastAddedDirIndex];
  SelectDirsPage.Values[1] := PluginsDirpath;
end;

procedure CheckPythonScriptingEnabled;
begin
  if not DirExists(GimpDirpath + '\Python') then begin
    MsgBox(PYTHON_NOT_FOUND_IN_GIMP_MESSAGE, mbInformation, MB_OK);
    Abort();
  end;
end;

function GetLocalPluginsDirpath (const gimpVersionMajorMinor: TVersionArray; const gimpVersionMajorMinorStr: string) : string;
begin
  if (gimpVersionMajorMinor[0] <= 2) and (gimpVersionMajorMinor[1] < 9) then
    Result := ExpandConstant('{%USERPROFILE}') + '\.gimp-' + gimpVersionMajorMinorStr + '\plug-ins'
  else
    Result := ExpandConstant('{userappdata}') + '\GIMP\' + gimpVersionMajorMinorStr + '\plug-ins';
end;

function GetGimpVersionMajorMinor (const gimpVersion: string) : TVersionArray;
var
  versionNumberMajorMinor: TVersionArray;
  i: integer;
  versionNumberFields: array of integer;
  versionNumberFieldCurrentArrayIndex: integer;
  versionNumberFieldStartIndex: integer;
begin
  versionNumberFieldCurrentArrayIndex := 0;
  versionNumberFieldStartIndex := 1;

  for i := 1 to Length(gimpVersion) do begin
    if gimpVersion[i] = '.' then begin
      SetArrayLength(versionNumberFields, GetArrayLength(versionNumberFields) + 1);
      versionNumberFields[versionNumberFieldCurrentArrayIndex] := (
        StrToIntDef(
          Copy(
            gimpVersion, versionNumberFieldStartIndex, i - versionNumberFieldStartIndex), -1));
      versionNumberFieldCurrentArrayIndex := versionNumberFieldCurrentArrayIndex + 1;
      versionNumberFieldStartIndex := i + 1;
    end;
  end;

  if versionNumberFieldStartIndex <= Length(gimpVersion) then begin
    SetArrayLength(versionNumberFields, GetArrayLength(versionNumberFields) + 1);
    versionNumberFields[versionNumberFieldCurrentArrayIndex] := (
      StrToIntDef(
        Copy(
          gimpVersion, versionNumberFieldStartIndex, Length(gimpVersion) + 1 - versionNumberFieldStartIndex), -1));
  end;

  versionNumberMajorMinor[0] := versionNumberFields[0];
  versionNumberMajorMinor[1] := versionNumberFields[1];

  Result := versionNumberMajorMinor;
end;


fix iss

fix iss

#define app "..\..\dist\win-unpacked"
#define modules "..\..\modules"
#define internals "..\..\internals"
#define executable "FIRST LEGO League TMS.exe"
#define add_firewall_rule "advfirewall firewall add rule protocol=tcp dir=in enable=yes action=allow profile=private"

[Setup]
AppName=FIRST LEGO League TMS
AppVersion=2.0-alpha
DefaultDirName=C:\FIRST_Lego_League_TMS
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64
DisableProgramGroupPage=yes

[Dirs]
Name: "{app}\data"
Name: "{app}\logs"
Name: "{app}\tmp"

[Files]
Source: "{#app}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs;
Source: "{#modules}\*"; DestDir: "{app}\modules"; Flags: ignoreversion recursesubdirs;
Source: "{#internals}\*"; DestDir: "{app}\internals"; Flags: ignoreversion recursesubdirs;

[Run]
Filename: "{sys}\netsh.exe";  StatusMsg: "Adding firewall rules..."; Parameters: "{#add_firewall_rule} name=""FIRST LEGO League TMS"" program=""{app}\{#executable}"""
Filename: "{sys}\netsh.exe";  StatusMsg: "Adding firewall rules..."; Parameters: "{#add_firewall_rule} name=""FIRST LEGO League TMS"" program=""{app}\internals\caddy\caddy.exe"""
Filename: "{sys}\netsh.exe";  StatusMsg: "Adding firewall rules..."; Parameters: "{#add_firewall_rule} name=""FIRST LEGO League TMS"" program=""{app}\internals\mongo\bin\mongod.exe"""

[Icons]
Name: "{commondesktop}\FIRST LEGO League TMS"; Filename: "{app}\{#executable}"
Name: "{commonprograms}\FIRST LEGO League TMS"; Filename: "{app}\{#executable}"

[UninstallDelete]
Type: filesandordirs; Name: "{app}\data"
Type: filesandordirs; Name: "{app}\logs"
Type: filesandordirs; Name: "{app}\tmp"

[UninstallRun]
Filename: "{sys}\netsh.exe";  StatusMsg: "Adding firewall rules..."; Parameters: "advfirewall firewall delete rule name=""FIRST LEGO League TMS"""

#define app "..\..\dist\win-unpacked"
#define modules "..\..\modules"
#define internals "..\..\internals"
#define executable "FIRST LEGO League TMS.exe"
#define add_firewall_rule "advfirewall firewall add rule name=""FIRST LEGO League TMS"" protocol=tcp dir=in enable=yes action=allow profile=private"

[Setup]
AppName=FIRST LEGO League TMS
AppVersion=2.0-alpha
DefaultDirName=C:\FIRST_Lego_League_TMS
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64
DisableProgramGroupPage=yes

[Dirs]
Name: "{app}\data"
Name: "{app}\logs"
Name: "{app}\tmp"

[Files]
Source: "{#app}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs;
Source: "{#modules}\*"; DestDir: "{app}\modules"; Flags: ignoreversion recursesubdirs;
Source: "{#internals}\*"; DestDir: "{app}\internals"; Flags: ignoreversion recursesubdirs;

[Run]
Filename: "{sys}\netsh.exe";  StatusMsg: "Adding firewall rules..."; Parameters: "{#add_firewall_rule} program=""{app}\{#executable}"""
Filename: "{sys}\netsh.exe";  StatusMsg: "Adding firewall rules..."; Parameters: "{#add_firewall_rule} program=""{app}\internals\caddy\caddy.exe"""
Filename: "{sys}\netsh.exe";  StatusMsg: "Adding firewall rules..."; Parameters: "{#add_firewall_rule} program=""{app}\internals\mongo\bin\mongod.exe"""

[Icons]
Name: "{commondesktop}\FIRST LEGO League TMS"; Filename: "{app}\{#executable}"
Name: "{commonprograms}\FIRST LEGO League TMS"; Filename: "{app}\{#executable}"

[UninstallDelete]
Type: filesandordirs; Name: "{app}\data"
Type: filesandordirs; Name: "{app}\logs"
Type: filesandordirs; Name: "{app}\tmp"

[UninstallRun]
Filename: "{sys}\netsh.exe";  StatusMsg: "Adding firewall rules..."; Parameters: "advfirewall firewall delete rule name=""FIRST LEGO League TMS"""


VersionInfoVersion added (to avoid "0.0.0.0"), compression set to "lzma/max"

; Basic setup script for the Inno Setup installer builder.  For more
; information on the free installer builder, see www.jrsoftware.org.
;
; This script was contributed by Tim Peters.
; The current version is used with Inno Setup 2.0.19.

[Setup]
AppName=Expat
AppId=expat
AppVersion=2.0.1
AppVerName=Expat 2.0.1
AppCopyright=Copyright  1998-2006 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers
AppPublisher=The Expat Developers
AppPublisherURL=http://www.libexpat.org/
AppSupportURL=http://www.libexpat.org/
AppUpdatesURL=http://www.libexpat.org/
UninstallDisplayName=Expat XML Parser 2.0.1
VersionInfoVersion=2.0.1

DefaultDirName={pf}\Expat 2.0.1
UninstallFilesDir={app}\Uninstall

Compression=lzma/max
SourceDir=..
OutputDir=win32
DisableStartupPrompt=yes
AllowNoIcons=yes
DisableProgramGroupPage=yes
DisableReadyPage=yes

[Files]
Flags: ignoreversion; Source: win32\bin\Release\xmlwf.exe;  DestDir: "{app}\Bin"
Flags: ignoreversion; Source: win32\MANIFEST.txt;           DestDir: "{app}"
Flags: ignoreversion; Source: Changes;                      DestDir: "{app}"; DestName: Changes.txt
Flags: ignoreversion; Source: COPYING;                      DestDir: "{app}"; DestName: COPYING.txt
Flags: ignoreversion; Source: README;                       DestDir: "{app}"; DestName: README.txt
Flags: ignoreversion; Source: doc\*.html;                   DestDir: "{app}\Doc"
Flags: ignoreversion; Source: doc\*.css;                    DestDir: "{app}\Doc"
Flags: ignoreversion; Source: doc\*.png;                    DestDir: "{app}\Doc"
Flags: ignoreversion; Source: win32\bin\Release\*.dll;      DestDir: "{app}\Bin"
Flags: ignoreversion; Source: win32\bin\Release\*.lib;      DestDir: "{app}\Bin"
Flags: ignoreversion; Source: expat.dsw;                    DestDir: "{app}\Source"
Flags: ignoreversion; Source: win32\README.txt;             DestDir: "{app}\Source"
Flags: ignoreversion; Source: bcb5\*.bp*;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: bcb5\*.mak;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: bcb5\*.def;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: bcb5\*.txt;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: bcb5\*.bat;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: lib\*.c;                      DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: lib\*.h;                      DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: lib\*.def;                    DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: lib\*.dsp;                    DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: examples\*.c;                 DestDir: "{app}\Source\examples"
Flags: ignoreversion; Source: examples\*.dsp;               DestDir: "{app}\Source\examples"
Flags: ignoreversion; Source: tests\*.c;                    DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\*.cpp;                  DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\*.h;                    DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\README.txt;             DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\benchmark\*.c;          DestDir: "{app}\Source\tests\benchmark"
Flags: ignoreversion; Source: tests\benchmark\*.ds*;        DestDir: "{app}\Source\tests\benchmark"
Flags: ignoreversion; Source: tests\benchmark\README.txt;   DestDir: "{app}\Source\tests\benchmark"
Flags: ignoreversion; Source: xmlwf\*.c*;                   DestDir: "{app}\Source\xmlwf"
Flags: ignoreversion; Source: xmlwf\*.h;                    DestDir: "{app}\Source\xmlwf"
Flags: ignoreversion; Source: xmlwf\*.dsp;                  DestDir: "{app}\Source\xmlwf"

[Messages]
WelcomeLabel1=Welcome to the Expat XML Parser Setup Wizard
WelcomeLabel2=This will install [name/ver] on your computer.%n%nExpat is an XML parser with a C-language API, and is primarily made available to allow developers to build applications which use XML using a portable API and fast implementation.%n%nIt is strongly recommended that you close all other applications you have running before continuing. This will help prevent any conflicts during the installation process.

; Basic setup script for the Inno Setup installer builder.  For more
; information on the free installer builder, see www.jrsoftware.org.
;
; This script was contributed by Tim Peters.
; The current version is used with Inno Setup 2.0.19.

[Setup]
AppName=Expat
AppId=expat
AppVersion=2.0.1
AppVerName=expat 2.0.1
AppCopyright=Copyright  1998-2006 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers
DefaultDirName={pf}\Expat 2.0.1
AppPublisher=The Expat Developers
AppPublisherURL=http://www.libexpat.org/
AppSupportURL=http://www.libexpat.org/
AppUpdatesURL=http://www.libexpat.org/
UninstallDisplayName=Expat XML Parser 2.0.1
UninstallFilesDir={app}\Uninstall

Compression=bzip/9
SourceDir=..
OutputDir=win32
DisableStartupPrompt=yes
AllowNoIcons=yes
DisableProgramGroupPage=yes
DisableReadyPage=yes

[Files]
Flags: ignoreversion; Source: win32\bin\Release\xmlwf.exe;  DestDir: "{app}\Bin"
Flags: ignoreversion; Source: win32\MANIFEST.txt;           DestDir: "{app}"
Flags: ignoreversion; Source: Changes;                      DestDir: "{app}"; DestName: Changes.txt
Flags: ignoreversion; Source: COPYING;                      DestDir: "{app}"; DestName: COPYING.txt
Flags: ignoreversion; Source: README;                       DestDir: "{app}"; DestName: README.txt
Flags: ignoreversion; Source: doc\*.html;                   DestDir: "{app}\Doc"
Flags: ignoreversion; Source: doc\*.css;                    DestDir: "{app}\Doc"
Flags: ignoreversion; Source: doc\*.png;                    DestDir: "{app}\Doc"
Flags: ignoreversion; Source: win32\bin\Release\*.dll;      DestDir: "{app}\Bin"
Flags: ignoreversion; Source: win32\bin\Release\*.lib;      DestDir: "{app}\Bin"
Flags: ignoreversion; Source: expat.dsw;                    DestDir: "{app}\Source"
Flags: ignoreversion; Source: win32\README.txt;             DestDir: "{app}\Source"
Flags: ignoreversion; Source: bcb5\*.bp*;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: bcb5\*.mak;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: bcb5\*.def;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: bcb5\*.txt;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: bcb5\*.bat;                   DestDir: "{app}\Source\bcb5"
Flags: ignoreversion; Source: lib\*.c;                      DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: lib\*.h;                      DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: lib\*.def;                    DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: lib\*.dsp;                    DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: examples\*.c;                 DestDir: "{app}\Source\examples"
Flags: ignoreversion; Source: examples\*.dsp;               DestDir: "{app}\Source\examples"
Flags: ignoreversion; Source: tests\*.c;                    DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\*.cpp;                  DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\*.h;                    DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\README.txt;             DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\benchmark\*.c;          DestDir: "{app}\Source\tests\benchmark"
Flags: ignoreversion; Source: tests\benchmark\*.ds*;        DestDir: "{app}\Source\tests\benchmark"
Flags: ignoreversion; Source: tests\benchmark\README.txt;   DestDir: "{app}\Source\tests\benchmark"
Flags: ignoreversion; Source: xmlwf\*.c*;                   DestDir: "{app}\Source\xmlwf"
Flags: ignoreversion; Source: xmlwf\*.h;                    DestDir: "{app}\Source\xmlwf"
Flags: ignoreversion; Source: xmlwf\*.dsp;                  DestDir: "{app}\Source\xmlwf"

[Messages]
WelcomeLabel1=Welcome to the Expat XML Parser Setup Wizard
WelcomeLabel2=This will install [name/ver] on your computer.%n%nExpat is an XML parser with a C-language API, and is primarily made available to allow developers to build applications which use XML using a portable API and fast implementation.%n%nIt is strongly recommended that you close all other applications you have running before continuing. This will help prevent any conflicts during the installation process.


fixed installation of system-wide DLLs

fixed installation of system-wide DLLs

; This script was first created by ISTool
; http://www.lerstad.com/istool/

[Setup]
OutputBaseFilename=poedit_DLLs
AppName=poEdit support DLLs

ChangesAssociations=false
AlwaysShowComponentsList=false
SourceDir=..
DefaultDirName={pf}\poEdit

UninstallIconName=Uninstall poEdit
AllowNoIcons=true
AlwaysCreateUninstallIcon=true
DisableAppendDir=false
UninstallStyle=modern
WizardStyle=modern

OutputDir=.

Compression=bzip

WindowShowCaption=false
WindowStartMaximized=false
FlatComponentsList=true
CreateAppDir=false
UsePreviousGroup=false
Uninstallable=false
UpdateUninstallLogAppName=false
AppVerName=poEdit support DLLs
DisableProgramGroupPage=true
DisableFinishedPage=false
DisableReadyMemo=false
DisableReadyPage=true
AdminPrivilegesRequired=true

[Files]
Source: extras\win32-runtime\msvcrt.dll; DestDir: {sys}; CopyMode: alwaysskipifsameorolder; Flags: restartreplace uninsneveruninstall
Source: extras\win32-runtime\50comupd.exe; DestDir: {tmp}; Flags: deleteafterinstall
Source: extras\win32-runtime\hhupd.exe; DestDir: {tmp}; Flags: deleteafterinstall

[Registry]

[Icons]

[Run]
Filename: {tmp}\50comupd.exe; Parameters: /Q; WorkingDir: {tmp}; StatusMsg: Installing Common Controls DLL...
Filename: {tmp}\hhupd.exe; Parameters: /Q; WorkingDir: {tmp}; StatusMsg: Installing MS HTML Help component...

[_ISTool]
EnableISX=true
UseAbsolutePaths=false

[Dirs]

[_ISToolPreCompile]

; This script was first created by ISTool
; http://www.lerstad.com/istool/

[Setup]
OutputBaseFilename=poedit_DLLs
AppName=poEdit support DLLs

ChangesAssociations=false
AlwaysShowComponentsList=false
SourceDir=..
DefaultDirName={pf}\poEdit

UninstallIconName=Uninstall poEdit
AllowNoIcons=true
AlwaysCreateUninstallIcon=true
DisableAppendDir=false
UninstallStyle=modern
WizardStyle=modern

OutputDir=.

Compression=bzip

WindowShowCaption=false
WindowStartMaximized=false
FlatComponentsList=true
CreateAppDir=false
UsePreviousGroup=false
Uninstallable=false
UpdateUninstallLogAppName=false
AppVerName=poEdit support DLLs
DisableProgramGroupPage=true
DisableFinishedPage=false
DisableReadyMemo=false
DisableReadyPage=true

[Files]
Source: c:\windows\system\msvcrt.dll; DestDir: {sys}; CopyMode: alwaysskipifsameorolder; Flags: sharedfile
Source: extras\win32-runtime\50comupd.exe; DestDir: {tmp}; Flags: deleteafterinstall
Source: extras\win32-runtime\hhupd.exe; DestDir: {tmp}; Flags: deleteafterinstall

[Registry]

[Icons]

[Run]
Filename: {tmp}\50comupd.exe; Parameters: /Q; WorkingDir: {tmp}; StatusMsg: Installing Common Controls DLL...
Filename: {tmp}\hhupd.exe; Parameters: /Q; WorkingDir: {tmp}; StatusMsg: Installing MS HTML Help component...

[_ISTool]
EnableISX=true
UseAbsolutePaths=false

[Dirs]

[_ISToolPreCompile]