Add helpful error message when the python installations don't match the global/per user status of vapoursynth

#define AppName = 'VapourSynth'
#define Version = 'R46'

[Setup]
OutputDir=Compiled
OutputBaseFilename=VapourSynth-{#= Version}
Compression=lzma2/max
InternalCompressLevel=max
SolidCompression=yes
LZMAUseSeparateProcess=yes
VersionInfoDescription={#= AppName} {#= Version} Installer
AppId={#= AppName}
AppName={#= AppName} {#= Version}
AppVersion={#= Version}
AppVerName={#= AppName} {#= Version}
AppPublisher=Fredrik Mellbin
AppPublisherURL=http://www.vapoursynth.com/
AppSupportURL=http://www.vapoursynth.com/
AppUpdatesURL=http://www.vapoursynth.com/
VersionInfoVersion=1.46.0.0
DefaultDirName={autopf32}\VapourSynth
DefaultGroupName=VapourSynth
AllowCancelDuringInstall=no
AllowNoIcons=yes
AllowUNCPath=no
MinVersion=6.0
UsePreviousPrivileges=no
PrivilegesRequired=admin
PrivilegesRequiredOverridesAllowed=dialog
WizardStyle=modern
FlatComponentsList=yes
ArchitecturesAllowed=x86 x64
ArchitecturesInstallIn64BitMode=x64

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

[Types]
Name: Full; Description: Full installation; Flags: iscustom

[Components]
Name: "vs64"; Description: "VapourSynth 64-bit"; Types: Full; Check: HasPython64; Flags: disablenouninstallwarning
Name: "vs32"; Description: "VapourSynth 32-bit"; Types: Full; Check: HasPython32; Flags: disablenouninstallwarning
Name: "vsrepo"; Description: "VSRepo Package Manager"; Types: Full; Flags: disablenouninstallwarning
Name: "docs"; Description: "VapourSynth Documentation"; Types: Full; Flags: disablenouninstallwarning
Name: "sdk"; Description: "VapourSynth SDK"; Flags: disablenouninstallwarning; Types: Full
Name: "pismo"; Description: "Pismo PFM Runtime (required for AVFS)"; Types: Full; Check: IsAdminInstallMode; Flags: disablenouninstallwarning
Name: "vsruntimes"; Description: "Visual Studio 2019 Runtimes"; Types: Full; Check: IsAdminInstallMode; Flags: disablenouninstallwarning

[Tasks]
Name: newvpyfile; Description: "Add 'New VapourSynth Python Script' option to shell context menu"; GroupDescription: "New File Shortcuts:"; Components: vs32 vs64
Name: vsrepoupdate; Description: "Update VSRepo package list"; GroupDescription: "VSRepo:"; Components: vsrepo

[Run]
Filename: "{app}\pismo\pfm-192-vapoursynth-win.exe"; Parameters: "install"; Flags: runhidden; Components: pismo
Filename: {code:GetPythonExecutableAny}; Parameters: """{app}\vsrepo\vsrepo.py"" update"; Flags: runhidden runasoriginaluser; Components: vsrepo

[Files]
;core binaries
Source: template.vpy; DestDir: {app}; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32 vs64
Source: vapoursynth.pth; DestDir: {code:GetPythonPath32}\Lib\site-packages; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: vapoursynth.pth; DestDir: {code:GetPythonPath64}\Lib\site-packages; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\vapoursynth.cp37-win32.pyd; DestDir: {code:GetPythonPath32}\Lib\site-packages\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\vapoursynth.cp37-win_amd64.pyd; DestDir: {code:GetPythonPath64}\Lib\site-packages\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\vapoursynth.dll; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\vapoursynth.dll; DestDir: {code:GetPythonPath32}\Lib\site-packages\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\vapoursynth.pdb; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\vapoursynth.dll; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\vapoursynth.dll; DestDir: {code:GetPythonPath64}\Lib\site-packages\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\vapoursynth.pdb; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\avfs.exe; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\avfs.exe; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\vspipe.exe; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\vspipe.exe; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\vsvfw.dll; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\vsvfw.dll; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\vsscript.dll; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\vsscript.dll; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

;vsrepo
Source: ..\vsrepo\vsrepo.py; DestDir: {app}\vsrepo; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vsrepo

;docs
Source: ..\doc\_build\html\*; DestDir: {app}\docs; Flags: ignoreversion uninsrestartdelete restartreplace recursesubdirs; Components: docs

;sdk
Source: ..\include\VapourSynth.h; DestDir: {app}\sdk\include\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\include\VSHelper.h; DestDir: {app}\sdk\include\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\include\VSScript.h; DestDir: {app}\sdk\include\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\msvc_project\Release\vsscript.lib; DestDir: {app}\sdk\lib32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\msvc_project\x64\Release\vsscript.lib; DestDir: {app}\sdk\lib64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\msvc_project\Release\vapoursynth.lib; DestDir: {app}\sdk\lib32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\msvc_project\x64\Release\vapoursynth.lib; DestDir: {app}\sdk\lib64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\sdk\filter_skeleton.c; DestDir: {app}\sdk\examples; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\sdk\invert_example.c; DestDir: {app}\sdk\examples; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\sdk\vsscript_example.c; DestDir: {app}\sdk\examples; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk

;bundled plugins
Source: x86\plugins\*; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\AvsCompat.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\EEDI3.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\MiscFilters.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\Morpho.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\RemoveGrainVS.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\Vinverse.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\VIVTC.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32

Source: x64\plugins\*; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\AvsCompat.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\EEDI3.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\MiscFilters.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\Morpho.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\RemoveGrainVS.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\Vinverse.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\VIVTC.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

;pismo installer
Source: "pfm-192-vapoursynth-win.exe"; DestDir: {app}\pismo; Flags: ignoreversion uninsrestartdelete restartreplace; Components: pismo

; Create the general autoload directory
[Dirs]
Name: "{app}\plugins32"; Flags: uninsalwaysuninstall; Components: vs32
Name: "{app}\plugins64"; Flags: uninsalwaysuninstall; Components: vs64

[Icons]
Name: {group}\VapourSynth Website; Filename: http://www.vapoursynth.com/
Name: {group}\Documentation (Local); Filename: {app}\docs\index.html; Components: docs
Name: {group}\Documentation (Online); Filename: http://www.vapoursynth.com/doc/
Name: {group}\Global Autoload Directory (32bit); Filename: {app}\plugins32; Components: vs32
Name: {group}\Global Autoload Directory (64bit); Filename: {app}\plugins64; Components: vs64
Name: {group}\VapourSynth SDK; Filename: {app}\sdk; Components: sdk

[Registry]
Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Version"; ValueData: {#= Version}; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Version"; ValueData: {#= Version}; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Path"; ValueData: "{app}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Path"; ValueData: "{app}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "CorePlugins"; ValueData: "{app}\core32\plugins"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "CorePlugins"; ValueData: "{app}\core64\plugins"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Plugins"; ValueData: "{app}\plugins32"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Plugins"; ValueData: "{app}\plugins64"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "VapourSynthDLL"; ValueData: "{app}\core32\vapoursynth.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "VapourSynthDLL"; ValueData: "{app}\core64\vapoursynth.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "VSScriptDLL"; ValueData: "{app}\core32\vsscript.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "PythonPath"; ValueData: "{code:GetPythonPath32}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "VSScriptDLL"; ValueData: "{app}\core64\vsscript.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "PythonPath"; ValueData: "{code:GetPythonPath64}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

; new vpy file shortcut task
Root: HKA; Subkey: SOFTWARE\Classes\.vpy\ShellNew; ValueType: string; ValueName: "FileName"; ValueData: "{app}\template.vpy"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: newvpyfile

; 32bit vfw
Root: HKA32; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}; ValueType: string; ValueName: ""; ValueData: "VapourSynth"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}\InProcServer32; ValueType: string; ValueName: ""; ValueData: "{app}\core32\vsvfw.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}\InProcServer32; ValueType: string; ValueName: "ThreadingModel"; ValueData: "Apartment"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\Media Type\Extensions\.vpy; ValueType: string; ValueName: ""; ValueData: ""; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\Media Type\Extensions\.vpy; ValueType: string; ValueName: "Source Filter"; ValueData: "{{D3588AB0-0781-11CE-B03A-0020AF0BA770}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\.vpy; ValueType: string; ValueName: ""; ValueData: "vpyfile"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\vpyfile; ValueType: string; ValueName: ""; ValueData: "VapourSynth Python Script"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\vpyfile\DefaultIcon; ValueType: string; ValueName: ""; ValueData: "{app}\core32\vsvfw.dll,0"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\AVIFile\Extensions\VPY; ValueType: string; ValueName: ""; ValueData: "{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32

; 64bit vfw
Root: HKA64; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}; ValueType: string; ValueName: ""; ValueData: "VapourSynth"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}\InProcServer32; ValueType: string; ValueName: ""; ValueData: "{app}\core64\vsvfw.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}\InProcServer32; ValueType: string; ValueName: "ThreadingModel"; ValueData: "Apartment"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\Media Type\Extensions\.vpy; ValueType: string; ValueName: ""; ValueData: ""; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\Media Type\Extensions\.vpy; ValueType: string; ValueName: "Source Filter"; ValueData: "{{D3588AB0-0781-11CE-B03A-0020AF0BA770}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\.vpy; ValueType: string; ValueName: ""; ValueData: "vpyfile"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\vpyfile; ValueType: string; ValueName: ""; ValueData: "VapourSynth Python Script"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\vpyfile\DefaultIcon; ValueType: string; ValueName: ""; ValueData: "{app}\core64\vsvfw.dll,0"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\AVIFile\Extensions\VPY; ValueType: string; ValueName: ""; ValueData: "{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

[UninstallDelete]
Type: dirifempty; Name: "{code:GetPythonPath32}\Lib\site-packages\vapoursynth"; Components: vs32
Type: dirifempty; Name: "{code:GetPythonPath64}\Lib\site-packages\vapoursynth"; Components: vs64

#include "scripts\products.iss"
#include "scripts\products\stringversion.iss"
#include "scripts\products\msiproduct.iss"
#include "scripts\products\vcredist2017.iss"

[Code]

type
  TPythonPath = record
    DisplayName: string;
    InstallPath: string;
    ExecutablePath: string;
    Bitness: Integer;
  end;

var
  Runtimes32Added: Boolean;
  Runtimes64Added: Boolean;
  PythonInstallations: array of TPythonPath;
  GlobalPythonInstallations: array of TPythonPath;
  UserPythonInstallations: array of TPythonPath;
  PythonPage: TWizardPage;
  PythonList: TNewCheckListBox;
  Python32Path: string;
  Python32Executable: string;
  Python64Path: string;
  Python64Executable: string;

function HasPython32: Boolean;
var
  Counter: Integer;
begin
  Result := False;
  for Counter := 0 to GetArrayLength(PythonInstallations) - 1 do
    if PythonInstallations[Counter].Bitness = 32 then
      Result := True;
end;

function HasPython64: Boolean;
var
  Counter: Integer;
begin
  Result := False;
  for Counter := 0 to GetArrayLength(PythonInstallations) - 1 do
    if PythonInstallations[Counter].Bitness = 64 then
      Result := True;
end;

procedure GetPythonInstallations2(var DestArray: array of TPythonPath; RegRoot: Integer; RegPath: string; AssumeBitness: Integer);
var
  Names, Tags: TArrayOfString;
  Nc, Tc: Integer;
  RegPathTemp: string;
  Temp: string;
  DisplayName, InstallPath, ExecutablePath: string;
  Bitness: Integer;
begin
  if RegGetSubkeyNames(RegRoot, RegPath, Names) then
  begin
    for Nc := 0 to GetArrayLength(Names) - 1 do
    begin
      if RegGetSubkeyNames(RegRoot, RegPath + '\' + Names[Nc], Tags) then
      begin
        for Tc := 0 to GetArrayLength(Tags) - 1 do
        begin
          RegPathTemp := RegPath + '\' + Names[Nc] + '\' + Tags[Tc];
          Bitness := AssumeBitness;
          if (not RegQueryStringValue(RegRoot, RegPathTemp, 'SysVersion', Temp)) or (Temp <> '3.7') then
            continue;
          if RegQueryStringValue(RegRoot, RegPathTemp, 'SysArchitecture', Temp) then
          begin
            if Temp = '32bit' then
              Bitness := 32
            else if Temp = '64bit' then
              Bitness := 64;
          end;

          if RegQueryStringValue(RegRoot, RegPathTemp, 'DisplayName', DisplayName)
            and RegQueryStringValue(RegRoot, RegPathTemp + '\InstallPath', '', InstallPath)
            and RegQueryStringValue(RegRoot, RegPathTemp + '\InstallPath', 'ExecutablePath', ExecutablePath) then
          begin
             SetArrayLength(DestArray, GetArrayLength(DestArray) + 1);
             DestArray[GetArrayLength(DestArray) - 1].DisplayName := DisplayName;
             DestArray[GetArrayLength(DestArray) - 1].InstallPath := InstallPath;
             DestArray[GetArrayLength(DestArray) - 1].ExecutablePath := ExecutablePath;
             DestArray[GetArrayLength(DestArray) - 1].Bitness := Bitness;
          end;
        end;
      end;
    end;
  end;
end;

function GetPythonInstallations: Boolean;
begin
  GetPythonInstallations2(UserPythonInstallations, HKCU, 'SOFTWARE\Python', 0);
  GetPythonInstallations2(GlobalPythonInstallations, HKLM32, 'SOFTWARE\Python', 32);
  if Is64BitInstallMode then
    GetPythonInstallations2(GlobalPythonInstallations, HKLM, 'SOFTWARE\Python', 64);
end;

procedure PopulatePythonInstallations(List: TNewCheckListBox);
var
  Counter: Integer;
  First: Boolean;
begin
  List.Items.Clear;

  if WizardIsComponentSelected('vs32') then
  begin
    First := True;
    List.AddGroup('Python Environments (32-bit)', '', 0, nil);
    for Counter := 0 to GetArrayLength(PythonInstallations) - 1 do
      if PythonInstallations[Counter].Bitness = 32 then
        with PythonInstallations[Counter] do
        begin
          List.AddRadioButton(DisplayName, '(' + InstallPath + ')', 1, First, True, TObject(Counter));
          First := False;
        end;
  end;

  if WizardIsComponentSelected('vs64') then
  begin
    First := True;
    List.AddGroup('Python Environments (64-bit)', '', 0, nil);
    for Counter := 0 to GetArrayLength(PythonInstallations) - 1 do
      if PythonInstallations[Counter].Bitness = 64 then
        with PythonInstallations[Counter] do
        begin
          List.AddRadioButton(DisplayName, '(' + InstallPath + ')', 1, First, True, TObject(Counter));
          First := False;
        end;
  end;
end;

function InitializeSetup: Boolean;
var
  HasOtherPython: Boolean;
begin
  Runtimes32Added := False;
  Runtimes64Added := False;
  PythonList := nil;
  GetPythonInstallations;
  if IsAdminInstallMode then
  begin
    PythonInstallations := GlobalPythonInstallations;
    HasOtherPython := GetArrayLength(UserPythonInstallations) > 0;
  end
  else
  begin
    PythonInstallations := UserPythonInstallations;
    HasOtherPython := GetArrayLength(GlobalPythonInstallations) > 0;
  end;

  Result := GetArrayLength(PythonInstallations) > 0;

  if not Result and not HasOtherPython then
      MsgBox('No suitable Python 3.7 installation found. The installer will now exit.', mbCriticalError, MB_OK)
  else if not Result and IsAdminInstallMode then
      MsgBox('Only Python 3.7 installed for "current user" found. Run the installer again in "current user" mode or install Python for the "all users".', mbCriticalError, MB_OK)
  else if not Result and not IsAdminInstallMode then
      MsgBox('Only Python 3.7 installed for "all users" found. Run the installer again in "all users" mode or install Python for the "current user".', mbCriticalError, MB_OK)
end;

procedure WizardFormOnResize(Sender: TObject);
begin
  with PythonList do
  begin
    Parent := PythonPage.Surface;
    Left := ScaleX(0);
    Top := ScaleY(0);
    Width := PythonPage.Surface.Width - ScaleX(0) * 2;
    Height := PythonPage.Surface.Height;
  end;
end;

procedure InitializeWizard();
begin
  PythonPage := CreateCustomPage(wpSelectComponents, 'Select Python Installations', 'Select one or more Python installations to use');
  PythonList := TNewCheckListBox.Create(PythonPage);

  with PythonList do
  begin
    Parent := PythonPage.Surface;
    Left := ScaleX(0);
    Top := ScaleY(0);
    Width := PythonPage.Surface.Width - ScaleX(0) * 2;
    Height := PythonPage.Surface.Height;
  end;

  WizardForm.OnResize := @WizardFormOnResize;
end;

function GetPythonPath32(Param: string): String;
begin
  Result := Python32Path;
end;

function GetPythonPath64(Param: String): String;
begin
  Result := Python64Path;
end;

function GetPythonExecutableAny(Param: string): String;
begin
  if Python64Executable <> '' then
    Result := Python64Executable
  else
    Result := Python32Executable;
end;

/////////////////////////////////////////////////////////////////////
function GetUninstallString: String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
  sUnInstallString := '';
  RegQueryStringValue(HKA, sUnInstPath, 'UninstallString', sUnInstallString)
  Result := sUnInstallString;
end;

/////////////////////////////////////////////////////////////////////
function IsUpgrade: Boolean;
begin
  Result := (GetUninstallString() <> '');
end;

/////////////////////////////////////////////////////////////////////
function UnInstallOldVersion: Integer;
var
  sUnInstallString: String;
  iResultCode: Integer;
begin
// Return Values:
// 1 - uninstall string is empty
// 2 - error executing the UnInstallString
// 3 - successfully executed the UnInstallString

  // default return value
  Result := 0;

  // get the uninstall string of the old app
  sUnInstallString := GetUninstallString();
  if sUnInstallString <> '' then begin
    sUnInstallString := RemoveQuotes(sUnInstallString);
    if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
      Result := 3
    else
      Result := 2;
  end
  else
    Result := 1;
end;

/////////////////////////////////////////////////////////////////////
procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep=ssInstall then
  begin
    if IsUpgrade() then
      UnInstallOldVersion();
  end;
end;

/////////////////////////////////////////////////////////////////////
function NextButtonClick(CurPageID: Integer): Boolean;
var
  Counter: Integer;
  Idx: Integer;
begin
  Result := True;
  if CurPageID = PythonPage.ID then
  begin
    for Counter := 0 to PythonList.Items.Count - 1 do
    begin
      if (PythonList.Checked[Counter]) and (PythonList.ItemLevel[Counter] = 1) then
      begin
        Idx := Integer(PythonList.ItemObject[Counter]);
        with PythonInstallations[Idx] do
        begin
          if Bitness = 64 then
          begin
            Python64Path := InstallPath;
            Python64Executable := ExecutablePath;
          end
          else if Bitness = 32 then
          begin
            Python32Path := InstallPath;
            Python32Executable := ExecutablePath;
          end;
        end;
      end;
    end;
  end
  else if CurPageID = wpSelectComponents then
  begin
    if not WizardIsComponentSelected('vs32 or vs64') then
    begin
      Result := False;
      MsgBox('At least one version of the core library has to be installed.', mbCriticalError, MB_OK)
    end;

    PopulatePythonInstallations(PythonList);
  end
  else if CurPageID = wpReady then
  begin
    if WizardIsComponentSelected('vsruntimes') and WizardIsComponentSelected('vs32') and not Runtimes32Added then
    begin
      SetForceX86(True);
      vcredist2017('14.21.27702');
      SetForceX86(False);
      Runtimes32Added := True;
    end;
    if WizardIsComponentSelected('vsruntimes') and WizardIsComponentSelected('vs64') and not Runtimes64Added then
    begin
      vcredist2017('14.21.27702');
      Runtimes64Added := True;
    end;
    Result := NextButtonClick2(CurPageID);
  end;
end;

#define AppName = 'VapourSynth'
#define Version = 'R46'

[Setup]
OutputDir=Compiled
OutputBaseFilename=VapourSynth-{#= Version}
Compression=lzma2/max
InternalCompressLevel=max
SolidCompression=yes
LZMAUseSeparateProcess=yes
VersionInfoDescription={#= AppName} {#= Version} Installer
AppId={#= AppName}
AppName={#= AppName} {#= Version}
AppVersion={#= Version}
AppVerName={#= AppName} {#= Version}
AppPublisher=Fredrik Mellbin
AppPublisherURL=http://www.vapoursynth.com/
AppSupportURL=http://www.vapoursynth.com/
AppUpdatesURL=http://www.vapoursynth.com/
VersionInfoVersion=1.46.0.0
DefaultDirName={autopf32}\VapourSynth
DefaultGroupName=VapourSynth
AllowCancelDuringInstall=no
AllowNoIcons=yes
AllowUNCPath=no
MinVersion=6.0
UsePreviousPrivileges=no
PrivilegesRequired=admin
PrivilegesRequiredOverridesAllowed=dialog
WizardStyle=modern
FlatComponentsList=yes
ArchitecturesAllowed=x86 x64
ArchitecturesInstallIn64BitMode=x64

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

[Types]
Name: Full; Description: Full installation; Flags: iscustom

[Components]
Name: "vs64"; Description: "VapourSynth 64-bit"; Types: Full; Check: HasPython64; Flags: disablenouninstallwarning
Name: "vs32"; Description: "VapourSynth 32-bit"; Types: Full; Check: HasPython32; Flags: disablenouninstallwarning
Name: "vsrepo"; Description: "VSRepo Package Manager"; Types: Full; Flags: disablenouninstallwarning
Name: "docs"; Description: "VapourSynth Documentation"; Types: Full; Flags: disablenouninstallwarning
Name: "sdk"; Description: "VapourSynth SDK"; Flags: disablenouninstallwarning; Types: Full
Name: "pismo"; Description: "Pismo PFM Runtime (required for AVFS)"; Types: Full; Check: IsAdminInstallMode; Flags: disablenouninstallwarning
Name: "vsruntimes"; Description: "Visual Studio 2019 Runtimes"; Types: Full; Check: IsAdminInstallMode; Flags: disablenouninstallwarning

[Tasks]
Name: newvpyfile; Description: "Add 'New VapourSynth Python Script' option to shell context menu"; GroupDescription: "New File Shortcuts:"; Components: vs32 vs64
Name: vsrepoupdate; Description: "Update VSRepo package list"; GroupDescription: "VSRepo:"; Components: vsrepo

[Run]
Filename: "{app}\pismo\pfm-192-vapoursynth-win.exe"; Parameters: "install"; Flags: runhidden; Components: pismo
Filename: {code:GetPythonExecutableAny}; Parameters: """{app}\vsrepo\vsrepo.py"" update"; Flags: runhidden runasoriginaluser; Components: vsrepo

[Files]
;core binaries
Source: template.vpy; DestDir: {app}; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32 vs64
Source: vapoursynth.pth; DestDir: {code:GetPythonPath32}\Lib\site-packages; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: vapoursynth.pth; DestDir: {code:GetPythonPath64}\Lib\site-packages; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\vapoursynth.cp37-win32.pyd; DestDir: {code:GetPythonPath32}\Lib\site-packages\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\vapoursynth.cp37-win_amd64.pyd; DestDir: {code:GetPythonPath64}\Lib\site-packages\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\vapoursynth.dll; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\vapoursynth.dll; DestDir: {code:GetPythonPath32}\Lib\site-packages\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\vapoursynth.pdb; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\vapoursynth.dll; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\vapoursynth.dll; DestDir: {code:GetPythonPath64}\Lib\site-packages\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\vapoursynth.pdb; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\avfs.exe; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\avfs.exe; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\vspipe.exe; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\vspipe.exe; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\vsvfw.dll; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\vsvfw.dll; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

Source: ..\msvc_project\Release\vsscript.dll; DestDir: {app}\core32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\x64\Release\vsscript.dll; DestDir: {app}\core64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

;vsrepo
Source: ..\vsrepo\vsrepo.py; DestDir: {app}\vsrepo; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vsrepo

;docs
Source: ..\doc\_build\html\*; DestDir: {app}\docs; Flags: ignoreversion uninsrestartdelete restartreplace recursesubdirs; Components: docs

;sdk
Source: ..\include\VapourSynth.h; DestDir: {app}\sdk\include\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\include\VSHelper.h; DestDir: {app}\sdk\include\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\include\VSScript.h; DestDir: {app}\sdk\include\vapoursynth; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\msvc_project\Release\vsscript.lib; DestDir: {app}\sdk\lib32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\msvc_project\x64\Release\vsscript.lib; DestDir: {app}\sdk\lib64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\msvc_project\Release\vapoursynth.lib; DestDir: {app}\sdk\lib32; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\msvc_project\x64\Release\vapoursynth.lib; DestDir: {app}\sdk\lib64; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\sdk\filter_skeleton.c; DestDir: {app}\sdk\examples; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\sdk\invert_example.c; DestDir: {app}\sdk\examples; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk
Source: ..\sdk\vsscript_example.c; DestDir: {app}\sdk\examples; Flags: ignoreversion uninsrestartdelete restartreplace; Components: sdk

;bundled plugins
Source: x86\plugins\*; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\AvsCompat.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\EEDI3.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\MiscFilters.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\Morpho.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\RemoveGrainVS.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\Vinverse.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32
Source: ..\msvc_project\Release\VIVTC.dll; DestDir: {app}\core32\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs32

Source: x64\plugins\*; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\AvsCompat.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\EEDI3.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\MiscFilters.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\Morpho.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\RemoveGrainVS.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\Vinverse.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64
Source: ..\msvc_project\x64\Release\VIVTC.dll; DestDir: {app}\core64\plugins; Flags: ignoreversion uninsrestartdelete restartreplace; Components: vs64

;pismo installer
Source: "pfm-192-vapoursynth-win.exe"; DestDir: {app}\pismo; Flags: ignoreversion uninsrestartdelete restartreplace; Components: pismo

; Create the general autoload directory
[Dirs]
Name: "{app}\plugins32"; Flags: uninsalwaysuninstall; Components: vs32
Name: "{app}\plugins64"; Flags: uninsalwaysuninstall; Components: vs64

[Icons]
Name: {group}\VapourSynth Website; Filename: http://www.vapoursynth.com/
Name: {group}\Documentation (Local); Filename: {app}\docs\index.html; Components: docs
Name: {group}\Documentation (Online); Filename: http://www.vapoursynth.com/doc/
Name: {group}\Global Autoload Directory (32bit); Filename: {app}\plugins32; Components: vs32
Name: {group}\Global Autoload Directory (64bit); Filename: {app}\plugins64; Components: vs64
Name: {group}\VapourSynth SDK; Filename: {app}\sdk; Components: sdk

[Registry]
Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Version"; ValueData: {#= Version}; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Version"; ValueData: {#= Version}; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Path"; ValueData: "{app}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Path"; ValueData: "{app}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "CorePlugins"; ValueData: "{app}\core32\plugins"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "CorePlugins"; ValueData: "{app}\core64\plugins"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Plugins"; ValueData: "{app}\plugins32"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "Plugins"; ValueData: "{app}\plugins64"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "VapourSynthDLL"; ValueData: "{app}\core32\vapoursynth.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "VapourSynthDLL"; ValueData: "{app}\core64\vapoursynth.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "VSScriptDLL"; ValueData: "{app}\core32\vsscript.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "PythonPath"; ValueData: "{code:GetPythonPath32}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "VSScriptDLL"; ValueData: "{app}\core64\vsscript.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\VapourSynth; ValueType: string; ValueName: "PythonPath"; ValueData: "{code:GetPythonPath64}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

; new vpy file shortcut task
Root: HKA; Subkey: SOFTWARE\Classes\.vpy\ShellNew; ValueType: string; ValueName: "FileName"; ValueData: "{app}\template.vpy"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: newvpyfile

; 32bit vfw
Root: HKA32; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}; ValueType: string; ValueName: ""; ValueData: "VapourSynth"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}\InProcServer32; ValueType: string; ValueName: ""; ValueData: "{app}\core32\vsvfw.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}\InProcServer32; ValueType: string; ValueName: "ThreadingModel"; ValueData: "Apartment"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\Media Type\Extensions\.vpy; ValueType: string; ValueName: ""; ValueData: ""; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\Media Type\Extensions\.vpy; ValueType: string; ValueName: "Source Filter"; ValueData: "{{D3588AB0-0781-11CE-B03A-0020AF0BA770}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\.vpy; ValueType: string; ValueName: ""; ValueData: "vpyfile"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\vpyfile; ValueType: string; ValueName: ""; ValueData: "VapourSynth Python Script"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\vpyfile\DefaultIcon; ValueType: string; ValueName: ""; ValueData: "{app}\core32\vsvfw.dll,0"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32
Root: HKA32; Subkey: SOFTWARE\Classes\AVIFile\Extensions\VPY; ValueType: string; ValueName: ""; ValueData: "{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs32

; 64bit vfw
Root: HKA64; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}; ValueType: string; ValueName: ""; ValueData: "VapourSynth"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}\InProcServer32; ValueType: string; ValueName: ""; ValueData: "{app}\core64\vsvfw.dll"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\CLSID\{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}\InProcServer32; ValueType: string; ValueName: "ThreadingModel"; ValueData: "Apartment"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\Media Type\Extensions\.vpy; ValueType: string; ValueName: ""; ValueData: ""; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\Media Type\Extensions\.vpy; ValueType: string; ValueName: "Source Filter"; ValueData: "{{D3588AB0-0781-11CE-B03A-0020AF0BA770}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\.vpy; ValueType: string; ValueName: ""; ValueData: "vpyfile"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\vpyfile; ValueType: string; ValueName: ""; ValueData: "VapourSynth Python Script"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\vpyfile\DefaultIcon; ValueType: string; ValueName: ""; ValueData: "{app}\core64\vsvfw.dll,0"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64
Root: HKA64; Subkey: SOFTWARE\Classes\AVIFile\Extensions\VPY; ValueType: string; ValueName: ""; ValueData: "{{58F74CA0-BD0E-4664-A49B-8D10E6F0C131}"; Flags: uninsdeletevalue uninsdeletekeyifempty; Components: vs64

[UninstallDelete]
Type: dirifempty; Name: "{code:GetPythonPath32}\Lib\site-packages\vapoursynth"; Components: vs32
Type: dirifempty; Name: "{code:GetPythonPath64}\Lib\site-packages\vapoursynth"; Components: vs64

#include "scripts\products.iss"
#include "scripts\products\stringversion.iss"
#include "scripts\products\msiproduct.iss"
#include "scripts\products\vcredist2017.iss"

[Code]

type
  TPythonPath = record
    DisplayName: string;
    InstallPath: string;
    ExecutablePath: string;
    Bitness: Integer;
  end;

var
  Runtimes32Added: Boolean;
  Runtimes64Added: Boolean;
  PythonInstallations: array of TPythonPath;
  PythonPage: TWizardPage;
  PythonList: TNewCheckListBox;
  Python32Path: string;
  Python32Executable: string;
  Python64Path: string;
  Python64Executable: string;

function HasPython32: Boolean;
var
  Counter: Integer;
begin
  Result := False;
  for Counter := 0 to GetArrayLength(PythonInstallations) - 1 do
    if PythonInstallations[Counter].Bitness = 32 then
      Result := True;
end;

function HasPython64: Boolean;
var
  Counter: Integer;
begin
  Result := False;
  for Counter := 0 to GetArrayLength(PythonInstallations) - 1 do
    if PythonInstallations[Counter].Bitness = 64 then
      Result := True;
end;

procedure GetPythonInstallations2(RegRoot: Integer; RegPath: string; AssumeBitness: Integer);
var
  Names, Tags: TArrayOfString;
  Nc, Tc: Integer;
  RegPathTemp: string;
  Temp: string;
  DisplayName, InstallPath, ExecutablePath: string;
  Bitness: Integer;
begin
  if RegGetSubkeyNames(RegRoot, RegPath, Names) then
  begin
    for Nc := 0 to GetArrayLength(Names) - 1 do
    begin
      if RegGetSubkeyNames(RegRoot, RegPath + '\' + Names[Nc], Tags) then
      begin
        for Tc := 0 to GetArrayLength(Tags) - 1 do
        begin
          RegPathTemp := RegPath + '\' + Names[Nc] + '\' + Tags[Tc];
          Bitness := AssumeBitness;
          if (not RegQueryStringValue(RegRoot, RegPathTemp, 'SysVersion', Temp)) or (Temp <> '3.7') then
            continue;
          if RegQueryStringValue(RegRoot, RegPathTemp, 'SysArchitecture', Temp) then
          begin
            if Temp = '32bit' then
              Bitness := 32
            else if Temp = '64bit' then
              Bitness := 64;
          end;

          if RegQueryStringValue(RegRoot, RegPathTemp, 'DisplayName', DisplayName)
            and RegQueryStringValue(RegRoot, RegPathTemp + '\InstallPath', '', InstallPath)
            and RegQueryStringValue(RegRoot, RegPathTemp + '\InstallPath', 'ExecutablePath', ExecutablePath) then
          begin
             SetArrayLEngth(PythonInstallations, GetArrayLength(PythonInstallations) + 1);
             PythonInstallations[GetArrayLength(PythonInstallations) - 1].DisplayName := DisplayName;
             PythonInstallations[GetArrayLength(PythonInstallations) - 1].InstallPath := InstallPath;
             PythonInstallations[GetArrayLength(PythonInstallations) - 1].ExecutablePath := ExecutablePath;
             PythonInstallations[GetArrayLength(PythonInstallations) - 1].Bitness := Bitness;
          end;
        end;
      end;
    end;
  end;
end;

function GetPythonInstallations: Boolean;
begin
  if IsAdminInstallMode then
  begin
    GetPythonInstallations2(HKLM32, 'SOFTWARE\Python', 32);
    if Is64BitInstallMode then
      GetPythonInstallations2(HKLM, 'SOFTWARE\Python', 64);
  end
  else
  begin
    GetPythonInstallations2(HKCU, 'SOFTWARE\Python', 0);
  end;
  Result := (GetArrayLength(PythonInstallations) > 0);
end;

procedure PopulatePythonInstallations(List: TNewCheckListBox);
var
  Counter: Integer;
  First: Boolean;
begin
  List.Items.Clear;

  if WizardIsComponentSelected('vs32') then
  begin
    First := True;
    List.AddGroup('Python Environments (32-bit)', '', 0, nil);
    for Counter := 0 to GetArrayLength(PythonInstallations) - 1 do
      if PythonInstallations[Counter].Bitness = 32 then
        with PythonInstallations[Counter] do
        begin
          List.AddRadioButton(DisplayName, '(' + InstallPath + ')', 1, First, True, TObject(Counter));
          First := False;
        end;
  end;

  if WizardIsComponentSelected('vs64') then
  begin
    First := True;
    List.AddGroup('Python Environments (64-bit)', '', 0, nil);
    for Counter := 0 to GetArrayLength(PythonInstallations) - 1 do
      if PythonInstallations[Counter].Bitness = 64 then
        with PythonInstallations[Counter] do
        begin
          List.AddRadioButton(DisplayName, '(' + InstallPath + ')', 1, First, True, TObject(Counter));
          First := False;
        end;
  end;
end;

function InitializeSetup: Boolean;
begin
  Runtimes32Added := False;
  Runtimes64Added := False;
  PythonList := nil;
  Result := GetPythonInstallations;
  if not Result then
  begin
    if IsAdminInstallMode then
      MsgBox('No suitable global Python 3.7 installation found. Installer will now exit.', mbCriticalError, MB_OK)
    else
      MsgBox('No suitable per user Python 3.7 installation found. Installer will now exit.', mbCriticalError, MB_OK);
  end;
end;

procedure WizardFormOnResize(Sender: TObject);
begin
  with PythonList do
  begin
    Parent := PythonPage.Surface;
    Left := ScaleX(0);
    Top := ScaleY(0);
    Width := PythonPage.Surface.Width - ScaleX(0) * 2;
    Height := PythonPage.Surface.Height;
  end;
end;

procedure InitializeWizard();
begin
  PythonPage := CreateCustomPage(wpSelectComponents, 'Select Python Installations', 'Select one or more Python installations to use');
  PythonList := TNewCheckListBox.Create(PythonPage);

  with PythonList do
  begin
    Parent := PythonPage.Surface;
    Left := ScaleX(0);
    Top := ScaleY(0);
    Width := PythonPage.Surface.Width - ScaleX(0) * 2;
    Height := PythonPage.Surface.Height;
  end;

  WizardForm.OnResize := @WizardFormOnResize;
end;

function GetPythonPath32(Param: string): String;
begin
  Result := Python32Path;
end;

function GetPythonPath64(Param: String): String;
begin
  Result := Python64Path;
end;

function GetPythonExecutableAny(Param: string): String;
begin
  if Python64Executable <> '' then
    Result := Python64Executable
  else
    Result := Python32Executable;
end;

/////////////////////////////////////////////////////////////////////
function GetUninstallString: String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
  sUnInstallString := '';
  RegQueryStringValue(HKA, sUnInstPath, 'UninstallString', sUnInstallString)
  Result := sUnInstallString;
end;

/////////////////////////////////////////////////////////////////////
function IsUpgrade: Boolean;
begin
  Result := (GetUninstallString() <> '');
end;

/////////////////////////////////////////////////////////////////////
function UnInstallOldVersion: Integer;
var
  sUnInstallString: String;
  iResultCode: Integer;
begin
// Return Values:
// 1 - uninstall string is empty
// 2 - error executing the UnInstallString
// 3 - successfully executed the UnInstallString

  // default return value
  Result := 0;

  // get the uninstall string of the old app
  sUnInstallString := GetUninstallString();
  if sUnInstallString <> '' then begin
    sUnInstallString := RemoveQuotes(sUnInstallString);
    if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
      Result := 3
    else
      Result := 2;
  end
  else
    Result := 1;
end;

/////////////////////////////////////////////////////////////////////
procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep=ssInstall then
  begin
    if IsUpgrade() then
      UnInstallOldVersion();
  end;
end;

/////////////////////////////////////////////////////////////////////
function NextButtonClick(CurPageID: Integer): Boolean;
var
  Counter: Integer;
  Idx: Integer;
begin
  Result := True;
  if CurPageID = PythonPage.ID then
  begin
    for Counter := 0 to PythonList.Items.Count - 1 do
    begin
      if (PythonList.Checked[Counter]) and (PythonList.ItemLevel[Counter] = 1) then
      begin
        Idx := Integer(PythonList.ItemObject[Counter]);
        with PythonInstallations[Idx] do
        begin
          if Bitness = 64 then
          begin
            Python64Path := InstallPath;
            Python64Executable := ExecutablePath;
          end
          else if Bitness = 32 then
          begin
            Python32Path := InstallPath;
            Python32Executable := ExecutablePath;
          end;
        end;
      end;
    end;
  end
  else if CurPageID = wpSelectComponents then
  begin
    if not WizardIsComponentSelected('vs32 or vs64') then
    begin
      Result := False;
      MsgBox('At least one version of the core library has to be installed.', mbCriticalError, MB_OK)
    end;

    PopulatePythonInstallations(PythonList);
  end
  else if CurPageID = wpReady then
  begin
    if WizardIsComponentSelected('vsruntimes') and WizardIsComponentSelected('vs32') and not Runtimes32Added then
    begin
      SetForceX86(True);
      vcredist2017('14.21.27702');
      SetForceX86(False);
      Runtimes32Added := True;
    end;
    if WizardIsComponentSelected('vsruntimes') and WizardIsComponentSelected('vs64') and not Runtimes64Added then
    begin
      vcredist2017('14.21.27702');
      Runtimes64Added := True;
    end;
    Result := NextButtonClick2(CurPageID);
  end;
end;


fix package reference

fix package reference

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

[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={{9FD61024-BC9A-4226-ADA5-E72254250B6C}
AppName=FHIR Toolkit
AppVersion=0.1
AppVerName=FHIR ToolKit v0.0.64 (FHIR Version )
AppPublisher=Health Intersections
AppPublisherURL=http://www.healthintersections.com.au/FhirServer
AppSupportURL=http://www.healthintersections.com.au/FhirServer
AppUpdatesURL=http://www.healthintersections.com.au/FhirServer
DefaultDirName={pf}\FHIRToolkit
DefaultGroupName=FHIR Applications
AllowNoIcons=yes
LicenseFile=C:\work\fhirserver\toolkit\install\licence.txt
OutputDir=C:\work\fhirserver\toolkit\install
OutputBaseFilename=fhir-toolkit-install-0.0.64
SetupIconFile=C:\work\fhirserver\toolkit\AppEndorser_Icon.ico
Compression=lzma
SolidCompression=yes
ArchitecturesInstallIn64BitMode=x64
ArchitecturesAllowed=x64

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

[Files]
Source: "C:\work\fhirserver\exec\32\installer.dll";               Flags: dontcopy;
Source: "C:\work\fhirserver\toolkit\install\FHIRToolkitR4.exe";                                 DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\toolkit\install\FHIRToolkitR3.exe";                                 DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\toolkit\install\FHIRTransformer.exe";                               DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\Exec\32\cde-scintilla.dll";                                         DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\Exec\32\chakracore.dll";                                            DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\toolkit\install\osx\FHIRToolkit.app\Contents\MacOS\toolkit.png";    DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\toolkit\install\osx\FHIRToolkit.app\Contents\MacOS\*.xml";          DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\Exec\64\ssleay32.dll";                                              DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\Exec\64\libeay32.dll";                                              DestDir: "{app}"; Flags: ignoreversion

[Icons]
Name: "{group}\Toolkit (R4)"; Filename: "{app}\FHIRToolkitR4.exe"
Name: "{group}\Toolkit (R3)"; Filename: "{app}\FHIRToolkitR3.exe"
Name: "{group}\Transformer"; Filename: "{app}\FHIRTransformer.exe"
Name: "{group}\{cm:ProgramOnTheWeb,FHIR Toolkit}"; Filename: "http://www.healthintersections.com.au/FhirServer"

[Run]
Filename: "{app}\FHIRToolkitR3.exe"; Description: "{cm:LaunchProgram,FHIR Toolkit (R3)}"; Flags: nowait postinstall skipifsilent unchecked
Filename: "{app}\FHIRToolkitR4.exe"; Description: "{cm:LaunchProgram,FHIR Toolkit (R4)}"; Flags: nowait postinstall skipifsilent unchecked

[Code]
var
  LoadInstallPage : TOutputProgressWizardPage;

type
  TMyCallback = procedure(IntParam: Integer; StrParam: WideString);

Function MyDllDownloadPackages(mode : PAnsiChar; urls : PAnsiChar; callback: TMyCallback) : PAnsiChar; external 'MyDllDownloadPackages@files:installer.dll stdcall setuponly';

procedure InitCallback(IntParam: Integer; StrParam: WideString);
begin
  LoadInstallPage.SetProgress(intparam, 100);
  LoadInstallPage.SetText(StrParam, '');
end;

procedure InstallPackages;
var
  done : boolean;
  s : String;
  msg : String;
begin
  LoadInstallPage.SetText('Installing R3/R4/CDA Packages...', '');
  LoadInstallPage.SetProgress(0, 100);
  LoadInstallPage.Show;
  try
    s := ',hl7.fhir.r3.core#3.0.1,hl7.fhir.r4.core#4.0.0,hl7.fhir.cda#0.0.1';
    repeat
      done := true;
      msg := MyDllDownloadPackages('user', s, @InitCallback);
      if msg <> '' then
        done := MsgBox('Downloading the packages failed : '+msg+#13#10+'Try again? (can be done later through installed applications)', mbError, MB_YESNO) = mrNo;
    until done;
  finally
    LoadInstallPage.Hide;
  end;

end;

Procedure CreatePostInstallPage;
Begin
  LoadInstallPage := CreateOutputProgressPage('Perform Installation tasks', '');
End;

procedure InitializeWizard();
Begin
  CreatePostInstallPage;
End;

procedure CurStepChanged(CurStep: TSetupStep);
Begin
  if (CurStep = ssPostInstall)  Then
    InstallPackages;
End;

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

[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={{9FD61024-BC9A-4226-ADA5-E72254250B6C}
AppName=FHIR Toolkit
AppVersion=0.1
AppVerName=FHIR ToolKit v0.0.64 (FHIR Version )
AppPublisher=Health Intersections
AppPublisherURL=http://www.healthintersections.com.au/FhirServer
AppSupportURL=http://www.healthintersections.com.au/FhirServer
AppUpdatesURL=http://www.healthintersections.com.au/FhirServer
DefaultDirName={pf}\FHIRToolkit
DefaultGroupName=FHIR Applications
AllowNoIcons=yes
LicenseFile=C:\work\fhirserver\toolkit\install\licence.txt
OutputDir=C:\work\fhirserver\toolkit\install
OutputBaseFilename=fhir-toolkit-install-0.0.64
SetupIconFile=C:\work\fhirserver\toolkit\AppEndorser_Icon.ico
Compression=lzma
SolidCompression=yes
ArchitecturesInstallIn64BitMode=x64
ArchitecturesAllowed=x64

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

[Files]
Source: "C:\work\fhirserver\exec\32\installer.dll";               Flags: dontcopy;
Source: "C:\work\fhirserver\toolkit\install\FHIRToolkitR4.exe";                                 DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\toolkit\install\FHIRToolkitR3.exe";                                 DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\toolkit\install\FHIRTransformer.exe";                               DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\Exec\32\cde-scintilla.dll";                                         DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\Exec\32\chakracore.dll";                                            DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\toolkit\install\osx\FHIRToolkit.app\Contents\MacOS\toolkit.png";    DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\toolkit\install\osx\FHIRToolkit.app\Contents\MacOS\*.xml";          DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\Exec\64\ssleay32.dll";                                              DestDir: "{app}"; Flags: ignoreversion
Source: "C:\work\fhirserver\Exec\64\libeay32.dll";                                              DestDir: "{app}"; Flags: ignoreversion

[Icons]
Name: "{group}\Toolkit (R4)"; Filename: "{app}\FHIRToolkitR4.exe"
Name: "{group}\Toolkit (R3)"; Filename: "{app}\FHIRToolkitR3.exe"
Name: "{group}\Transformer"; Filename: "{app}\FHIRTransformer.exe"
Name: "{group}\{cm:ProgramOnTheWeb,FHIR Toolkit}"; Filename: "http://www.healthintersections.com.au/FhirServer"

[Run]
Filename: "{app}\FHIRToolkitR3.exe"; Description: "{cm:LaunchProgram,FHIR Toolkit (R3)}"; Flags: nowait postinstall skipifsilent unchecked
Filename: "{app}\FHIRToolkitR4.exe"; Description: "{cm:LaunchProgram,FHIR Toolkit (R4)}"; Flags: nowait postinstall skipifsilent unchecked

[Code]
var
  LoadInstallPage : TOutputProgressWizardPage;

type
  TMyCallback = procedure(IntParam: Integer; StrParam: WideString);

Function MyDllDownloadPackages(mode : PAnsiChar; urls : PAnsiChar; callback: TMyCallback) : PAnsiChar; external 'MyDllDownloadPackages@files:installer.dll stdcall setuponly';

procedure InitCallback(IntParam: Integer; StrParam: WideString);
begin
  LoadInstallPage.SetProgress(intparam, 100);
  LoadInstallPage.SetText(StrParam, '');
end;

procedure InstallPackages;
var
  done : boolean;
  s : String;
  msg : String;
begin
  LoadInstallPage.SetText('Installing R3/R4/CDA Packages...', '');
  LoadInstallPage.SetProgress(0, 100);
  LoadInstallPage.Show;
  try
    s := ',hl7.fhir.core#3.0.1,hl7.fhir.core#4.0.0,hl7.fhir.cda#0.0.1';
    repeat
      done := true;
      msg := MyDllDownloadPackages('user', s, @InitCallback);
      if msg <> '' then
        done := MsgBox('Downloading the packages failed : '+msg+#13#10+'Try again? (can be done later through installed applications)', mbError, MB_YESNO) = mrNo;
    until done;
  finally
    LoadInstallPage.Hide;
  end;

end;

Procedure CreatePostInstallPage;
Begin
  LoadInstallPage := CreateOutputProgressPage('Perform Installation tasks', '');
End;

procedure InitializeWizard();
Begin
  CreatePostInstallPage;
End;

procedure CurStepChanged(CurStep: TSetupStep);
Begin
  if (CurStep = ssPostInstall)  Then
    InstallPackages;
End;


License is accepted by default.

License is accepted by default.

#define AppName        GetStringFileInfo('..\Binaries\VhdAttach.exe', 'ProductName')
#define AppVersion     GetStringFileInfo('..\Binaries\VhdAttach.exe', 'ProductVersion')
#define AppFileVersion GetStringFileInfo('..\Binaries\VhdAttach.exe', 'FileVersion')
#define AppCompany     GetStringFileInfo('..\Binaries\VhdAttach.exe', 'CompanyName')
#define AppCopyright   GetStringFileInfo('..\Binaries\VhdAttach.exe', 'LegalCopyright')
#define AppBase        LowerCase(StringChange(AppName, ' ', ''))
#define AppSetupFile   AppBase + StringChange(AppVersion, '.', '')

#define AppVersionEx   StringChange(AppVersion, '0.00', '')
#if "" != HgNode
#  define AppVersionEx AppVersionEx + " (" + HgNode + ")"
#endif

[Setup]
AppName={#AppName}
AppVersion={#AppVersion}
AppVerName={#AppName} {#AppVersion}
AppPublisher={#AppCompany}
AppPublisherURL=http://jmedved.com/{#AppBase}/
AppCopyright={#AppCopyright}
VersionInfoProductVersion={#AppVersion}
VersionInfoProductTextVersion={#AppVersionEx}
VersionInfoVersion={#AppFileVersion}
DefaultDirName={pf}\{#AppCompany}\{#AppName}
OutputBaseFilename={#AppSetupFile}
OutputDir=..\Releases
SourceDir=..\Binaries
AppId=JosipMedved_VhdAttach
CloseApplications="yes"
RestartApplications="no"
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
LicenseFile=..\Setup\License.txt

[Messages]
SetupAppTitle=Setup {#AppName} {#AppVersionEx}
SetupWindowTitle=Setup {#AppName} {#AppVersionEx}
BeveledLabel=jmedved.com

[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_open;                GroupDescription: "Context menu items:";      Description: "Open";                                 OnlyBelowVersion: 6.2;
Name: context_attach;              GroupDescription: "Context menu items:";      Description: "Attach";                               OnlyBelowVersion: 6.2;
Name: context_attachreadonly;      GroupDescription: "Context menu items:";      Description: "Attach read-only";  Flags: unchecked;  OnlyBelowVersion: 6.2;
Name: context_detach;              GroupDescription: "Context menu items:";      Description: "Detach";                               OnlyBelowVersion: 6.2;
Name: context_detachdrive;         GroupDescription: "Context menu items:";      Description: "Detach drive";      Flags: unchecked;  OnlyBelowVersion: 6.2;

Name: context_vhd_open;            GroupDescription: "VHD context menu items:";  Description: "Open";                                 MinVersion: 6.2;
Name: context_vhd_attach;          GroupDescription: "VHD context menu items:";  Description: "Attach";                               MinVersion: 6.2;
Name: context_vhd_attachreadonly;  GroupDescription: "VHD context menu items:";  Description: "Attach read-only";  Flags: unchecked;  MinVersion: 6.2;
Name: context_vhd_detach;          GroupDescription: "VHD context menu items:";  Description: "Detach";                               MinVersion: 6.2;
Name: context_iso_open;            GroupDescription: "ISO context menu items:";  Description: "Open";                                 MinVersion: 6.2;
Name: context_iso_attachreadonly;  GroupDescription: "ISO context menu items:";  Description: "Attach";                               MinVersion: 6.2;
Name: context_iso_detach;          GroupDescription: "ISO context menu items:";  Description: "Detach";                               MinVersion: 6.2;

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

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

Root: HKCR;  Subkey: ".vhd";                                                    ValueType: none;    ValueName: "";                  Flags: deletevalue;                                                      Tasks: context_open context_attach context_attachreadonly context_detach context_detachdrive context_vhd_open context_vhd_attach context_vhd_attachreadonly context_vhd_detach;
Root: HKCR;  Subkey: ".vhd\OpenWithProgids";                                    ValueType: string;  ValueName: "Windows.VhdFile";   ValueData: "";                                                           Tasks: context_open context_attach context_attachreadonly context_detach context_detachdrive context_vhd_open context_vhd_attach context_vhd_attachreadonly context_vhd_detach;
Root: HKCR;  Subkey: "Windows.VhdFile\DefaultIcon";                             ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe""";  Flags: createvalueifdoesntexist;  Tasks: context_open context_attach context_attachreadonly context_detach context_detachdrive context_vhd_open context_vhd_attach context_vhd_attachreadonly context_vhd_detach;

Root: HKCR;  Subkey: "VhdAttachFile";                                           ValueType: none;    Flags: deletekey;

Root: HKCR;  Subkey: "Windows.VhdFile\shell";                                   ValueType: string;  ValueName: "";                  ValueData: "VhdAttach-Open";                                    Tasks: context_open context_vhd_open;

Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open";                    ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "";                  ValueData: "Open with VHD Attach";                              Tasks: context_open context_vhd_open;
Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_open context_vhd_open;
Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Document";                                          Tasks: context_open context_vhd_open;
Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open\command";            ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" ""%1""";                    Tasks: context_open context_vhd_open;

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

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

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

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

Root: HKCR;  Subkey: ".iso";                                                    ValueType: none;    ValueName: "";                  Flags: deletevalue;                                                      Tasks: context_iso_open context_iso_attachreadonly context_iso_detach;
Root: HKCR;  Subkey: ".iso\OpenWithProgids";                                    ValueType: string;  ValueName: "Windows.IsoFile";   ValueData: "";                                                           Tasks: context_iso_open context_iso_attachreadonly context_iso_detach;
Root: HKCR;  Subkey: "Windows.VhdFile\DefaultIcon";                             ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe""";  Flags: createvalueifdoesntexist;  Tasks: context_iso_open context_iso_attachreadonly context_iso_detach;

Root: HKCR;  Subkey: "Windows.IsoFile\shell";                                   ValueType: string;  ValueName: "";                  ValueData: "VhdAttach-Open";                                    Tasks: context_iso_open;

Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open";                    ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "";                  ValueData: "Open with VHD Attach";                              Tasks: context_iso_open;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_iso_open;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Document";                                          Tasks: context_iso_open;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open\command";            ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" ""%1""";                    Tasks: context_iso_open;

Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly";          ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly";          ValueType: string;  ValueName: "";                  ValueData: "Attach";                                            Tasks: context_iso_attachreadonly;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly";          ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_iso_attachreadonly;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly";          ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Document";                                          Tasks: context_iso_attachreadonly;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly\command";  ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /readonly /attach ""%1""";  Tasks: context_iso_attachreadonly;

Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach";                  ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach";                  ValueType: string;  ValueName: "";                  ValueData: "Detach";                                            Tasks: context_iso_detach;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach";                  ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_iso_detach;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach";                  ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Document";                                          Tasks: context_iso_detach;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach\command";          ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /detach ""%1""";            Tasks: context_iso_detach;

[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]

procedure InitializeWizard;
begin
  WizardForm.LicenseAcceptedRadio.Checked := True;
end;

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

#define AppName        GetStringFileInfo('..\Binaries\VhdAttach.exe', 'ProductName')
#define AppVersion     GetStringFileInfo('..\Binaries\VhdAttach.exe', 'ProductVersion')
#define AppFileVersion GetStringFileInfo('..\Binaries\VhdAttach.exe', 'FileVersion')
#define AppCompany     GetStringFileInfo('..\Binaries\VhdAttach.exe', 'CompanyName')
#define AppCopyright   GetStringFileInfo('..\Binaries\VhdAttach.exe', 'LegalCopyright')
#define AppBase        LowerCase(StringChange(AppName, ' ', ''))
#define AppSetupFile   AppBase + StringChange(AppVersion, '.', '')

#define AppVersionEx   StringChange(AppVersion, '0.00', '')
#if "" != HgNode
#  define AppVersionEx AppVersionEx + " (" + HgNode + ")"
#endif

[Setup]
AppName={#AppName}
AppVersion={#AppVersion}
AppVerName={#AppName} {#AppVersion}
AppPublisher={#AppCompany}
AppPublisherURL=http://jmedved.com/{#AppBase}/
AppCopyright={#AppCopyright}
VersionInfoProductVersion={#AppVersion}
VersionInfoProductTextVersion={#AppVersionEx}
VersionInfoVersion={#AppFileVersion}
DefaultDirName={pf}\{#AppCompany}\{#AppName}
OutputBaseFilename={#AppSetupFile}
OutputDir=..\Releases
SourceDir=..\Binaries
AppId=JosipMedved_VhdAttach
CloseApplications="yes"
RestartApplications="no"
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
LicenseFile=..\Setup\License.txt

[Messages]
SetupAppTitle=Setup {#AppName} {#AppVersionEx}
SetupWindowTitle=Setup {#AppName} {#AppVersionEx}
BeveledLabel=jmedved.com

[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_open;                GroupDescription: "Context menu items:";      Description: "Open";                                 OnlyBelowVersion: 6.2;
Name: context_attach;              GroupDescription: "Context menu items:";      Description: "Attach";                               OnlyBelowVersion: 6.2;
Name: context_attachreadonly;      GroupDescription: "Context menu items:";      Description: "Attach read-only";  Flags: unchecked;  OnlyBelowVersion: 6.2;
Name: context_detach;              GroupDescription: "Context menu items:";      Description: "Detach";                               OnlyBelowVersion: 6.2;
Name: context_detachdrive;         GroupDescription: "Context menu items:";      Description: "Detach drive";      Flags: unchecked;  OnlyBelowVersion: 6.2;

Name: context_vhd_open;            GroupDescription: "VHD context menu items:";  Description: "Open";                                 MinVersion: 6.2;
Name: context_vhd_attach;          GroupDescription: "VHD context menu items:";  Description: "Attach";                               MinVersion: 6.2;
Name: context_vhd_attachreadonly;  GroupDescription: "VHD context menu items:";  Description: "Attach read-only";  Flags: unchecked;  MinVersion: 6.2;
Name: context_vhd_detach;          GroupDescription: "VHD context menu items:";  Description: "Detach";                               MinVersion: 6.2;
Name: context_iso_open;            GroupDescription: "ISO context menu items:";  Description: "Open";                                 MinVersion: 6.2;
Name: context_iso_attachreadonly;  GroupDescription: "ISO context menu items:";  Description: "Attach";                               MinVersion: 6.2;
Name: context_iso_detach;          GroupDescription: "ISO context menu items:";  Description: "Detach";                               MinVersion: 6.2;

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

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

Root: HKCR;  Subkey: ".vhd";                                                    ValueType: none;    ValueName: "";                  Flags: deletevalue;                                                      Tasks: context_open context_attach context_attachreadonly context_detach context_detachdrive context_vhd_open context_vhd_attach context_vhd_attachreadonly context_vhd_detach;
Root: HKCR;  Subkey: ".vhd\OpenWithProgids";                                    ValueType: string;  ValueName: "Windows.VhdFile";   ValueData: "";                                                           Tasks: context_open context_attach context_attachreadonly context_detach context_detachdrive context_vhd_open context_vhd_attach context_vhd_attachreadonly context_vhd_detach;
Root: HKCR;  Subkey: "Windows.VhdFile\DefaultIcon";                             ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe""";  Flags: createvalueifdoesntexist;  Tasks: context_open context_attach context_attachreadonly context_detach context_detachdrive context_vhd_open context_vhd_attach context_vhd_attachreadonly context_vhd_detach;

Root: HKCR;  Subkey: "VhdAttachFile";                                           ValueType: none;    Flags: deletekey;

Root: HKCR;  Subkey: "Windows.VhdFile\shell";                                   ValueType: string;  ValueName: "";                  ValueData: "VhdAttach-Open";                                    Tasks: context_open context_vhd_open;

Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open";                    ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "";                  ValueData: "Open with VHD Attach";                              Tasks: context_open context_vhd_open;
Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_open context_vhd_open;
Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Document";                                          Tasks: context_open context_vhd_open;
Root: HKCR;  Subkey: "Windows.VhdFile\shell\VhdAttach-Open\command";            ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" ""%1""";                    Tasks: context_open context_vhd_open;

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

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

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

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

Root: HKCR;  Subkey: ".iso";                                                    ValueType: none;    ValueName: "";                  Flags: deletevalue;                                                      Tasks: context_iso_open context_iso_attachreadonly context_iso_detach;
Root: HKCR;  Subkey: ".iso\OpenWithProgids";                                    ValueType: string;  ValueName: "Windows.IsoFile";   ValueData: "";                                                           Tasks: context_iso_open context_iso_attachreadonly context_iso_detach;
Root: HKCR;  Subkey: "Windows.VhdFile\DefaultIcon";                             ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe""";  Flags: createvalueifdoesntexist;  Tasks: context_iso_open context_iso_attachreadonly context_iso_detach;

Root: HKCR;  Subkey: "Windows.IsoFile\shell";                                   ValueType: string;  ValueName: "";                  ValueData: "VhdAttach-Open";                                    Tasks: context_iso_open;

Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open";                    ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "";                  ValueData: "Open with VHD Attach";                              Tasks: context_iso_open;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_iso_open;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open";                    ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Document";                                          Tasks: context_iso_open;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Open\command";            ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" ""%1""";                    Tasks: context_iso_open;

Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly";          ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly";          ValueType: string;  ValueName: "";                  ValueData: "Attach";                                            Tasks: context_iso_attachreadonly;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly";          ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_iso_attachreadonly;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly";          ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Document";                                          Tasks: context_iso_attachreadonly;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-AttachReadOnly\command";  ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /readonly /attach ""%1""";  Tasks: context_iso_attachreadonly;

Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach";                  ValueType: none;    Flags: deletekey uninsdeletekey;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach";                  ValueType: string;  ValueName: "";                  ValueData: "Detach";                                            Tasks: context_iso_detach;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach";                  ValueType: string;  ValueName: "Icon";              ValueData: """{app}\VhdAttach.exe""";                           Tasks: context_iso_detach;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach";                  ValueType: string;  ValueName: "MultiSelectModel";  ValueData: "Document";                                          Tasks: context_iso_detach;
Root: HKCR;  Subkey: "Windows.IsoFile\shell\VhdAttach-Detach\command";          ValueType: string;  ValueName: "";                  ValueData: """{app}\VhdAttach.exe"" /detach ""%1""";            Tasks: context_iso_detach;

[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)
    Result := Result;
end;