remove convert_nv

remove convert_nv

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

#define MyAppName "AvNav"
#define MyAppVersion "1.0"
#define MyAppPublisher "Andreas Vogel"
#define MyAppURL "http://www.wellenvogel.de/software/avnav"
#define MyAppExeName "AvChartConvert.exe"
#define RegKey "SOFTWARE\AvNav"
#define PythonMSI "python-2.7.10.msi"
#define PythonCode "{{E2B51919-207A-43EB-AE78-733F9C6797C2}"
#define PythonDir "python"
#define GdalMSI "gdal-111-1500-core.msi"
#define GdalCode "{{A811F26E-D8EE-4DDB-8E23-ED5386E98695}"
#define GdalDir "gdal"
#define GdalPythonMSI "GDAL-1.11.0.win32-py2.7.msi"
#define GdalPythonCode "{{B086ED88-4BB5-46E0-9CDA-8AA8ED2BF906}"
#define PillowWhl "Pillow-3.0.0-cp27-none-win32.whl"
#define KeyInstalledPython "installedPython"
#define KeyInstalledGdal "installedGdal"
#define KeyUnistallBase "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"

[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={{832C93A9-F8FA-4EE4-9447-2645D4340A13}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
;OutputDir=C:\Users\andreas\Documents\GitHub\avnav\windows\installer
OutputBaseFilename=AvNavSetup
Compression=lzma
SolidCompression=yes
ChangesEnvironment=yes

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

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

[Files]
Source: "..\AvChartConvert.exe"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
Source: "..\avnav_server_home.xml"; DestDir: "{app}"; DestName: "avnav_server.xml"
Source: "..\..\server\*.py"; DestDir: "{app}\scripts"
Source: "..\..\chartconvert\*.py"; DestDir: "{app}\scripts" ; Excludes: "convert_nv.py"
Source: "..\..\chartconvert\tiler_tools\*.py"; DestDir: "{app}\scripts\tiler_tools"
Source: "..\..\chartconvert\tiler_tools\*.csv"; DestDir: "{app}\scripts\tiler_tools"
Source: "..\..\chartconvert\tiler_tools\*.html"; DestDir: "{app}\scripts\tiler_tools"
Source: "library\{#PythonMSI}"; DestDir: "{tmp}"
Source: "library\{#GdalMSI}"; DestDir: "{tmp}"
Source: "library\{#GdalPythonMSI}"; DestDir: "{tmp}"
Source: "library\{#PillowWhl}"; DestDir: "{tmp}"
Source: "..\..\viewer\avnav_min.js"; DestDir: "{app}\viewer"
Source: "..\..\viewer\loader.js"; DestDir: "{app}\viewer"
Source: "..\..\viewer\version.js"; DestDir: "{app}\viewer"
Source: "..\..\viewer\avnav_viewer.html"; DestDir: "{app}\viewer"
Source: "..\..\viewer\avnav_viewer.less"; DestDir: "{app}\viewer"
Source: "..\..\viewer\base.js"; DestDir: "{app}\viewer"
Source: "..\..\viewer\images\*.png"; DestDir: "{app}\viewer\images"
Source: "..\..\libraries\*"; DestDir: "{app}\libraries"; Flags: recursesubdirs; Excludes: "*.pyc,*debug.js"

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Flags: nowait postinstall skipifsilent; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\{#PythonMSI}"" /qb TARGETDIR=""{app}\{#PythonDir}"""; WorkingDir: "{tmp}"; Check: checkInstallPython
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\{#GdalMSI}"" /qb TARGETDIR=""{app}\{#GdalDir}"" INSTALLDIR=""{app}\{#GdalDir}"""; WorkingDir: "{tmp}"; Check: checkInstallGdal
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\{#GdalPythonMSI}"" /qb TARGETDIR=""{app}\{#GdalDir}"" INSTALLDIR=""{app}\{#GdalDir}"""; WorkingDir: "{tmp}"; Check: checkInstallGdal

[Registry]
Root: "HKLM"; Subkey: "{#RegKey}"; ValueType: string; ValueName: "InstallDir"; ValueData: "{app}"; Flags: createvalueifdoesntexist  uninsdeletekey
Root: "HKLM"; Subkey: "{#RegKey}"; ValueType: string; ValueName: "{#KeyInstalledPython}"; ValueData: "true"; Flags: createvalueifdoesntexist uninsdeletekey; Check: checkInstallPython
Root: "HKLM"; Subkey: "{#RegKey}"; ValueType: string; ValueName: "{#KeyInstalledGdal}"; ValueData: "true"; Flags: createvalueifdoesntexist uninsdeletekey;  Check: checkInstallGdal
Root: "HKCU"; Subkey: "Environment"; ValueType:string; ValueName:"GDAL_DATA"; ValueData:"{app}\gdal\gdal_data" ; Flags: preservestringtype ; Check: checkInstallGdal

[Code]

function findPip(): string;
var
val: string;
pip: string;
spos: integer;
begin
  Result:='';
  if RegQueryStringValue(HKEY_CLASSES_ROOT,'Python.File\shell\open\command','',val) then begin
       spos:=Pos('" ',val);
       if spos > 0 then begin
         val:=copy(val,1,spos);
       end;
       val:=RemoveQuotes(val);
       Log('val='+val);
       pip:=ExtractFilePath(val)+'\scripts\pip.exe';
       //MsgBox('found pip at '+pip,mbError, MB_OK);
       Result:=pip;
  end;
end;

function BoolToStr(ip:Boolean): string;
begin
  if ip then
  begin
    Result:='true';
  end else begin
    Result:='false';
  end;
end;

function isProductInstalled(ProductCode: String): Boolean;
var rkey:string;
begin
  rkey:=ExpandConstant('{#KeyUnistallBase}')+ProductCode;
  Log('isProductInstalled '+rkey);
  Result:=RegKeyExists(HKEY_LOCAL_MACHINE,rkey);
end;

var
OptionPage: TInputOptionWizardPage;
uninstallPython: Boolean;
uninstallGdal: Boolean;
procedure InitializeWizard;
var
subcap:String;
pythonInstalled:Boolean;
gdalInstalled: Boolean;

begin
  { Create the pages }
  subcap:='If select to install python/gdal the embedded python/gdal will become your default';
  pythonInstalled:=isProductInstalled(ExpandConstant('{#PythonCode}'));
  Log('pythonInstalled: '+BoolToStr(pythonInstalled));
  gdalInstalled:=isProductInstalled(ExpandConstant('{#GdalCode}'));
  Log('gdalInstalled: '+BoolToStr(gdalInstalled));
  if pythonInstalled then begin
    subcap:=subcap+#13+'HINT: Python 2.7 is already installed';
  end;
  if gdalInstalled then begin
    subcap:=subcap+#13+'HINT: gdal is already installed';
  end;
  OptionPage := CreateInputOptionPage(wpWelcome,
    'Install Python/GDAL', 'Select if you want to install the embedded python/gdal',
    subcap,
    True, False);
  OptionPage.AddEx('Install Python',0,false);
  OptionPage.AddEx('Install GDAL',0,false);
  OptionPage.Values[0]:= not pythonInstalled;
  OptionPage.Values[1]:= not gdalInstalled;
end;

function checkInstall(index:integer): Boolean;
begin
  Result:=OptionPage.Values[index];
end;

function checkInstallPython(): Boolean;
begin
  Result:=checkInstall(0);
end;

function checkInstallGdal(): Boolean;
begin
  Result:=checkInstall(1);
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
pip:string;
ResultCode: integer;
oldPath: string;
begin
  if CurStep = ssPostInstall then begin
    pip:=findPip();
    Log('pip found at '+pip);
    if FileExists(pip) then begin
       Exec(pip,'install "'+ExpandConstant('{tmp}\{#PillowWhl}')+'"','',SW_SHOW,ewWaitUntilTerminated, ResultCode);
       if ResultCode <> 0 then begin
         MsgBox('error during installing Pillow ',mbError, MB_OK);
       end
    end else begin
      MsgBox('unable to find pip for python, cannot install Pillow ',mbError, MB_OK);
    end;
    if checkInstallGdal() then begin
      oldpath:='';
      RegQueryStringValue(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
        'Path',oldpath);
      if Pos('gdal',oldpath) < 1 then begin
        RegWriteExpandStringValue(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
          'Path',oldpath+';'+ExpandConstant('{app}\{#GdalDir}'));
      end;
    end;
    //add path
  end;
end;

//check if a feature was installed by us
function CheckFeature(Name:String;Key:String): Boolean;
var
  path: String;
  isInstalledByUs: string;
  dirpath: string;
  rkey: string;
begin
  Result:= False;
  rkey:=ExpandConstant('{#RegKey}');
  if RegQueryStringValue(HKEY_LOCAL_MACHINE,rkey,Key,isInstalledByUs) then begin
    if isInstalledByUs = 'true' then begin
      if RegQueryStringValue(HKEY_LOCAL_MACHINE, rkey,'InstallDir', path) then  begin
        dirpath:=path+'\'+Name;
        Result:=DirExists(dirpath);
      end;
    end;
  end;
end;

//Deinstall functions
procedure DeinstallFeature(fkey:String);
var
  ResultCode: Integer;
begin
    Exec('msiexec.exe', '/x '+fkey+' /qb', '', SW_SHOW,
     ewWaitUntilTerminated, ResultCode)
    Log('Deinstall for '+fkey+' ended with '+IntToStr(ResultCode));
end;

function InitializeUninstall(): Boolean;
begin
  Result:=true;
  uninstallPython:=checkFeature(ExpandConstant('{#PythonDir}'),ExpandConstant('{#KeyInstalledPython}'));
  uninstallGdal:=checkFeature(ExpandConstant('{#GdalDir}'),ExpandConstant('{#KeyInstalledGdal}'));
end;
//take the uninstall id from the properties of the MSI
//getmsiinfo.py library\python-2.7.10.msi "ProductCode"
//would be better to check for the python install dir...
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usPostUninstall then begin
    if uninstallPython then
    begin
      DeinstallFeature(ExpandConstant('{#PythonCode}'));
    end;
    if uninstallGdal then
    begin
      DeinstallFeature(ExpandConstant('{#GdalCode}'));
      DeinstallFeature(ExpandConstant('{#GdalPythonCode}'));
    end;
  end;
end;

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

#define MyAppName "AvNav"
#define MyAppVersion "1.0"
#define MyAppPublisher "Andreas Vogel"
#define MyAppURL "http://www.wellenvogel.de/software/avnav"
#define MyAppExeName "AvChartConvert.exe"
#define RegKey "SOFTWARE\AvNav"
#define PythonMSI "python-2.7.10.msi"
#define PythonCode "{{E2B51919-207A-43EB-AE78-733F9C6797C2}"
#define PythonDir "python"
#define GdalMSI "gdal-111-1500-core.msi"
#define GdalCode "{{A811F26E-D8EE-4DDB-8E23-ED5386E98695}"
#define GdalDir "gdal"
#define GdalPythonMSI "GDAL-1.11.0.win32-py2.7.msi"
#define GdalPythonCode "{{B086ED88-4BB5-46E0-9CDA-8AA8ED2BF906}"
#define PillowWhl "Pillow-3.0.0-cp27-none-win32.whl"
#define KeyInstalledPython "installedPython"
#define KeyInstalledGdal "installedGdal"
#define KeyUnistallBase "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"

[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={{832C93A9-F8FA-4EE4-9447-2645D4340A13}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
;OutputDir=C:\Users\andreas\Documents\GitHub\avnav\windows\installer
OutputBaseFilename=AvNavSetup
Compression=lzma
SolidCompression=yes
ChangesEnvironment=yes

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

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

[Files]
Source: "..\AvChartConvert.exe"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
Source: "..\avnav_server_home.xml"; DestDir: "{app}"; DestName: "avnav_server.xml"
Source: "..\..\server\*.py"; DestDir: "{app}\scripts"
Source: "..\..\chartconvert\*.py"; DestDir: "{app}\scripts"
Source: "..\..\chartconvert\tiler_tools\*.py"; DestDir: "{app}\scripts\tiler_tools"
Source: "..\..\chartconvert\tiler_tools\*.csv"; DestDir: "{app}\scripts\tiler_tools"
Source: "..\..\chartconvert\tiler_tools\*.html"; DestDir: "{app}\scripts\tiler_tools"
Source: "library\{#PythonMSI}"; DestDir: "{tmp}"
Source: "library\{#GdalMSI}"; DestDir: "{tmp}"
Source: "library\{#GdalPythonMSI}"; DestDir: "{tmp}"
Source: "library\{#PillowWhl}"; DestDir: "{tmp}"
Source: "..\..\viewer\avnav_min.js"; DestDir: "{app}\viewer"
Source: "..\..\viewer\loader.js"; DestDir: "{app}\viewer"
Source: "..\..\viewer\version.js"; DestDir: "{app}\viewer"
Source: "..\..\viewer\avnav_viewer.html"; DestDir: "{app}\viewer"
Source: "..\..\viewer\avnav_viewer.less"; DestDir: "{app}\viewer"
Source: "..\..\viewer\base.js"; DestDir: "{app}\viewer"
Source: "..\..\viewer\images\*.png"; DestDir: "{app}\viewer\images"
Source: "..\..\libraries\*"; DestDir: "{app}\libraries"; Flags: recursesubdirs; Excludes: "*.pyc,*debug.js"

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Flags: nowait postinstall skipifsilent; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\{#PythonMSI}"" /qb TARGETDIR=""{app}\{#PythonDir}"""; WorkingDir: "{tmp}"; Check: checkInstallPython
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\{#GdalMSI}"" /qb TARGETDIR=""{app}\{#GdalDir}"" INSTALLDIR=""{app}\{#GdalDir}"""; WorkingDir: "{tmp}"; Check: checkInstallGdal
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\{#GdalPythonMSI}"" /qb TARGETDIR=""{app}\{#GdalDir}"" INSTALLDIR=""{app}\{#GdalDir}"""; WorkingDir: "{tmp}"; Check: checkInstallGdal

[Registry]
Root: "HKLM"; Subkey: "{#RegKey}"; ValueType: string; ValueName: "InstallDir"; ValueData: "{app}"; Flags: createvalueifdoesntexist  uninsdeletekey
Root: "HKLM"; Subkey: "{#RegKey}"; ValueType: string; ValueName: "{#KeyInstalledPython}"; ValueData: "true"; Flags: createvalueifdoesntexist uninsdeletekey; Check: checkInstallPython
Root: "HKLM"; Subkey: "{#RegKey}"; ValueType: string; ValueName: "{#KeyInstalledGdal}"; ValueData: "true"; Flags: createvalueifdoesntexist uninsdeletekey;  Check: checkInstallGdal
Root: "HKCU"; Subkey: "Environment"; ValueType:string; ValueName:"GDAL_DATA"; ValueData:"{app}\gdal\gdal_data" ; Flags: preservestringtype ; Check: checkInstallGdal

[Code]

function findPip(): string;
var
val: string;
pip: string;
spos: integer;
begin
  Result:='';
  if RegQueryStringValue(HKEY_CLASSES_ROOT,'Python.File\shell\open\command','',val) then begin
       spos:=Pos('" ',val);
       if spos > 0 then begin
         val:=copy(val,1,spos);
       end;
       val:=RemoveQuotes(val);
       Log('val='+val);
       pip:=ExtractFilePath(val)+'\scripts\pip.exe';
       //MsgBox('found pip at '+pip,mbError, MB_OK);
       Result:=pip;
  end;
end;

function BoolToStr(ip:Boolean): string;
begin
  if ip then
  begin
    Result:='true';
  end else begin
    Result:='false';
  end;
end;

function isProductInstalled(ProductCode: String): Boolean;
var rkey:string;
begin
  rkey:=ExpandConstant('{#KeyUnistallBase}')+ProductCode;
  Log('isProductInstalled '+rkey);
  Result:=RegKeyExists(HKEY_LOCAL_MACHINE,rkey);
end;

var
OptionPage: TInputOptionWizardPage;
uninstallPython: Boolean;
uninstallGdal: Boolean;
procedure InitializeWizard;
var
subcap:String;
pythonInstalled:Boolean;
gdalInstalled: Boolean;

begin
  { Create the pages }
  subcap:='If select to install python/gdal the embedded python/gdal will become your default';
  pythonInstalled:=isProductInstalled(ExpandConstant('{#PythonCode}'));
  Log('pythonInstalled: '+BoolToStr(pythonInstalled));
  gdalInstalled:=isProductInstalled(ExpandConstant('{#GdalCode}'));
  Log('gdalInstalled: '+BoolToStr(gdalInstalled));
  if pythonInstalled then begin
    subcap:=subcap+#13+'HINT: Python 2.7 is already installed';
  end;
  if gdalInstalled then begin
    subcap:=subcap+#13+'HINT: gdal is already installed';
  end;
  OptionPage := CreateInputOptionPage(wpWelcome,
    'Install Python/GDAL', 'Select if you want to install the embedded python/gdal',
    subcap,
    True, False);
  OptionPage.AddEx('Install Python',0,false);
  OptionPage.AddEx('Install GDAL',0,false);
  OptionPage.Values[0]:= not pythonInstalled;
  OptionPage.Values[1]:= not gdalInstalled;
end;

function checkInstall(index:integer): Boolean;
begin
  Result:=OptionPage.Values[index];
end;

function checkInstallPython(): Boolean;
begin
  Result:=checkInstall(0);
end;

function checkInstallGdal(): Boolean;
begin
  Result:=checkInstall(1);
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
pip:string;
ResultCode: integer;
oldPath: string;
begin
  if CurStep = ssPostInstall then begin
    pip:=findPip();
    Log('pip found at '+pip);
    if FileExists(pip) then begin
       Exec(pip,'install "'+ExpandConstant('{tmp}\{#PillowWhl}')+'"','',SW_SHOW,ewWaitUntilTerminated, ResultCode);
       if ResultCode <> 0 then begin
         MsgBox('error during installing Pillow ',mbError, MB_OK);
       end
    end else begin
      MsgBox('unable to find pip for python, cannot install Pillow ',mbError, MB_OK);
    end;
    if checkInstallGdal() then begin
      oldpath:='';
      RegQueryStringValue(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
        'Path',oldpath);
      if Pos('gdal',oldpath) < 1 then begin
        RegWriteExpandStringValue(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
          'Path',oldpath+';'+ExpandConstant('{app}\{#GdalDir}'));
      end;
    end;
    //add path
  end;
end;

//check if a feature was installed by us
function CheckFeature(Name:String;Key:String): Boolean;
var
  path: String;
  isInstalledByUs: string;
  dirpath: string;
  rkey: string;
begin
  Result:= False;
  rkey:=ExpandConstant('{#RegKey}');
  if RegQueryStringValue(HKEY_LOCAL_MACHINE,rkey,Key,isInstalledByUs) then begin
    if isInstalledByUs = 'true' then begin
      if RegQueryStringValue(HKEY_LOCAL_MACHINE, rkey,'InstallDir', path) then  begin
        dirpath:=path+'\'+Name;
        Result:=DirExists(dirpath);
      end;
    end;
  end;
end;

//Deinstall functions
procedure DeinstallFeature(fkey:String);
var
  ResultCode: Integer;
begin
    Exec('msiexec.exe', '/x '+fkey+' /qb', '', SW_SHOW,
     ewWaitUntilTerminated, ResultCode)
    Log('Deinstall for '+fkey+' ended with '+IntToStr(ResultCode));
end;

function InitializeUninstall(): Boolean;
begin
  Result:=true;
  uninstallPython:=checkFeature(ExpandConstant('{#PythonDir}'),ExpandConstant('{#KeyInstalledPython}'));
  uninstallGdal:=checkFeature(ExpandConstant('{#GdalDir}'),ExpandConstant('{#KeyInstalledGdal}'));
end;
//take the uninstall id from the properties of the MSI
//getmsiinfo.py library\python-2.7.10.msi "ProductCode"
//would be better to check for the python install dir...
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usPostUninstall then begin
    if uninstallPython then
    begin
      DeinstallFeature(ExpandConstant('{#PythonCode}'));
    end;
    if uninstallGdal then
    begin
      DeinstallFeature(ExpandConstant('{#GdalCode}'));
      DeinstallFeature(ExpandConstant('{#GdalPythonCode}'));
    end;
  end;
end;


win32: Add CMake files to Inno Setup

win32: Add CMake files to Inno Setup

; 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.
; It was designed for Inno Setup 2.0.19 but works with later versions as well.

#define expatVer "2.2.7"

[Setup]
AppName=Expat
AppId=expat
AppVersion={#expatVer}
AppVerName=Expat {#expatVer}
AppCopyright=Copyright © 1998-2017 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 {#expatVer}
VersionInfoVersion={#expatVer}
OutputBaseFilename=expat-win32bin-{#expatVer}

DefaultDirName={pf}\Expat {#expatVer}
UninstallFilesDir={app}\Uninstall

Compression=lzma
SolidCompression=yes
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: AUTHORS;                      DestDir: "{app}"; DestName: AUTHORS.txt
Flags: ignoreversion; Source: Changes;                      DestDir: "{app}"; DestName: Changes.txt
Flags: ignoreversion; Source: COPYING;                      DestDir: "{app}"; DestName: COPYING.txt
Flags: ignoreversion; Source: README.md;                    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.sln;                    DestDir: "{app}\Source"
Flags: ignoreversion; Source: win32\README.txt;             DestDir: "{app}\Source"
Flags: ignoreversion; Source: CMake.README;                 DestDir: "{app}\Source"
Flags: ignoreversion; Source: CMakeLists.txt;               DestDir: "{app}\Source"
Flags: ignoreversion; Source: ConfigureChecks.cmake;        DestDir: "{app}\Source"
Flags: ignoreversion; Source: expat_config.h.cmake;         DestDir: "{app}\Source"
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\*.vcxproj;                DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: lib\*.vcxproj.filters;        DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: examples\*.c;                 DestDir: "{app}\Source\examples"
Flags: ignoreversion; Source: examples\*.vcxproj;           DestDir: "{app}\Source\examples"
Flags: ignoreversion; Source: examples\*.vcxproj.filters;   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\*.sln;                  DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\*.vcxproj;              DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\*.vcxproj.filters;      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\*.sln;        DestDir: "{app}\Source\tests\benchmark"
Flags: ignoreversion; Source: tests\benchmark\*.vcxproj;    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\*.vcxproj;              DestDir: "{app}\Source\xmlwf"
Flags: ignoreversion; Source: xmlwf\*.vcxproj.filters;      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.
; It was designed for Inno Setup 2.0.19 but works with later versions as well.

#define expatVer "2.2.7"

[Setup]
AppName=Expat
AppId=expat
AppVersion={#expatVer}
AppVerName=Expat {#expatVer}
AppCopyright=Copyright © 1998-2017 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 {#expatVer}
VersionInfoVersion={#expatVer}
OutputBaseFilename=expat-win32bin-{#expatVer}

DefaultDirName={pf}\Expat {#expatVer}
UninstallFilesDir={app}\Uninstall

Compression=lzma
SolidCompression=yes
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: AUTHORS;                      DestDir: "{app}"; DestName: AUTHORS.txt
Flags: ignoreversion; Source: Changes;                      DestDir: "{app}"; DestName: Changes.txt
Flags: ignoreversion; Source: COPYING;                      DestDir: "{app}"; DestName: COPYING.txt
Flags: ignoreversion; Source: README.md;                    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.sln;                    DestDir: "{app}\Source"
Flags: ignoreversion; Source: win32\README.txt;             DestDir: "{app}\Source"
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\*.vcxproj;                DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: lib\*.vcxproj.filters;        DestDir: "{app}\Source\lib"
Flags: ignoreversion; Source: examples\*.c;                 DestDir: "{app}\Source\examples"
Flags: ignoreversion; Source: examples\*.vcxproj;           DestDir: "{app}\Source\examples"
Flags: ignoreversion; Source: examples\*.vcxproj.filters;   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\*.sln;                  DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\*.vcxproj;              DestDir: "{app}\Source\tests"
Flags: ignoreversion; Source: tests\*.vcxproj.filters;      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\*.sln;        DestDir: "{app}\Source\tests\benchmark"
Flags: ignoreversion; Source: tests\benchmark\*.vcxproj;    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\*.vcxproj;              DestDir: "{app}\Source\xmlwf"
Flags: ignoreversion; Source: xmlwf\*.vcxproj.filters;      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.


Changing name of setup executable.

Changing name of setup executable.

[Setup]
AppName=VHD Attach
AppVerName=VHD Attach 3.00 (beta 2)
DefaultDirName={pf}\Josip Medved\VHD Attach
OutputBaseFilename=vhdattach300b2
OutputDir=..\Releases
SourceDir=..\Binaries
AppId=JosipMedved_VhdAttach
AppMutex=Global\JosipMedved_VhdAttach
AppPublisher=Josip Medved
AppPublisherURL=http://www.jmedved.com/vhdattach/
UninstallDisplayIcon={app}\VhdAttach.exe
AlwaysShowComponentsList=no
ArchitecturesInstallIn64BitMode=x64
DisableProgramGroupPage=yes
MergeDuplicateFiles=yes
MinVersion=0,6.01.7200
PrivilegesRequired=admin
ShowLanguageDialog=no
SolidCompression=yes
ChangesAssociations=yes
DisableWelcomePage=yes

[Files]
Source: "VhdAttach.exe";         DestDir: "{app}";                      Flags: ignoreversion;
Source: "VhdAttachService.exe";  DestDir: "{app}";                      Flags: ignoreversion;
Source: "ReadMe.txt";            DestDir: "{app}";  Attribs: readonly;  Flags: overwritereadonly uninsremovereadonly;

[Tasks]
Name: context_attach;          GroupDescription: "Context menu items:";  Description: "Attach";
Name: context_attachreadonly;  GroupDescription: "Context menu items:";  Description: "Attach read-only";  Flags: unchecked;
Name: context_detach;          GroupDescription: "Context menu items:";  Description: "Detach";
Name: context_detachdrive;     GroupDescription: "Context menu items:";  Description: "Detach drive";      Flags: unchecked;

[Icons]
Name: "{userstartmenu}\VHD Attach";  Filename: "{app}\VhdAttach.exe"

[Registry]
Root: HKCU;  Subkey: "Software\Josip Medved";                                                                                Flags: uninsdeletekeyifempty
Root: HKCU;  Subkey: "Software\Josip Medved\VhdAttach";               ValueType: none;                                                                 Flags: deletekey uninsdeletekey;
Root: HKCU;  Subkey: "Software\Josip Medved\VHD Attach";              ValueType: dword;   ValueName: "Installed";         ValueData: "1";              Flags: uninsdeletekey

Root: HKCR;  Subkey: ".vhd";                                          ValueType: string;  ValueName: "";                  ValueData: "VhdAttachFile";  Flags: uninsclearvalue;

Root: HKCR;  Subkey: "VhdAttachFile";                                 ValueType: none;    Flags: uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile";                                 ValueType: string;  ValueName: "";                  ValueData: "Virtual Disk";

Root: HKCR;  Subkey: "VhdAttachFile\shell\Open";                      ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Open";                      ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";
Root: HKCR;  Subkey: "VhdAttachFile\shell\Open";                      ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Player";
Root: HKCR;  Subkey: "VhdAttachFile\shell\Open\command";              ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" ""%1""";

Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach";                    ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach";                    ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_attach;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach";                    ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Player";                                            Tasks: context_attach;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach\command";            ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /attach ""%1""";            Tasks: context_attach;

Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach read-only";          ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach read-only";          ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_attachreadonly;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach read-only";          ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Player";                                            Tasks: context_attachreadonly;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach read-only\command";  ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /readonly /attach ""%1""";  Tasks: context_attachreadonly;

Root: HKCR;  Subkey: "VhdAttachFile\shell\Detach";                    ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Detach";                    ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_detach;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Detach";                    ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Player";                                            Tasks: context_detach;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Detach\command";            ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /detach ""%1""";            Tasks: context_detach;

Root: HKCR;  Subkey: "Drive\shell\Detach";                            ValueType: none;    Flags: deletekey;
Root: HKCR;  Subkey: "Drive\shell\Detach drive";                      ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Drive\shell\Detach drive";                      ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_detachdrive;
Root: HKCR;  Subkey: "Drive\shell\Detach drive";                      ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Single";                                            Tasks: context_detachdrive;
Root: HKCR;  Subkey: "Drive\shell\Detach drive\command";              ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /detachdrive ""%1""";       Tasks: context_detachdrive;

[Run]
Filename: "{app}\VhdAttachService.exe";  Parameters: "/Install";  Flags: runascurrentuser waituntilterminated;
Filename: "{app}\ReadMe.txt";                                     Flags: postinstall runasoriginaluser shellexec nowait skipifsilent unchecked;  Description: "View ReadMe.txt";
Filename: "{app}\VhdAttach.exe";                                  Flags: postinstall nowait skipifsilent runasoriginaluser unchecked;            Description: "Launch application now";

[UninstallRun]
Filename: "{app}\VhdAttachService.exe";  Parameters: "/Uninstall";  Flags: runascurrentuser waituntilterminated

[Code]

function PrepareToInstall(var NeedsRestart: Boolean): String;
var
    ResultCode: Integer;
begin
    Exec(ExpandConstant('{app}\VhdAttachService.exe'), '/Uninstall', '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
end;

[Setup]
AppName=VHD Attach
AppVerName=VHD Attach 3.00 (beta 2)
DefaultDirName={pf}\Josip Medved\VHD Attach
OutputBaseFilename=vhdattach300b1
OutputDir=..\Releases
SourceDir=..\Binaries
AppId=JosipMedved_VhdAttach
AppMutex=Global\JosipMedved_VhdAttach
AppPublisher=Josip Medved
AppPublisherURL=http://www.jmedved.com/vhdattach/
UninstallDisplayIcon={app}\VhdAttach.exe
AlwaysShowComponentsList=no
ArchitecturesInstallIn64BitMode=x64
DisableProgramGroupPage=yes
MergeDuplicateFiles=yes
MinVersion=0,6.01.7200
PrivilegesRequired=admin
ShowLanguageDialog=no
SolidCompression=yes
ChangesAssociations=yes
DisableWelcomePage=yes

[Files]
Source: "VhdAttach.exe";         DestDir: "{app}";                      Flags: ignoreversion;
Source: "VhdAttachService.exe";  DestDir: "{app}";                      Flags: ignoreversion;
Source: "ReadMe.txt";            DestDir: "{app}";  Attribs: readonly;  Flags: overwritereadonly uninsremovereadonly;

[Tasks]
Name: context_attach;          GroupDescription: "Context menu items:";  Description: "Attach";
Name: context_attachreadonly;  GroupDescription: "Context menu items:";  Description: "Attach read-only";  Flags: unchecked;
Name: context_detach;          GroupDescription: "Context menu items:";  Description: "Detach";
Name: context_detachdrive;     GroupDescription: "Context menu items:";  Description: "Detach drive";      Flags: unchecked;

[Icons]
Name: "{userstartmenu}\VHD Attach";  Filename: "{app}\VhdAttach.exe"

[Registry]
Root: HKCU;  Subkey: "Software\Josip Medved";                                                                                Flags: uninsdeletekeyifempty
Root: HKCU;  Subkey: "Software\Josip Medved\VhdAttach";               ValueType: none;                                                                 Flags: deletekey uninsdeletekey;
Root: HKCU;  Subkey: "Software\Josip Medved\VHD Attach";              ValueType: dword;   ValueName: "Installed";         ValueData: "1";              Flags: uninsdeletekey

Root: HKCR;  Subkey: ".vhd";                                          ValueType: string;  ValueName: "";                  ValueData: "VhdAttachFile";  Flags: uninsclearvalue;

Root: HKCR;  Subkey: "VhdAttachFile";                                 ValueType: none;    Flags: uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile";                                 ValueType: string;  ValueName: "";                  ValueData: "Virtual Disk";

Root: HKCR;  Subkey: "VhdAttachFile\shell\Open";                      ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Open";                      ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";
Root: HKCR;  Subkey: "VhdAttachFile\shell\Open";                      ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Player";
Root: HKCR;  Subkey: "VhdAttachFile\shell\Open\command";              ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" ""%1""";

Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach";                    ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach";                    ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_attach;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach";                    ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Player";                                            Tasks: context_attach;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach\command";            ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /attach ""%1""";            Tasks: context_attach;

Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach read-only";          ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach read-only";          ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_attachreadonly;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach read-only";          ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Player";                                            Tasks: context_attachreadonly;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Attach read-only\command";  ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /readonly /attach ""%1""";  Tasks: context_attachreadonly;

Root: HKCR;  Subkey: "VhdAttachFile\shell\Detach";                    ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Detach";                    ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_detach;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Detach";                    ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Player";                                            Tasks: context_detach;
Root: HKCR;  Subkey: "VhdAttachFile\shell\Detach\command";            ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /detach ""%1""";            Tasks: context_detach;

Root: HKCR;  Subkey: "Drive\shell\Detach";                            ValueType: none;    Flags: deletekey;
Root: HKCR;  Subkey: "Drive\shell\Detach drive";                      ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Drive\shell\Detach drive";                      ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_detachdrive;
Root: HKCR;  Subkey: "Drive\shell\Detach drive";                      ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Single";                                            Tasks: context_detachdrive;
Root: HKCR;  Subkey: "Drive\shell\Detach drive\command";              ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /detachdrive ""%1""";       Tasks: context_detachdrive;

[Run]
Filename: "{app}\VhdAttachService.exe";  Parameters: "/Install";  Flags: runascurrentuser waituntilterminated;
Filename: "{app}\ReadMe.txt";                                     Flags: postinstall runasoriginaluser shellexec nowait skipifsilent unchecked;  Description: "View ReadMe.txt";
Filename: "{app}\VhdAttach.exe";                                  Flags: postinstall nowait skipifsilent runasoriginaluser unchecked;            Description: "Launch application now";

[UninstallRun]
Filename: "{app}\VhdAttachService.exe";  Parameters: "/Uninstall";  Flags: runascurrentuser waituntilterminated

[Code]

function PrepareToInstall(var NeedsRestart: Boolean): String;
var
    ResultCode: Integer;
begin
    Exec(ExpandConstant('{app}\VhdAttachService.exe'), '/Uninstall', '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
end;


Always show directory selection dialog in the Windows installer. Addresses #89.

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

#define MyAppName "MiniZinc IDE"
#define MyAppPublisher "Data61 and Monash University"
#define MyAppURL "http://www.minizinc.org"
#define MyAppExeName "MiniZincIDE.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={{80FFFA5B-5C33-442E-8C26-A8CD257EFD97}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
LicenseFile={#MyAppDirectory}\resources\misc\COMBINED_LICENSE.txt
DefaultDirName={pf}\MiniZinc
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
OutputBaseFilename=MiniZincIDE-{#MyAppVersion}-bundled-setup-{#MyAppArch}
Compression=lzma
SolidCompression=yes
ChangesAssociations=yes
ArchitecturesInstallIn64BitMode={#MyApp64Bit}
ArchitecturesAllowed={#MyAppArchitectures}
DisableDirPage=no

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

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

[Files]
Source: "{#MyAppDirectory}\ide\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyAppDirectory}\vendor\openssl\*.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MyAppDirectory}\resources\scripts\fzn-gecode-gist.bat"; DestDir: "{app}\bin"; Flags: ignoreversion

Source: "{#MyAppDirectory}\minizinc\bin\*.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MyAppDirectory}\minizinc\share\minizinc\*"; DestDir: "{app}\share\minizinc"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "{#MyAppDirectory}\resources\solvers\*.msc"; DestDir: "{app}\share\minizinc\solvers"; Flags: ignoreversion
Source: "{#MyAppDirectory}\resources\Preferences.json"; DestDir: "{app}\share\minizinc"; Flags: ignoreversion

Source: "{#MyAppDirectory}\vendor\gecode\bin\*"; DestDir: "{app}\bin"; Flags: ignoreversion
Source: "{#MyAppDirectory}\vendor\gecode\share\gecode\mznlib\*"; DestDir: "{app}\share\minizinc\gecode"; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyAppDirectory}\vendor\chuffed\bin\fzn-chuffed.exe"; DestDir:"{app}\bin"; Flags: ignoreversion
Source: "{#MyAppDirectory}\vendor\chuffed\share\chuffed\mznlib\*"; DestDir: "{app}\share\minizinc\chuffed"; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyAppDirectory}\globalizer\bin\minizinc-globalizer.exe"; DestDir:"{app}\bin"; Flags: ignoreversion
Source: "{#MyAppDirectory}\globalizer\share\globalizer\mznlib\*"; DestDir: "{app}\share\minizinc\globalizer"; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyAppDirectory}\findMUS\bin\findMUS.exe"; DestDir:"{app}\bin"; Flags: ignoreversion

Source: "{#MyMSVCRedist}\*.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MyUCRTRedist}\*.dll"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

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

[Registry]
Root: HKCR; Subkey: ".mzp"; ValueType: string; ValueName: ""; ValueData: "MiniZincProjectFile"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincProjectFile"; ValueType: string; ValueName: ""; ValueData: "MiniZinc project"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincProjectFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "MiniZincProjectFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

Root: HKCR; Subkey: ".mzn"; ValueType: string; ValueName: ""; ValueData: "MiniZincModelFile"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincModelFile"; ValueType: string; ValueName: ""; ValueData: "MiniZinc model"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincModelFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "MiniZincModelFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

Root: HKCR; Subkey: ".dzn"; ValueType: string; ValueName: ""; ValueData: "MiniZincDataFile"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincDataFile"; ValueType: string; ValueName: ""; ValueData: "MiniZinc data"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincDataFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "MiniZincDataFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

Root: HKCR; Subkey: ".fzn"; ValueType: string; ValueName: ""; ValueData: "MiniZincFlatZincFile"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincFlatZincFile"; ValueType: string; ValueName: ""; ValueData: "FlatZinc instance"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincFlatZincFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "MiniZincFlatZincFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

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

#define MyAppName "MiniZinc IDE"
#define MyAppPublisher "Data61 and Monash University"
#define MyAppURL "http://www.minizinc.org"
#define MyAppExeName "MiniZincIDE.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={{80FFFA5B-5C33-442E-8C26-A8CD257EFD97}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
LicenseFile={#MyAppDirectory}\resources\misc\COMBINED_LICENSE.txt
DefaultDirName={pf}\MiniZinc
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
OutputBaseFilename=MiniZincIDE-{#MyAppVersion}-bundled-setup-{#MyAppArch}
Compression=lzma
SolidCompression=yes
ChangesAssociations=yes
ArchitecturesInstallIn64BitMode={#MyApp64Bit}
ArchitecturesAllowed={#MyAppArchitectures}

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

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

[Files]
Source: "{#MyAppDirectory}\ide\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyAppDirectory}\vendor\openssl\*.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MyAppDirectory}\resources\scripts\fzn-gecode-gist.bat"; DestDir: "{app}\bin"; Flags: ignoreversion

Source: "{#MyAppDirectory}\minizinc\bin\*.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MyAppDirectory}\minizinc\share\minizinc\*"; DestDir: "{app}\share\minizinc"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "{#MyAppDirectory}\resources\solvers\*.msc"; DestDir: "{app}\share\minizinc\solvers"; Flags: ignoreversion
Source: "{#MyAppDirectory}\resources\Preferences.json"; DestDir: "{app}\share\minizinc"; Flags: ignoreversion

Source: "{#MyAppDirectory}\vendor\gecode\bin\*"; DestDir: "{app}\bin"; Flags: ignoreversion
Source: "{#MyAppDirectory}\vendor\gecode\share\gecode\mznlib\*"; DestDir: "{app}\share\minizinc\gecode"; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyAppDirectory}\vendor\chuffed\bin\fzn-chuffed.exe"; DestDir:"{app}\bin"; Flags: ignoreversion
Source: "{#MyAppDirectory}\vendor\chuffed\share\chuffed\mznlib\*"; DestDir: "{app}\share\minizinc\chuffed"; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyAppDirectory}\globalizer\bin\minizinc-globalizer.exe"; DestDir:"{app}\bin"; Flags: ignoreversion
Source: "{#MyAppDirectory}\globalizer\share\globalizer\mznlib\*"; DestDir: "{app}\share\minizinc\globalizer"; Flags: ignoreversion recursesubdirs createallsubdirs

Source: "{#MyAppDirectory}\findMUS\bin\findMUS.exe"; DestDir:"{app}\bin"; Flags: ignoreversion

Source: "{#MyMSVCRedist}\*.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MyUCRTRedist}\*.dll"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

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

[Registry]
Root: HKCR; Subkey: ".mzp"; ValueType: string; ValueName: ""; ValueData: "MiniZincProjectFile"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincProjectFile"; ValueType: string; ValueName: ""; ValueData: "MiniZinc project"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincProjectFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "MiniZincProjectFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

Root: HKCR; Subkey: ".mzn"; ValueType: string; ValueName: ""; ValueData: "MiniZincModelFile"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincModelFile"; ValueType: string; ValueName: ""; ValueData: "MiniZinc model"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincModelFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "MiniZincModelFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

Root: HKCR; Subkey: ".dzn"; ValueType: string; ValueName: ""; ValueData: "MiniZincDataFile"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincDataFile"; ValueType: string; ValueName: ""; ValueData: "MiniZinc data"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincDataFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "MiniZincDataFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""

Root: HKCR; Subkey: ".fzn"; ValueType: string; ValueName: ""; ValueData: "MiniZincFlatZincFile"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincFlatZincFile"; ValueType: string; ValueName: ""; ValueData: "FlatZinc instance"; Flags: uninsdeletevalue;
Root: HKCR; Subkey: "MiniZincFlatZincFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKCR; Subkey: "MiniZincFlatZincFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""


Forgot to include installer in previous commit.

#define MyAppName "pGina"
#define MyAppVersion "3.0.7.0"
#define MyAppPublisher "pGina Team"
#define MyAppURL "http://www.pgina.org/"
#define MyAppExeName "pGina.Configuration.exe"
#define MyAppSetupName 'pGina'
#define SetupScriptVersion '0'

; Use some useful packaging stuff from: http://tonaday.blogspot.com/2010/12/innosetup.html
// dotnet_Passive enabled shows the .NET/VC2010 installation progress, as it can take quite some time
#define dotnet_Passive
#define use_dotnetfx40
#define use_vc2010

// Enable the required define(s) below if a local event function (prepended with Local) is used
//#define haveLocalPrepareToInstall
//#define haveLocalNeedRestart
//#define haveLocalNextButtonClick

[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={{3D8D0F0D-7DBF-400C-9C44-00BD21986138}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} v{#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=true
LicenseFile=..\LICENSE
OutputBaseFilename=pGinaSetup-{#MyAppVersion}
SetupIconFile=..\Installer\pgina.ico
Compression=lzma/Max
SolidCompression=true
AppCopyright=pGina Team
ExtraDiskSpaceRequired=6
DisableDirPage=auto
AlwaysShowDirOnReadyPage=yes
AlwaysShowGroupOnReadyPage=yes
DisableProgramGroupPage=auto

ArchitecturesInstallIn64BitMode=x64 ia64

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

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

[Files]
Source: "..\pGina\src\bin\pGina.Configuration.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\pGina\src\bin\*.exe"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\pGina\src\bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\pGina\src\bin\*.xml"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\pGina\src\bin\*.config"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
;Source: "..\Plugins\bin\*.exe"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\Plugins\bin\*.dll"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
;Source: "..\Plugins\bin\*.xml"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
;Source: "..\Plugins\bin\*.config"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\pGina.Service.ServiceHost.exe"; Parameters: "--install"
Filename: "{app}\pGina.Service.ServiceHost.exe"; Parameters: "--start"
Filename: "{app}\pGina.CredentialProvider.Registration.exe"; Parameters: "--mode install"; WorkingDir: "{app}"
Filename: "{app}\pGina.CredentialProvider.Registration.exe"; Parameters: "--mode enable"; WorkingDir: "{app}"
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall skipifsilent runascurrentuser

[UninstallRun]
Filename: "{app}\pGina.Service.ServiceHost.exe"; Parameters: "--uninstall"
Filename: "{app}\pGina.Service.ServiceHost.exe"; Parameters: "--stop"
Filename: "{app}\pGina.CredentialProvider.Registration.exe"; Parameters: "--mode uninstall"; WorkingDir: "{app}"

; More custom stuff from [] for ensuring user gets everything needed
#include "scripts\products.iss"

#include "scripts\products\winversion.iss"
#include "scripts\products\fileversion.iss"

#ifdef use_dotnetfx40
#include "scripts\products\dotnetfx40client.iss"
#include "scripts\products\dotnetfx40full.iss"
#endif
#ifdef use_vc2010
#include "scripts\products\vc2010.iss"
#endif

#include "scripts\services.iss"

[CustomMessages]
win2000sp3_title=Windows 2000 Service Pack 3
winxpsp2_title=Windows XP Service Pack 2
winxpsp3_title=Windows XP Service Pack 3

#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed"+MyAppSetupname+SetupScriptVersion+".iss")

[Code]
function InitializeSetup(): Boolean;
begin
	//init windows version
	initwinversion();

	//check if dotnetfx20 can be installed on this OS
	//if not minwinspversion(5, 0, 3) then begin
	//	MsgBox(FmtMessage(CustomMessage('depinstall_missing'), [CustomMessage('win2000sp3_title')]), mbError, MB_OK);
	//	exit;
	//end;
	if not minwinspversion(5, 1, 3) then begin
		MsgBox(FmtMessage(CustomMessage('depinstall_missing'), [CustomMessage('winxpsp3_title')]), mbError, MB_OK);
		exit;
	end;

	// If no .NET 4.0 framework found, install the full thing
#ifdef use_dotnetfx40
	dotnetfx40full(false);
#endif

	// Visual C++ 2010 Redistributable
#ifdef use_vc2010
	vc2010();
#endif

	Result := true;
end;

procedure DoPreInstall();
begin
  // If our service is already installed, stop it!
  if IsServiceInstalled('pGina') = true then begin
		StopService('pGina');
	end
end;

procedure DoPostInstall();
begin
  // ...
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then begin
    DoPreInstall();
  end else if CurStep = ssPostInstall then begin
    DoPostInstall();
  end;
end;

#define MyAppName "pGina"
#define MyAppVersion "3.0.6.0"
#define MyAppPublisher "pGina Team"
#define MyAppURL "http://www.pgina.org/"
#define MyAppExeName "pGina.Configuration.exe"
#define MyAppSetupName 'pGina'
#define SetupScriptVersion '0'

; Use some useful packaging stuff from: http://tonaday.blogspot.com/2010/12/innosetup.html
// dotnet_Passive enabled shows the .NET/VC2010 installation progress, as it can take quite some time
#define dotnet_Passive
#define use_dotnetfx40
#define use_vc2010

// Enable the required define(s) below if a local event function (prepended with Local) is used
//#define haveLocalPrepareToInstall
//#define haveLocalNeedRestart
//#define haveLocalNextButtonClick

[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={{3D8D0F0D-7DBF-400C-9C44-00BD21986138}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} v{#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=true
LicenseFile=..\LICENSE
OutputBaseFilename=pGinaSetup-{#MyAppVersion}
SetupIconFile=..\Installer\pgina.ico
Compression=lzma/Max
SolidCompression=true
AppCopyright=pGina Team
ExtraDiskSpaceRequired=6
DisableDirPage=auto
AlwaysShowDirOnReadyPage=yes
AlwaysShowGroupOnReadyPage=yes
DisableProgramGroupPage=auto

ArchitecturesInstallIn64BitMode=x64 ia64

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

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

[Files]
Source: "..\pGina\src\bin\pGina.Configuration.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\pGina\src\bin\*.exe"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\pGina\src\bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\pGina\src\bin\*.xml"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\pGina\src\bin\*.config"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
;Source: "..\Plugins\bin\*.exe"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\Plugins\bin\*.dll"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
;Source: "..\Plugins\bin\*.xml"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
;Source: "..\Plugins\bin\*.config"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\pGina.Service.ServiceHost.exe"; Parameters: "--install"
Filename: "{app}\pGina.Service.ServiceHost.exe"; Parameters: "--start"
Filename: "{app}\pGina.CredentialProvider.Registration.exe"; Parameters: "--mode install"; WorkingDir: "{app}"
Filename: "{app}\pGina.CredentialProvider.Registration.exe"; Parameters: "--mode enable"; WorkingDir: "{app}"
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall skipifsilent runascurrentuser

[UninstallRun]
Filename: "{app}\pGina.Service.ServiceHost.exe"; Parameters: "--uninstall"
Filename: "{app}\pGina.Service.ServiceHost.exe"; Parameters: "--stop"
Filename: "{app}\pGina.CredentialProvider.Registration.exe"; Parameters: "--mode uninstall"; WorkingDir: "{app}"

; More custom stuff from [] for ensuring user gets everything needed
#include "scripts\products.iss"

#include "scripts\products\winversion.iss"
#include "scripts\products\fileversion.iss"

#ifdef use_dotnetfx40
#include "scripts\products\dotnetfx40client.iss"
#include "scripts\products\dotnetfx40full.iss"
#endif
#ifdef use_vc2010
#include "scripts\products\vc2010.iss"
#endif

#include "scripts\services.iss"

[CustomMessages]
win2000sp3_title=Windows 2000 Service Pack 3
winxpsp2_title=Windows XP Service Pack 2
winxpsp3_title=Windows XP Service Pack 3

#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed"+MyAppSetupname+SetupScriptVersion+".iss")

[Code]
function InitializeSetup(): Boolean;
begin
	//init windows version
	initwinversion();

	//check if dotnetfx20 can be installed on this OS
	//if not minwinspversion(5, 0, 3) then begin
	//	MsgBox(FmtMessage(CustomMessage('depinstall_missing'), [CustomMessage('win2000sp3_title')]), mbError, MB_OK);
	//	exit;
	//end;
	if not minwinspversion(5, 1, 3) then begin
		MsgBox(FmtMessage(CustomMessage('depinstall_missing'), [CustomMessage('winxpsp3_title')]), mbError, MB_OK);
		exit;
	end;

	// If no .NET 4.0 framework found, install the full thing
#ifdef use_dotnetfx40
	dotnetfx40full(false);
#endif

	// Visual C++ 2010 Redistributable
#ifdef use_vc2010
	vc2010();
#endif

	Result := true;
end;

procedure DoPreInstall();
begin
  // If our service is already installed, stop it!
  if IsServiceInstalled('pGina') = true then begin
		StopService('pGina');
	end
end;

procedure DoPostInstall();
begin
  // ...
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then begin
    DoPreInstall();
  end else if CurStep = ssPostInstall then begin
    DoPostInstall();
  end;
end;


Compression lzma

Compression lzma

Signed-off-by: Jeffrey Morgan <ed44c26e472545c167e88c1767e26e2a8b36f912@gmail.com>

#define MyAppName "Docker Toolbox"
#define MyAppPublisher "Docker"
#define MyAppURL "https://docker.com"
#define MyAppContact "https://docs.docker.com"

#define b2dIsoPath "..\bundle\boot2docker.iso"
#define dockerCli "..\bundle\docker.exe"
#define dockerMachineCli "..\bundle\docker-machine*.exe"
#define kitematic "..\bundle\kitematic"
#define git "..\bundle\Git.exe"
#define virtualBoxCommon "..\bundle\common.cab"
#define virtualBoxMsi "..\bundle\VirtualBox_amd64.msi"

[Setup]
AppCopyright={#MyAppPublisher}
AppId={{FC4417F0-D7F3-48DB-BCE1-F5ED5BAFFD91}
AppContact={#MyAppContact}
AppComments={#MyAppURL}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName=Docker
DisableProgramGroupPage=yes
OutputBaseFilename=DockerToolbox
Compression=lzma
SolidCompression=yes
WizardImageFile=windows-installer-side.bmp
WizardSmallImageFile=windows-installer-logo.bmp
WizardImageStretch=no
WizardImageBackColor=$22EBB8
UninstallDisplayIcon={app}\unins000.exe
SetupIconFile=toolbox.ico
ChangesEnvironment=true

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

[Types]
Name: "full"; Description: "Full installation"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Run]
Filename: "{win}\explorer.exe"; Parameters: "{userprograms}\Docker\"; Flags: postinstall skipifsilent; Description: "View Shortcuts in File Explorer"

[Tasks]
Name: desktopicon; Description: "{cm:CreateDesktopIcon}"
Name: modifypath; Description: "Add docker.exe & docker-machine.exe to &PATH"
Name: upgradevm; Description: "Upgrade or Migrate Boot2Docker VM to latest version of Docker if it exists."

[Components]
Name: "Docker"; Description: "Docker Client for Windows" ; Types: full custom; Flags: fixed
Name: "DockerMachine"; Description: "Docker Machine for Windows" ; Types: full custom; Flags: fixed
Name: "VirtualBox"; Description: "VirtualBox"; Types: full custom; Flags: disablenouninstallwarning
Name: "Kitematic"; Description: "Kitematic for Windows (Alpha)" ; Types: full custom
Name: "Git"; Description: "Git for Windows"; Types: full custom; Flags: disablenouninstallwarning

[Files]
Source: ".\docker-quickstart-terminal.ico"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#dockerCli}"; DestDir: "{app}"; Flags: ignoreversion; Components: "Docker"
Source: ".\start.sh"; DestDir: "{app}"; Flags: ignoreversion; Components: "Docker"
Source: ".\delete.sh"; DestDir: "{app}"; Flags: ignoreversion; Components: "Docker"
Source: "{#dockerMachineCli}"; DestDir: "{app}"; Flags: ignoreversion; Components: "DockerMachine"
Source: ".\migrate.sh"; DestDir: "{app}"; Flags: ignoreversion; Components: "DockerMachine"
Source: ".\migrate.bat"; DestDir: "{app}"; Flags: ignoreversion; Components: "DockerMachine"
Source: "{#kitematic}\*"; DestDir: "{app}\kitematic"; Flags: ignoreversion recursesubdirs; Components: "Kitematic"
Source: "{#b2dIsoPath}"; DestDir: "{app}"; Flags: ignoreversion; Components: "DockerMachine"; AfterInstall: CopyBoot2DockerISO()
Source: "{#git}"; DestDir: "{app}\installers\git"; DestName: "git.exe"; AfterInstall: RunInstallGit();  Components: "Git"
Source: "{#virtualBoxCommon}"; DestDir: "{app}\installers\virtualbox"; Components: "VirtualBox"
Source: "{#virtualBoxMsi}"; DestDir: "{app}\installers\virtualbox"; DestName: "virtualbox.msi"; AfterInstall: RunInstallVirtualBox(); Components: "VirtualBox"

[Icons]
Name: "{userprograms}\Docker\Kitematic (Alpha)"; WorkingDir: "{app}"; Filename: "{app}\kitematic\Kitematic.exe"; Components: "Kitematic"
Name: "{commondesktop}\Kitematic (Alpha)"; WorkingDir: "{app}"; Filename: "{app}\kitematic\Kitematic.exe"; Tasks: desktopicon; Components: "Kitematic"
Name: "{userprograms}\Docker\Docker Quickstart Terminal"; WorkingDir: "{app}"; Filename: "{pf64}\Git\git-bash.exe"; Parameters: """{app}\start.sh"""; IconFilename: "{app}/docker-quickstart-terminal.ico"; Components: "Docker"
Name: "{commondesktop}\Docker Quickstart Terminal"; WorkingDir: "{app}"; Filename: "{pf64}\Git\git-bash.exe"; Parameters: """{app}\start.sh"""; IconFilename: "{app}/docker-quickstart-terminal.ico"; Tasks: desktopicon; Components: "Docker"

[UninstallRun]
Filename: "{app}\delete.sh"

[UninstallDelete]
Type: filesandordirs; Name: "{localappdata}\..\Roaming\Kitematic"

[Code]
#include "base64.iss"
#include "guid.iss"

var
	restart: boolean;
  TrackingDisabled: Boolean;
	DockerInstallDocs: TLabel;
  TrackingCheckBox: TNewCheckBox;

function uuid(): String;
var
  dirpath: String;
  filepath: String;
  ansiresult: AnsiString;
begin
  dirpath := ExpandConstant('{userappdata}\DockerToolbox');
  filepath := dirpath + '\id.txt';
  ForceDirectories(dirpath);

  Result := '';
  if FileExists(filepath) then
    LoadStringFromFile(filepath, ansiresult);
    Result := String(ansiresult)

  if Length(Result) = 0 then
    Result := GetGuid('');
    StringChangeEx(Result, '{', '', True);
    StringChangeEx(Result, '}', '', True);
    SaveStringToFile(filepath, AnsiString(Result), False);
end;

function WindowsVersionString(): String;
var
	ResultCode: Integer;
	lines : TArrayOfString;
begin
	if not Exec(ExpandConstant('{cmd}'), ExpandConstant('/c wmic os get caption | more +1 > C:\windows-version.txt'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then begin
		Result := 'N/A';
		exit;
	end;

	if LoadStringsFromFile(ExpandConstant('C:\windows-version.txt'), lines) then begin
		Result := lines[0];
	end else begin
		Result := 'N/A'
	end;
end;

procedure TrackEvent(name: String);
var
  payload: String;
  WinHttpReq: Variant;
begin
  if TrackingDisabled or WizardSilent() then
    exit;
  try
    payload := Encode64(Format(ExpandConstant('{{"event": "%s", "properties": {{"token": "{#MixpanelToken}", "distinct_id": "%s", "os": "win32", "os version": "%s", "version": "{#MyAppVersion}"}}'), [name, uuid(), WindowsVersionString()]));
    WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
    WinHttpReq.Open('POST', 'https://api.mixpanel.com/track/?data=' + payload, false);
    WinHttpReq.SetRequestHeader('Content-Type', 'application/json');
    WinHttpReq.Send('');
  except
  end;
end;

function NeedRestart(): Boolean;
begin
	Result := restart;
end;

function NeedToInstallVirtualBox(): Boolean;
begin
	// TODO: Also compare versions
	Result := (
		(GetEnv('VBOX_INSTALL_PATH') = '')
		and
		(GetEnv('VBOX_MSI_INSTALL_PATH') = '')
	);
end;

function VBoxPath(): String;
begin
	if GetEnv('VBOX_INSTALL_PATH') <> '' then
		Result := GetEnv('VBOX_INSTALL_PATH')
	else
		Result := GetEnv('VBOX_MSI_INSTALL_PATH')
end;

function NeedToInstallGit(): Boolean;
begin
	// TODO: Find a better way to see if Git is installed
	Result := not DirExists('C:\Program Files\Git') or not FileExists('C:\Program Files\Git\git-bash.exe')
end;

procedure DocLinkClick(Sender: TObject);
var
	ErrorCode: Integer;
begin
	ShellExec('', 'https://docs.docker.com/installation/windows/', '', '', SW_SHOW, ewNoWait, ErrorCode);
end;

procedure TrackingCheckBoxClicked(Sender: TObject);
begin
  if TrackingCheckBox.Checked then begin
		TrackingDisabled := False;
    TrackEvent('Enabled Tracking');
  end else begin
    TrackEvent('Disabled Tracking');
    TrackingDisabled := True;
  end;
end;

procedure InitializeWizard;
var
  WelcomePage: TWizardPage;
	TrackingLabel: TLabel;
begin
	DockerInstallDocs := TLabel.Create(WizardForm);
	DockerInstallDocs.Parent := WizardForm;
	DockerInstallDocs.Left := 8;
	DockerInstallDocs.Top := WizardForm.ClientHeight - DockerInstallDocs.ClientHeight - 8;
	DockerInstallDocs.Cursor := crHand;
	DockerInstallDocs.Font.Color := clBlue;
	DockerInstallDocs.Font.Style := [fsUnderline];
	DockerInstallDocs.Caption := '{#MyAppName} installation documentation';
	DockerInstallDocs.OnClick := @DocLinkClick;
	DockerInstallDocs.Visible := True;

  WelcomePage := PageFromID(wpWelcome)

	WizardForm.WelcomeLabel2.AutoSize := True;

  TrackingCheckBox := TNewCheckBox.Create(WizardForm);
  TrackingCheckBox.Top := 168;
  TrackingCheckBox.Left := WizardForm.WelcomeLabel2.Left;
  TrackingCheckBox.Width := WizardForm.WelcomeLabel2.Width;
  TrackingCheckBox.Height := 40;
  TrackingCheckBox.Caption := 'Help Docker improve Toolbox.';
  TrackingCheckBox.Checked := True;
  TrackingCheckBox.Parent := WelcomePage.Surface;
  TrackingCheckBox.OnClick := @TrackingCheckboxClicked;

	TrackingLabel := TLabel.Create(WizardForm);
	TrackingLabel.Parent := WelcomePage.Surface;
	TrackingLabel.Font := WizardForm.WelcomeLabel2.Font;
	TrackingLabel.Font.Color := clGray;
  TrackingLabel.Caption := 'This collects annoymous data to help us detect installation problems and improve the overall experience. We only use it to aggregate statistics and will never share it with third parties.';
	TrackingLabel.WordWrap := True;
	TrackingLabel.Visible := True;
	TrackingLabel.Left := WizardForm.WelcomeLabel2.Left;
	TrackingLabel.Width := WizardForm.WelcomeLabel2.Width;
	TrackingLabel.Top := 200;
	TrackingLabel.Height := 100;

		// Don't do this until we can compare versions
		Wizardform.ComponentsList.Checked[2] := NeedToInstallVirtualBox();
		Wizardform.ComponentsList.ItemEnabled[2] := not NeedToInstallVirtualBox();
		Wizardform.ComponentsList.Checked[4] := NeedToInstallGit();
		Wizardform.ComponentsList.ItemEnabled[4] := not NeedToInstallGit();
end;

function InitializeSetup(): boolean;
begin
  TrackEvent('Installer Started');
  Result := True;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  if CurPageID = wpWelcome then begin
      TrackEvent('Continued from Overview');
  end;
  Result := True
end;

procedure RunInstallVirtualBox();
var
	ResultCode: Integer;
begin
	WizardForm.FilenameLabel.Caption := 'installing VirtualBox'
	if not Exec(ExpandConstant('msiexec'), ExpandConstant('/qn /i "{app}\installers\virtualbox\virtualbox.msi" /norestart'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
		MsgBox('virtualbox install failure', mbInformation, MB_OK);
end;

procedure RunInstallGit();
var
	ResultCode: Integer;
begin
	WizardForm.FilenameLabel.Caption := 'installing Git for Windows'
	if Exec(ExpandConstant('{app}\installers\git\git.exe'), '/sp- /verysilent /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
	begin
		// handle success if necessary; ResultCode contains the exit code
		//MsgBox('git installed OK', mbInformation, MB_OK);
	end
	else begin
		// handle failure if necessary; ResultCode contains the error code
		MsgBox('git install failure', mbInformation, MB_OK);
	end;
end;

procedure CopyBoot2DockerISO();
begin
  WizardForm.FilenameLabel.Caption := 'copying boot2docker iso'
  if not ForceDirectories(ExpandConstant('{userdocs}\..\.docker\machine\cache')) then
      MsgBox('Failed to create docker machine cache dir', mbError, MB_OK);
  if not FileCopy(ExpandConstant('{app}\boot2docker.iso'), ExpandConstant('{userdocs}\..\.docker\machine\cache\boot2docker.iso'), false) then
      MsgBox('File moving failed!', mbError, MB_OK);
end;

function CanUpgradeVM(): Boolean;
var
	ResultCode: Integer;
begin
	if NeedToInstallVirtualBox() or not FileExists(ExpandConstant('{app}\docker-machine.exe')) then begin
		Result := false
		exit
	end;

	ExecAsOriginalUser(VBoxPath() + 'VBoxManage.exe', 'showvminfo default', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
	if ResultCode <> 0 then begin
		Result := false
		exit
	end;

	if not DirExists(ExpandConstant('{userdocs}\..\.docker\machine\machines\default')) then begin
		Result := false
		exit
	end;

	Result := true
end;

function UpgradeVM() : Boolean;
var
	ResultCode: Integer;
begin
	TrackEvent('VM Upgrade Started');
	WizardForm.StatusLabel.Caption := 'Upgrading Docker Toolbox VM...'
	ExecAsOriginalUser(ExpandConstant('{app}\docker-machine.exe'), 'stop default', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
	if ResultCode = 0 then
	begin
		FileCopy(ExpandConstant('{userdocs}\..\.docker\machine\cache\boot2docker.iso'), ExpandConstant('{userdocs}\..\.docker\machine\machines\default\boot2docker.iso'), false)
		TrackEvent('VM Upgrade Succeeded');
	end
	else begin
		TrackEvent('VM Upgrade Failed');
		MsgBox('VM Upgrade Failed because the VirtualBox VM could not be stopped.', mbCriticalError, MB_OK);
		Result := false
		WizardForm.Close;
		exit;
	end;
	Result := true
end;

function MigrateVM() : Boolean;
var
  ResultCode: Integer;
begin
	if NeedToInstallGit() or NeedToInstallVirtualBox() or not FileExists(ExpandConstant('{app}\docker-machine.exe')) then begin
		Result := true
		exit
	end;

	ExecAsOriginalUser(VBoxPath() + 'VBoxManage.exe', 'showvminfo default', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
	if ResultCode <> 1 then begin
		Result := true
		exit
	end;

	ExecAsOriginalUser(VBoxPath() + 'VBoxManage.exe', 'showvminfo boot2docker-vm', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
	if ResultCode <> 0 then begin
		Result := true
		exit
	end;

  if MsgBox('Migrate your existing Boot2Docker VM to work with the Docker Toolbox? Your existing Boot2Docker VM will not be affected. This should take about a minute.', mbConfirmation, MB_YESNO) = IDYES then
  begin
		TrackEvent('Boot2Docker Migration Started');
    WizardForm.StatusLabel.Caption := 'Migrating Boot2Docker VM...'
    WizardForm.FilenameLabel.Caption := 'This will take a minute...'
    ExecAsOriginalUser(ExpandConstant('{app}\docker-machine.exe'), ExpandConstant('rm -f default > nul 2>&1'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
    DelTree(ExpandConstant('{userdocs}\..\.docker\machine\machines\default'), True, True, True);
    ExecAsOriginalUser(ExpandConstant('{app}\migrate.bat'), ExpandConstant('> {localappdata}\Temp\toolbox-migration-logs.txt 2>&1'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
    if ResultCode = 0 then
    begin
      TrackEvent('Boot2Docker Migration Succeeded');
      MsgBox('Succcessfully migrated Boot2Docker VM to a Docker Machine VM named "default"', mbInformation, MB_OK);
    end
    else begin
      TrackEvent('Boot2Docker Migration Failed');
      MsgBox('Migration of Boot2Docker VM failed. Please file an issue with the migration logs at https://github.com/docker/toolbox/issues/new.', mbCriticalError, MB_OK);
      Exec(ExpandConstant('{win}\notepad.exe'), ExpandConstant('{localappdata}\Temp\toolbox-migration-logs.txt'), '', SW_SHOW, ewNoWait, ResultCode)
      Result := false
			WizardForm.Close;
      exit;
    end;
  end
  else
  begin
    TrackEvent('Boot2Docker Migration Skipped');
  end;
  Result := true
end;

const
	ModPathName = 'modifypath';
	ModPathType = 'user';

function ModPathDir(): TArrayOfString;
begin
	setArrayLength(Result, 1);
	Result[0] := ExpandConstant('{app}');
end;
#include "modpath.iss"

procedure CurStepChanged(CurStep: TSetupStep);
var
	Success: Boolean;
begin
	Success := True;
	if CurStep = ssPostInstall then
  begin
    if IsTaskSelected(ModPathName) then
			ModPath();
    if not WizardSilent() then
		begin
			if IsTaskSelected('upgradevm') then
			begin
				if CanUpgradeVM() then begin
					Success := UpgradeVM();
				end
				else begin
					Success := MigrateVM();
				end;
			end;
		end;

		if Success then
			trackEvent('Installer Finished');
  end;
end;

#define MyAppName "Docker Toolbox"
#define MyAppPublisher "Docker"
#define MyAppURL "https://docker.com"
#define MyAppContact "https://docs.docker.com"

#define b2dIsoPath "..\bundle\boot2docker.iso"
#define dockerCli "..\bundle\docker.exe"
#define dockerMachineCli "..\bundle\docker-machine*.exe"
#define kitematic "..\bundle\kitematic"
#define git "..\bundle\Git.exe"
#define virtualBoxCommon "..\bundle\common.cab"
#define virtualBoxMsi "..\bundle\VirtualBox_amd64.msi"

[Setup]
AppCopyright={#MyAppPublisher}
AppId={{FC4417F0-D7F3-48DB-BCE1-F5ED5BAFFD91}
AppContact={#MyAppContact}
AppComments={#MyAppURL}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName=Docker
DisableProgramGroupPage=yes
OutputBaseFilename=DockerToolbox
// Compression=lzma
Compression=none
SolidCompression=yes
WizardImageFile=windows-installer-side.bmp
WizardSmallImageFile=windows-installer-logo.bmp
WizardImageStretch=no
WizardImageBackColor=$22EBB8
UninstallDisplayIcon={app}\unins000.exe
SetupIconFile=toolbox.ico
ChangesEnvironment=true

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

[Types]
Name: "full"; Description: "Full installation"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Run]
Filename: "{win}\explorer.exe"; Parameters: "{userprograms}\Docker\"; Flags: postinstall skipifsilent; Description: "View Shortcuts in File Explorer"

[Tasks]
Name: desktopicon; Description: "{cm:CreateDesktopIcon}"
Name: modifypath; Description: "Add docker.exe & docker-machine.exe to &PATH"
Name: upgradevm; Description: "Upgrade or Migrate Boot2Docker VM to latest version of Docker if it exists."

[Components]
Name: "Docker"; Description: "Docker Client for Windows" ; Types: full custom; Flags: fixed
Name: "DockerMachine"; Description: "Docker Machine for Windows" ; Types: full custom; Flags: fixed
Name: "VirtualBox"; Description: "VirtualBox"; Types: full custom; Flags: disablenouninstallwarning
Name: "Kitematic"; Description: "Kitematic for Windows (Alpha)" ; Types: full custom
Name: "Git"; Description: "Git for Windows"; Types: full custom; Flags: disablenouninstallwarning

[Files]
Source: ".\docker-quickstart-terminal.ico"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#dockerCli}"; DestDir: "{app}"; Flags: ignoreversion; Components: "Docker"
Source: ".\start.sh"; DestDir: "{app}"; Flags: ignoreversion; Components: "Docker"
Source: ".\delete.sh"; DestDir: "{app}"; Flags: ignoreversion; Components: "Docker"
Source: "{#dockerMachineCli}"; DestDir: "{app}"; Flags: ignoreversion; Components: "DockerMachine"
Source: ".\migrate.sh"; DestDir: "{app}"; Flags: ignoreversion; Components: "DockerMachine"
Source: ".\migrate.bat"; DestDir: "{app}"; Flags: ignoreversion; Components: "DockerMachine"
Source: "{#kitematic}\*"; DestDir: "{app}\kitematic"; Flags: ignoreversion recursesubdirs; Components: "Kitematic"
Source: "{#b2dIsoPath}"; DestDir: "{app}"; Flags: ignoreversion; Components: "DockerMachine"; AfterInstall: CopyBoot2DockerISO()
Source: "{#git}"; DestDir: "{app}\installers\git"; DestName: "git.exe"; AfterInstall: RunInstallGit();  Components: "Git"
Source: "{#virtualBoxCommon}"; DestDir: "{app}\installers\virtualbox"; Components: "VirtualBox"
Source: "{#virtualBoxMsi}"; DestDir: "{app}\installers\virtualbox"; DestName: "virtualbox.msi"; AfterInstall: RunInstallVirtualBox(); Components: "VirtualBox"

[Icons]
Name: "{userprograms}\Docker\Kitematic (Alpha)"; WorkingDir: "{app}"; Filename: "{app}\kitematic\Kitematic.exe"; Components: "Kitematic"
Name: "{commondesktop}\Kitematic (Alpha)"; WorkingDir: "{app}"; Filename: "{app}\kitematic\Kitematic.exe"; Tasks: desktopicon; Components: "Kitematic"
Name: "{userprograms}\Docker\Docker Quickstart Terminal"; WorkingDir: "{app}"; Filename: "{pf64}\Git\git-bash.exe"; Parameters: """{app}\start.sh"""; IconFilename: "{app}/docker-quickstart-terminal.ico"; Components: "Docker"
Name: "{commondesktop}\Docker Quickstart Terminal"; WorkingDir: "{app}"; Filename: "{pf64}\Git\git-bash.exe"; Parameters: """{app}\start.sh"""; IconFilename: "{app}/docker-quickstart-terminal.ico"; Tasks: desktopicon; Components: "Docker"

[UninstallRun]
Filename: "{app}\delete.sh"

[UninstallDelete]
Type: filesandordirs; Name: "{localappdata}\..\Roaming\Kitematic"

[Code]
#include "base64.iss"
#include "guid.iss"

var
	restart: boolean;
  TrackingDisabled: Boolean;
	DockerInstallDocs: TLabel;
  TrackingCheckBox: TNewCheckBox;

function uuid(): String;
var
  dirpath: String;
  filepath: String;
  ansiresult: AnsiString;
begin
  dirpath := ExpandConstant('{userappdata}\DockerToolbox');
  filepath := dirpath + '\id.txt';
  ForceDirectories(dirpath);

  Result := '';
  if FileExists(filepath) then
    LoadStringFromFile(filepath, ansiresult);
    Result := String(ansiresult)

  if Length(Result) = 0 then
    Result := GetGuid('');
    StringChangeEx(Result, '{', '', True);
    StringChangeEx(Result, '}', '', True);
    SaveStringToFile(filepath, AnsiString(Result), False);
end;

function WindowsVersionString(): String;
var
	ResultCode: Integer;
	lines : TArrayOfString;
begin
	if not Exec(ExpandConstant('{cmd}'), ExpandConstant('/c wmic os get caption | more +1 > C:\windows-version.txt'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then begin
		Result := 'N/A';
		exit;
	end;

	if LoadStringsFromFile(ExpandConstant('C:\windows-version.txt'), lines) then begin
		Result := lines[0];
	end else begin
		Result := 'N/A'
	end;
end;

procedure TrackEvent(name: String);
var
  payload: String;
  WinHttpReq: Variant;
begin
  if TrackingDisabled or WizardSilent() then
    exit;
  try
    payload := Encode64(Format(ExpandConstant('{{"event": "%s", "properties": {{"token": "{#MixpanelToken}", "distinct_id": "%s", "os": "win32", "os version": "%s", "version": "{#MyAppVersion}"}}'), [name, uuid(), WindowsVersionString()]));
    WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
    WinHttpReq.Open('POST', 'https://api.mixpanel.com/track/?data=' + payload, false);
    WinHttpReq.SetRequestHeader('Content-Type', 'application/json');
    WinHttpReq.Send('');
  except
  end;
end;

function NeedRestart(): Boolean;
begin
	Result := restart;
end;

function NeedToInstallVirtualBox(): Boolean;
begin
	// TODO: Also compare versions
	Result := (
		(GetEnv('VBOX_INSTALL_PATH') = '')
		and
		(GetEnv('VBOX_MSI_INSTALL_PATH') = '')
	);
end;

function VBoxPath(): String;
begin
	if GetEnv('VBOX_INSTALL_PATH') <> '' then
		Result := GetEnv('VBOX_INSTALL_PATH')
	else
		Result := GetEnv('VBOX_MSI_INSTALL_PATH')
end;

function NeedToInstallGit(): Boolean;
begin
	// TODO: Find a better way to see if Git is installed
	Result := not DirExists('C:\Program Files\Git') or not FileExists('C:\Program Files\Git\git-bash.exe')
end;

procedure DocLinkClick(Sender: TObject);
var
	ErrorCode: Integer;
begin
	ShellExec('', 'https://docs.docker.com/installation/windows/', '', '', SW_SHOW, ewNoWait, ErrorCode);
end;

procedure TrackingCheckBoxClicked(Sender: TObject);
begin
  if TrackingCheckBox.Checked then begin
		TrackingDisabled := False;
    TrackEvent('Enabled Tracking');
  end else begin
    TrackEvent('Disabled Tracking');
    TrackingDisabled := True;
  end;
end;

procedure InitializeWizard;
var
  WelcomePage: TWizardPage;
	TrackingLabel: TLabel;
begin
	DockerInstallDocs := TLabel.Create(WizardForm);
	DockerInstallDocs.Parent := WizardForm;
	DockerInstallDocs.Left := 8;
	DockerInstallDocs.Top := WizardForm.ClientHeight - DockerInstallDocs.ClientHeight - 8;
	DockerInstallDocs.Cursor := crHand;
	DockerInstallDocs.Font.Color := clBlue;
	DockerInstallDocs.Font.Style := [fsUnderline];
	DockerInstallDocs.Caption := '{#MyAppName} installation documentation';
	DockerInstallDocs.OnClick := @DocLinkClick;
	DockerInstallDocs.Visible := True;

  WelcomePage := PageFromID(wpWelcome)

	WizardForm.WelcomeLabel2.AutoSize := True;

  TrackingCheckBox := TNewCheckBox.Create(WizardForm);
  TrackingCheckBox.Top := 168;
  TrackingCheckBox.Left := WizardForm.WelcomeLabel2.Left;
  TrackingCheckBox.Width := WizardForm.WelcomeLabel2.Width;
  TrackingCheckBox.Height := 40;
  TrackingCheckBox.Caption := 'Help Docker improve Toolbox.';
  TrackingCheckBox.Checked := True;
  TrackingCheckBox.Parent := WelcomePage.Surface;
  TrackingCheckBox.OnClick := @TrackingCheckboxClicked;

	TrackingLabel := TLabel.Create(WizardForm);
	TrackingLabel.Parent := WelcomePage.Surface;
	TrackingLabel.Font := WizardForm.WelcomeLabel2.Font;
	TrackingLabel.Font.Color := clGray;
  TrackingLabel.Caption := 'This collects annoymous data to help us detect installation problems and improve the overall experience. We only use it to aggregate statistics and will never share it with third parties.';
	TrackingLabel.WordWrap := True;
	TrackingLabel.Visible := True;
	TrackingLabel.Left := WizardForm.WelcomeLabel2.Left;
	TrackingLabel.Width := WizardForm.WelcomeLabel2.Width;
	TrackingLabel.Top := 200;
	TrackingLabel.Height := 100;

		// Don't do this until we can compare versions
		Wizardform.ComponentsList.Checked[2] := NeedToInstallVirtualBox();
		Wizardform.ComponentsList.ItemEnabled[2] := not NeedToInstallVirtualBox();
		Wizardform.ComponentsList.Checked[4] := NeedToInstallGit();
		Wizardform.ComponentsList.ItemEnabled[4] := not NeedToInstallGit();
end;

function InitializeSetup(): boolean;
begin
  TrackEvent('Installer Started');
  Result := True;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  if CurPageID = wpWelcome then begin
      TrackEvent('Continued from Overview');
  end;
  Result := True
end;

procedure RunInstallVirtualBox();
var
	ResultCode: Integer;
begin
	WizardForm.FilenameLabel.Caption := 'installing VirtualBox'
	if not Exec(ExpandConstant('msiexec'), ExpandConstant('/qn /i "{app}\installers\virtualbox\virtualbox.msi" /norestart'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
		MsgBox('virtualbox install failure', mbInformation, MB_OK);
end;

procedure RunInstallGit();
var
	ResultCode: Integer;
begin
	WizardForm.FilenameLabel.Caption := 'installing Git for Windows'
	if Exec(ExpandConstant('{app}\installers\git\git.exe'), '/sp- /verysilent /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
	begin
		// handle success if necessary; ResultCode contains the exit code
		//MsgBox('git installed OK', mbInformation, MB_OK);
	end
	else begin
		// handle failure if necessary; ResultCode contains the error code
		MsgBox('git install failure', mbInformation, MB_OK);
	end;
end;

procedure CopyBoot2DockerISO();
begin
  WizardForm.FilenameLabel.Caption := 'copying boot2docker iso'
  if not ForceDirectories(ExpandConstant('{userdocs}\..\.docker\machine\cache')) then
      MsgBox('Failed to create docker machine cache dir', mbError, MB_OK);
  if not FileCopy(ExpandConstant('{app}\boot2docker.iso'), ExpandConstant('{userdocs}\..\.docker\machine\cache\boot2docker.iso'), false) then
      MsgBox('File moving failed!', mbError, MB_OK);
end;

function CanUpgradeVM(): Boolean;
var
	ResultCode: Integer;
begin
	if NeedToInstallVirtualBox() or not FileExists(ExpandConstant('{app}\docker-machine.exe')) then begin
		Result := false
		exit
	end;

	ExecAsOriginalUser(VBoxPath() + 'VBoxManage.exe', 'showvminfo default', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
	if ResultCode <> 0 then begin
		Result := false
		exit
	end;

	if not DirExists(ExpandConstant('{userdocs}\..\.docker\machine\machines\default')) then begin
		Result := false
		exit
	end;

	Result := true
end;

function UpgradeVM() : Boolean;
var
	ResultCode: Integer;
begin
	TrackEvent('VM Upgrade Started');
	WizardForm.StatusLabel.Caption := 'Upgrading Docker Toolbox VM...'
	ExecAsOriginalUser(ExpandConstant('{app}\docker-machine.exe'), 'stop default', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
	if ResultCode = 0 then
	begin
		FileCopy(ExpandConstant('{userdocs}\..\.docker\machine\cache\boot2docker.iso'), ExpandConstant('{userdocs}\..\.docker\machine\machines\default\boot2docker.iso'), false)
		TrackEvent('VM Upgrade Succeeded');
	end
	else begin
		TrackEvent('VM Upgrade Failed');
		MsgBox('VM Upgrade Failed because the VirtualBox VM could not be stopped.', mbCriticalError, MB_OK);
		Result := false
		WizardForm.Close;
		exit;
	end;
	Result := true
end;

function MigrateVM() : Boolean;
var
  ResultCode: Integer;
begin
	if NeedToInstallGit() or NeedToInstallVirtualBox() or not FileExists(ExpandConstant('{app}\docker-machine.exe')) then begin
		Result := true
		exit
	end;

	ExecAsOriginalUser(VBoxPath() + 'VBoxManage.exe', 'showvminfo default', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
	if ResultCode <> 1 then begin
		Result := true
		exit
	end;

	ExecAsOriginalUser(VBoxPath() + 'VBoxManage.exe', 'showvminfo boot2docker-vm', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
	if ResultCode <> 0 then begin
		Result := true
		exit
	end;

  if MsgBox('Migrate your existing Boot2Docker VM to work with the Docker Toolbox? Your existing Boot2Docker VM will not be affected. This should take about a minute.', mbConfirmation, MB_YESNO) = IDYES then
  begin
		TrackEvent('Boot2Docker Migration Started');
    WizardForm.StatusLabel.Caption := 'Migrating Boot2Docker VM...'
    WizardForm.FilenameLabel.Caption := 'This will take a minute...'
    ExecAsOriginalUser(ExpandConstant('{app}\docker-machine.exe'), ExpandConstant('rm -f default > nul 2>&1'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
    DelTree(ExpandConstant('{userdocs}\..\.docker\machine\machines\default'), True, True, True);
    ExecAsOriginalUser(ExpandConstant('{app}\migrate.bat'), ExpandConstant('> {localappdata}\Temp\toolbox-migration-logs.txt 2>&1'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
    if ResultCode = 0 then
    begin
      TrackEvent('Boot2Docker Migration Succeeded');
      MsgBox('Succcessfully migrated Boot2Docker VM to a Docker Machine VM named "default"', mbInformation, MB_OK);
    end
    else begin
      TrackEvent('Boot2Docker Migration Failed');
      MsgBox('Migration of Boot2Docker VM failed. Please file an issue with the migration logs at https://github.com/docker/toolbox/issues/new.', mbCriticalError, MB_OK);
      Exec(ExpandConstant('{win}\notepad.exe'), ExpandConstant('{localappdata}\Temp\toolbox-migration-logs.txt'), '', SW_SHOW, ewNoWait, ResultCode)
      Result := false
			WizardForm.Close;
      exit;
    end;
  end
  else
  begin
    TrackEvent('Boot2Docker Migration Skipped');
  end;
  Result := true
end;

const
	ModPathName = 'modifypath';
	ModPathType = 'user';

function ModPathDir(): TArrayOfString;
begin
	setArrayLength(Result, 1);
	Result[0] := ExpandConstant('{app}');
end;
#include "modpath.iss"

procedure CurStepChanged(CurStep: TSetupStep);
var
	Success: Boolean;
begin
	Success := True;
	if CurStep = ssPostInstall then
  begin
    if IsTaskSelected(ModPathName) then
			ModPath();
    if not WizardSilent() then
		begin
			if IsTaskSelected('upgradevm') then
			begin
				if CanUpgradeVM() then begin
					Success := UpgradeVM();
				end
				else begin
					Success := MigrateVM();
				end;
			end;
		end;

		if Success then
			trackEvent('Installer Finished');
  end;
end;