Version bump to 1.7.0

Version bump to 1.7.0

#define ShortName "Pictus"
#define LongName "Pictus Image Viewer"

[Setup]
ArchitecturesAllowed=x86 x64
ArchitecturesInstallIn64BitMode=x64
AppName=Pictus
AppMutex=Local\Pictus Viewer
AppPublisherURL=https://www.poppeman.se/
AppSupportURL=https://www.poppeman.se/pictus
AppUpdatesURL=https://www.poppeman.se/pictus
AppVerName=Pictus
DefaultDirName={pf}\Pictus
MinVersion=0.0,5.01
UninstallDisplayIcon={app}\Pictus.exe
VersionInfoDescription=Pictus Setup
OutputBaseFilename=PictInst
OutputDir=../../dist/
DisableProgramGroupPage=yes
VersionInfoVersion=1.7.0.0
DisableDirPage=auto

[Languages]
Name: en; MessagesFile: "compiler:Default.isl"; LicenseFile: "license_en.txt"
Name: sv; MessagesFile: "compiler:Languages\Swedish.isl"; LicenseFile: "license_sv.txt"

[CustomMessages]
en.ExplorerIntegration=Show thumbnails in Explorer
sv.ExplorerIntegration=Visa tummnaglar i Utforskaren

[Components]
Name: "integration"; Description: "{cm:ExplorerIntegration}"; Types: full custom

[Files]
Source: "..\x64\release\Pictus.exe"; DestDir: "{app}"; Flags: replacesameversion; Check: Is64BitInstallMode
Source: "..\release\Pictus.exe"; DestDir: "{app}"; Flags: replacesameversion; Check: not Is64BitInstallMode
Source: "..\x64\release\PictThumbs.dll"; DestDir: "{app}"; Flags: replacesameversion regserver; Check: Is64BitInstallMode; Components: integration
Source: "..\release\PictThumbs.dll"; DestDir: "{app}"; Flags: replacesameversion regserver; Check: not Is64BitInstallMode; Components: integration
Source: "..\..\Readme.txt"; DestDir: "{app}"; Flags: replacesameversion

[Icons]
Name: "{commonprograms}\Pictus"; Filename: "{app}\Pictus.exe"

[Tasks]
Name: "assoc_bmp"; Description: "{cm:AssocFileExtension,{#ShortName},.bmp}"
Name: "assoc_gif"; Description: "{cm:AssocFileExtension,{#ShortName},.gif}"
Name: "assoc_jpg"; Description: "{cm:AssocFileExtension,{#ShortName},.jpg}"
Name: "assoc_pcx"; Description: "{cm:AssocFileExtension,{#ShortName},.pcx}"
Name: "assoc_png"; Description: "{cm:AssocFileExtension,{#ShortName},.png}"
Name: "assoc_psd"; Description: "{cm:AssocFileExtension,{#ShortName},.psd}"; Flags: unchecked
Name: "assoc_psp"; Description: "{cm:AssocFileExtension,{#ShortName},.psp}"; Flags: unchecked
Name: "assoc_tga"; Description: "{cm:AssocFileExtension,{#ShortName},.tga}"
Name: "assoc_tif"; Description: "{cm:AssocFileExtension,{#ShortName},.tiff}"
Name: "assoc_wbmp"; Description: "{cm:AssocFileExtension,{#ShortName},.wbmp}"
Name: "assoc_webp"; Description: "{cm:AssocFileExtension,{#ShortName},.webp}"
Name: "assoc_xyz"; Description: "{cm:AssocFileExtension,{#ShortName},.xyz}"

[Registry]
Root: HKLM; Subkey: "SOFTWARE\Poppeman"; Flags: uninsdeletekeyifempty
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities"; ValueType: string; ValueName: "ApplicationDescription"; ValueData: "Pictus is a fast, lightweight image viewer."
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities"; ValueType: string; ValueName: "ApplicationName"; ValueData: "{#LongName}"
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".bmp"; ValueData: "Pictus.BMP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".gif"; ValueData: "Pictus.GIF"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".jfif"; ValueData: "Pictus.JPG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".jpe"; ValueData: "Pictus.JPG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".jpeg"; ValueData: "Pictus.JPG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".jpg"; ValueData: "Pictus.JPG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".pcx"; ValueData: "Pictus.PCX"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".png"; ValueData: "Pictus.PNG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".psd"; ValueData: "Pictus.PSD"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".psp"; ValueData: "Pictus.PSP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".pspimage"; ValueData: "Pictus.PSP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".tga"; ValueData: "Pictus.TGA"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".tif"; ValueData: "Pictus.TIF"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".tiff"; ValueData: "Pictus.TIF"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".wbm"; ValueData: "Pictus.WBMP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".wbmp"; ValueData: "Pictus.WBMP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".webp"; ValueData: "Pictus.WEBP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".xif"; ValueData: "Pictus.TIF"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".xyz"; ValueData: "Pictus.XYZ"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\RegisteredApplications"; ValueType: string; ValueName: "Pictus Image Viewer"; ValueData: "SOFTWARE\Poppeman\Pictus\Capabilities"; Flags: uninsdeletevalue

Root: HKCR; Subkey: "Pictus.BMP"; ValueType: string; ValueData: "Bitmap image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.BMP\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.GIF"; ValueType: string; ValueData: "GIF image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.GIF\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.JPG"; ValueType: string; ValueData: "Jpeg image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.JPG\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PCX"; ValueType: string; ValueData: "PCX image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PCX\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PNG"; ValueType: string; ValueData: "PNG image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PNG\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PSD"; ValueType: string; ValueData: "Photoshop image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PSD\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PSP"; ValueType: string; ValueData: "Paint Shop Pro image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PSP\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.TGA"; ValueType: string; ValueData: "Targa TGA image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.TGA\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.TIF"; ValueType: string; ValueData: "TIFF image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.TIF\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.WBMP"; ValueType: string; ValueData: "Wireless bitmap image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.WBMP\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.WEBP"; ValueType: string; ValueData: "Wireless bitmap image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.WEBP\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.XYZ"; ValueType: string; ValueData: "XYZ image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.XYZ\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey

Root: HKCR; Subkey: ".bmp"; ValueType: String; ValueData: "Pictus.BMP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_bmp
Root: HKCR; Subkey: ".gif"; ValueType: String; ValueData: "Pictus.GIF"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_gif
Root: HKCR; Subkey: ".jfif"; ValueType: String; ValueData: "Pictus.JPG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_jpg
Root: HKCR; Subkey: ".jpe"; ValueType: String; ValueData: "Pictus.JPG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_jpg
Root: HKCR; Subkey: ".jpeg"; ValueType: String; ValueData: "Pictus.JPG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_jpg
Root: HKCR; Subkey: ".jpg"; ValueType: String; ValueData: "Pictus.JPG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_jpg
Root: HKCR; Subkey: ".pcx"; ValueType: String; ValueData: "Pictus.PCX"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_pcx
Root: HKCR; Subkey: ".png"; ValueType: String; ValueData: "Pictus.PNG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_png
Root: HKCR; Subkey: ".psd"; ValueType: String; ValueData: "Pictus.PSD"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_psd
Root: HKCR; Subkey: ".psp"; ValueType: String; ValueData: "Pictus.PSP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_psp
Root: HKCR; Subkey: ".pspimage"; ValueType: String; ValueData: "Pictus.PSP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_psp
Root: HKCR; Subkey: ".tga"; ValueType: String; ValueData: "Pictus.TGA"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_tga
Root: HKCR; Subkey: ".tif"; ValueType: String; ValueData: "Pictus.TIF"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_tif
Root: HKCR; Subkey: ".tiff"; ValueType: String; ValueData: "Pictus.TIF"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_tif
Root: HKCR; Subkey: ".wbm"; ValueType: String; ValueData: "Pictus.WBMP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_wbmp
Root: HKCR; Subkey: ".wbmp"; ValueType: String; ValueData: "Pictus.WBMP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_wbmp
Root: HKCR; Subkey: ".webp"; ValueType: String; ValueData: "Pictus.WEBP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_webp
Root: HKCR; Subkey: ".xif"; ValueType: String; ValueData: "Pictus.TIF"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_tif
Root: HKCR; Subkey: ".xyz"; ValueType: String; ValueData: "Pictus.XYZ"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_xyz

#define ShortName "Pictus"
#define LongName "Pictus Image Viewer"

[Setup]
ArchitecturesAllowed=x86 x64
ArchitecturesInstallIn64BitMode=x64
AppName=Pictus
AppMutex=Local\Pictus Viewer
AppPublisherURL=https://www.poppeman.se/
AppSupportURL=https://www.poppeman.se/pictus
AppUpdatesURL=https://www.poppeman.se/pictus
AppVerName=Pictus
DefaultDirName={pf}\Pictus
MinVersion=0.0,5.01
UninstallDisplayIcon={app}\Pictus.exe
VersionInfoDescription=Pictus Setup
OutputBaseFilename=PictInst
OutputDir=../../dist/
DisableProgramGroupPage=yes
VersionInfoVersion=1.6.0.0
DisableDirPage=auto

[Languages]
Name: en; MessagesFile: "compiler:Default.isl"; LicenseFile: "license_en.txt"
Name: sv; MessagesFile: "compiler:Languages\Swedish.isl"; LicenseFile: "license_sv.txt"

[CustomMessages]
en.ExplorerIntegration=Show thumbnails in Explorer
sv.ExplorerIntegration=Visa tummnaglar i Utforskaren

[Components]
Name: "integration"; Description: "{cm:ExplorerIntegration}"; Types: full custom

[Files]
Source: "..\x64\release\Pictus.exe"; DestDir: "{app}"; Flags: replacesameversion; Check: Is64BitInstallMode
Source: "..\release\Pictus.exe"; DestDir: "{app}"; Flags: replacesameversion; Check: not Is64BitInstallMode
Source: "..\x64\release\PictThumbs.dll"; DestDir: "{app}"; Flags: replacesameversion regserver; Check: Is64BitInstallMode; Components: integration
Source: "..\release\PictThumbs.dll"; DestDir: "{app}"; Flags: replacesameversion regserver; Check: not Is64BitInstallMode; Components: integration
Source: "..\..\Readme.txt"; DestDir: "{app}"; Flags: replacesameversion

[Icons]
Name: "{commonprograms}\Pictus"; Filename: "{app}\Pictus.exe"

[Tasks]
Name: "assoc_bmp"; Description: "{cm:AssocFileExtension,{#ShortName},.bmp}"
Name: "assoc_gif"; Description: "{cm:AssocFileExtension,{#ShortName},.gif}"
Name: "assoc_jpg"; Description: "{cm:AssocFileExtension,{#ShortName},.jpg}"
Name: "assoc_pcx"; Description: "{cm:AssocFileExtension,{#ShortName},.pcx}"
Name: "assoc_png"; Description: "{cm:AssocFileExtension,{#ShortName},.png}"
Name: "assoc_psd"; Description: "{cm:AssocFileExtension,{#ShortName},.psd}"; Flags: unchecked
Name: "assoc_psp"; Description: "{cm:AssocFileExtension,{#ShortName},.psp}"; Flags: unchecked
Name: "assoc_tga"; Description: "{cm:AssocFileExtension,{#ShortName},.tga}"
Name: "assoc_tif"; Description: "{cm:AssocFileExtension,{#ShortName},.tiff}"
Name: "assoc_wbmp"; Description: "{cm:AssocFileExtension,{#ShortName},.wbmp}"
Name: "assoc_webp"; Description: "{cm:AssocFileExtension,{#ShortName},.webp}"
Name: "assoc_xyz"; Description: "{cm:AssocFileExtension,{#ShortName},.xyz}"

[Registry]
Root: HKLM; Subkey: "SOFTWARE\Poppeman"; Flags: uninsdeletekeyifempty
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities"; ValueType: string; ValueName: "ApplicationDescription"; ValueData: "Pictus is a fast, lightweight image viewer."
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities"; ValueType: string; ValueName: "ApplicationName"; ValueData: "{#LongName}"
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".bmp"; ValueData: "Pictus.BMP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".gif"; ValueData: "Pictus.GIF"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".jfif"; ValueData: "Pictus.JPG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".jpe"; ValueData: "Pictus.JPG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".jpeg"; ValueData: "Pictus.JPG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".jpg"; ValueData: "Pictus.JPG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".pcx"; ValueData: "Pictus.PCX"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".png"; ValueData: "Pictus.PNG"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".psd"; ValueData: "Pictus.PSD"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".psp"; ValueData: "Pictus.PSP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".pspimage"; ValueData: "Pictus.PSP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".tga"; ValueData: "Pictus.TGA"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".tif"; ValueData: "Pictus.TIF"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".tiff"; ValueData: "Pictus.TIF"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".wbm"; ValueData: "Pictus.WBMP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".wbmp"; ValueData: "Pictus.WBMP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".webp"; ValueData: "Pictus.WEBP"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".xif"; ValueData: "Pictus.TIF"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\Poppeman\Pictus\Capabilities\FileAssociations"; ValueType: string; ValueName: ".xyz"; ValueData: "Pictus.XYZ"; Flags: uninsdeletekey
Root: HKLM; Subkey: "SOFTWARE\RegisteredApplications"; ValueType: string; ValueName: "Pictus Image Viewer"; ValueData: "SOFTWARE\Poppeman\Pictus\Capabilities"; Flags: uninsdeletevalue

Root: HKCR; Subkey: "Pictus.BMP"; ValueType: string; ValueData: "Bitmap image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.BMP\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.GIF"; ValueType: string; ValueData: "GIF image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.GIF\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.JPG"; ValueType: string; ValueData: "Jpeg image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.JPG\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PCX"; ValueType: string; ValueData: "PCX image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PCX\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PNG"; ValueType: string; ValueData: "PNG image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PNG\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PSD"; ValueType: string; ValueData: "Photoshop image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PSD\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PSP"; ValueType: string; ValueData: "Paint Shop Pro image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.PSP\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.TGA"; ValueType: string; ValueData: "Targa TGA image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.TGA\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.TIF"; ValueType: string; ValueData: "TIFF image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.TIF\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.WBMP"; ValueType: string; ValueData: "Wireless bitmap image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.WBMP\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.WEBP"; ValueType: string; ValueData: "Wireless bitmap image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.WEBP\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.XYZ"; ValueType: string; ValueData: "XYZ image"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Pictus.XYZ\shell\open\command"; ValueType: string; ValueData: """{app}\Pictus.exe"" ""%1"""; Flags: uninsdeletekey

Root: HKCR; Subkey: ".bmp"; ValueType: String; ValueData: "Pictus.BMP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_bmp
Root: HKCR; Subkey: ".gif"; ValueType: String; ValueData: "Pictus.GIF"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_gif
Root: HKCR; Subkey: ".jfif"; ValueType: String; ValueData: "Pictus.JPG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_jpg
Root: HKCR; Subkey: ".jpe"; ValueType: String; ValueData: "Pictus.JPG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_jpg
Root: HKCR; Subkey: ".jpeg"; ValueType: String; ValueData: "Pictus.JPG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_jpg
Root: HKCR; Subkey: ".jpg"; ValueType: String; ValueData: "Pictus.JPG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_jpg
Root: HKCR; Subkey: ".pcx"; ValueType: String; ValueData: "Pictus.PCX"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_pcx
Root: HKCR; Subkey: ".png"; ValueType: String; ValueData: "Pictus.PNG"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_png
Root: HKCR; Subkey: ".psd"; ValueType: String; ValueData: "Pictus.PSD"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_psd
Root: HKCR; Subkey: ".psp"; ValueType: String; ValueData: "Pictus.PSP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_psp
Root: HKCR; Subkey: ".pspimage"; ValueType: String; ValueData: "Pictus.PSP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_psp
Root: HKCR; Subkey: ".tga"; ValueType: String; ValueData: "Pictus.TGA"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_tga
Root: HKCR; Subkey: ".tif"; ValueType: String; ValueData: "Pictus.TIF"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_tif
Root: HKCR; Subkey: ".tiff"; ValueType: String; ValueData: "Pictus.TIF"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_tif
Root: HKCR; Subkey: ".wbm"; ValueType: String; ValueData: "Pictus.WBMP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_wbmp
Root: HKCR; Subkey: ".wbmp"; ValueType: String; ValueData: "Pictus.WBMP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_wbmp
Root: HKCR; Subkey: ".webp"; ValueType: String; ValueData: "Pictus.WEBP"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_webp
Root: HKCR; Subkey: ".xif"; ValueType: String; ValueData: "Pictus.TIF"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_tif
Root: HKCR; Subkey: ".xyz"; ValueType: String; ValueData: "Pictus.XYZ"; Flags: uninsdeletevalue uninsdeletekeyifempty; Tasks: assoc_xyz


Update version number in Windows installer

Set for next Sandstorm release version (somewhat optimistically). But either way it'll be more accurate than a date in 2015, and give some clear indication if a user has installed a modern vagrant-spk.

Fixes #208.

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

#define MyAppName "vagrant-spk"
#define MyAppVersion "v0.233"
#define MyAppPublisher "Sandstorm Development Group, Inc."
#define MyAppURL "https://docs.sandstorm.io/"
#define MyAppExeName "vagrant-spk.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{1EAFBDE2-157F-46F4-B5AB-6858FD3A0D8A}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=dist\innosetup
OutputBaseFilename=vagrant-spk-setup
Compression=lzma
SolidCompression=yes
ChangesEnvironment=true

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

[Tasks]
Name: modifypath; Description: &Add application directory to your environmental path

[Files]
; vagrant-spk itself
Source: "dist\vagrant-spk.exe"; DestDir: "{app}"; Flags: ignoreversion

; vagrant-spk platform stacks
Source: "..\stacks\*"; DestDir: "{app}\stacks"; Flags: recursesubdirs

; "helpers" - right now just the enter_grain binary and its sha1
Source: "..\helpers\*"; DestDir: "{app}\helpers"; Flags: recursesubdirs

; ssh binary + required DLLs, so that `vagrant ssh` can work
Source: "vendor\msysgit\ssh.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "vendor\msysgit\msys-crypto-1.0.0.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "vendor\msysgit\msys-minires.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "vendor\msysgit\msys-1.0.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "vendor\msysgit\msys-z.dll"; DestDir: "{app}"; Flags: ignoreversion

; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Code]
const
	ModPathName = 'modifypath';
	ModPathType = 'user';

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

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

#define MyAppName "vagrant-spk"
#define MyAppVersion "2015-07-24"
#define MyAppPublisher "Sandstorm Development Group, Inc."
#define MyAppURL "https://docs.sandstorm.io/"
#define MyAppExeName "vagrant-spk.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{1EAFBDE2-157F-46F4-B5AB-6858FD3A0D8A}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=dist\innosetup
OutputBaseFilename=vagrant-spk-setup
Compression=lzma
SolidCompression=yes
ChangesEnvironment=true

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

[Tasks]
Name: modifypath; Description: &Add application directory to your environmental path

[Files]
; vagrant-spk itself
Source: "dist\vagrant-spk.exe"; DestDir: "{app}"; Flags: ignoreversion

; vagrant-spk platform stacks
Source: "..\stacks\*"; DestDir: "{app}\stacks"; Flags: recursesubdirs

; "helpers" - right now just the enter_grain binary and its sha1
Source: "..\helpers\*"; DestDir: "{app}\helpers"; Flags: recursesubdirs

; ssh binary + required DLLs, so that `vagrant ssh` can work
Source: "vendor\msysgit\ssh.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "vendor\msysgit\msys-crypto-1.0.0.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "vendor\msysgit\msys-minires.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "vendor\msysgit\msys-1.0.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "vendor\msysgit\msys-z.dll"; DestDir: "{app}"; Flags: ignoreversion

; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Code]
const
	ModPathName = 'modifypath';
	ModPathType = 'user';

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


Removed extra character.

Removed extra character.

#define MyAppName "KA Lite"
#define MyAppPublisher "Foundation for Learning Equality"
#define MyAppURL "http://learningequality.org/"
#define MyAppExeName "KA Lite.exe"

#define getKALiteVersion() \
    Local[1] = GetEnv("KALITE_BUILD_VERSION")

#define TargetVersion = getKALiteVersion();

#expr DeleteFile(SourcePath+"\version.temp")

[Setup]
AppId={#MyAppName}-{#MyAppPublisher}
AppName={#MyAppName}
AppVersion={#TargetVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
LicenseFile=..\ka-lite\LICENSE
OutputDir=..\
OutputBaseFilename=KALiteSetup-{#TargetVersion}
SetupIconFile=logo48.ico
Compression=lzma
SolidCompression=yes
PrivilegesRequired=admin
UsePreviousAppDir=yes
ChangesEnvironment=yes

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

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

[Files]
Source: "..\ka_lite_static-*.whl"; DestDir: "{app}\ka-lite"
Source: "..\en.zip"; DestDir: "{app}"
Source: "..\scripts\*.bat"; DestDir: "{app}\ka-lite\scripts\"
Source: "..\gui-packed\KA Lite.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\gui-packed\guitools.vbs"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\gui-packed\images\logo48.ico"; DestDir: "{app}\images"; Flags: ignoreversion
Source: "..\python-setup\*"; DestDir: "{app}\python-setup"; Flags: ignoreversion

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\images\logo48.ico"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon ; IconFilename: "{app}\images\logo48.ico"

[Dirs]
Name: "{app}\"; Permissions: everyone-readexec

[InstallDelete]
Type: Files; Name: "{app}\*"

[UninstallDelete]
Type: filesandordirs; Name: "{app}\ka-lite*"
Type: files; Name: "{userstartup}\KA Lite.lnk"
Type: files; Name: "{app}\CONFIG.dat"

[UninstallRun]
Filename: {app}\ka-lite\scripts\uninstall-ka-lite-static.bat; Parameters: "";

[Code]
function GetPreviousVersion : String; Forward;

var
  installFlag : boolean;
  startupFlag : string;
  ServerInformationPage : TInputQueryWizardPage;
  StartupOptionsPage : TOutputMsgWizardPage;
  isUpgrade : boolean;
  stopServerCode: integer;
  removeOldGuiTool: integer;
  uninstallError: integer;
  saveDatabaseTemp : integer;
  cleanOldKaliteFolder : integer;
  restoreDatabaseTemp : integer;
  forceCancel : boolean;

procedure InitializeWizard;
begin
    isUpgrade := False;
    forceCancel := False;

    if WizardForm.PrevAppDir <> nil then
    begin
        ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C ka-lite\bin\windows\kalite.bat stop', WizardForm.PrevAppDir, SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C del winshortcut.vbs', WizardForm.PrevAppDir, SW_HIDE, ewWaitUntilTerminated, removeOldGuiTool);
    end;

    // Server data
    ServerInformationPage := CreateInputQueryPage(wpSelectDir,
    'Server Information', 'General data',
    'Please specify the server name and a description, then click Next. (you can leave blank both fields if you want to use the default server name or if you do not want to insert a description)');
    ServerInformationPage.Add('Server name:', False);
    ServerInformationPage.Add('Server description:', False);

    StartupOptionsPage := CreateOutputMsgPage(ServerInformationPage.ID,
        'Startup options', 'Please read the following important information.',
        'In prior versions of KA Lite you could choose to start the server or task-tray program automatically during installation.' #13#13
        'This is no longer possible during installation, but you can set these options using the task-tray program after installation finishes.' #13#13
        'To enable or disable these features, start the task-tray program and right click on it to find a list of options.'
    )
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  if forceCancel = True then
  begin
    Confirm := False;
  end;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
    result := False;
    if isUpgrade = True then
    begin
        if PageID = ServerInformationPage.ID then
        begin
            result := True;
        end;
        if PageID = wpSelectDir then
        begin
            result := True;
        end;
    end;
end;

procedure RemoveOldInstallation(targetPath : String);
begin
    WizardForm.Hide;
    if Not Exec(ExpandConstant('{cmd}'),'/C ( dir /b "unins***.exe" | findstr /r "unins[0-9][0-9][0-9].exe" ) > tempu & ( for /f "delims=" %A in ( tempu ) do call %A /SILENT /SUPPRESSMSGBOXES ) & del tempu', targetPath, SW_HIDE, ewWaitUntilTerminated, uninstallError) then
    begin
        Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database & xcopy /y /s ka-lite\kalite\database\data.sqlite '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database', targetPath, SW_HIDE, ewWaitUntilTerminated, saveDatabaseTemp);
        Exec(ExpandConstant('{cmd}'),'/C cd .. & del /q "'+targetPath+'\*" & for /d %x in ( "'+targetPath+'\*" ) do @rd /s /q "%x"', targetPath, SW_HIDE, ewWaitUntilTerminated, cleanOldKaliteFolder);
        Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\kalite\database & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\kalite\database\data.sqlite ka-lite\kalite\database', targetPath, SW_HIDE, ewWaitUntilTerminated, restoreDatabaseTemp);
    end;
    WizardForm.Show;
end;

{ Get the previous version number by checking the uninstall key registry values. }
{ IS writes quite a bit of information to the registry by default: https://github.com/jrsoftware/issrc/blob/5203240a7de9b83c5432bee0b5b09d467869a02b/Projects/Install.pas#L434 }
function GetPreviousVersion : String;
var
    subkey : String;
begin
    subkey := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\KA Lite-Foundation for Learning Equality_is1';
    result := '';
    { 32-bit programs have a virtualized registry on 64-bit windows. So check all possible root keys. }
    if Not RegQueryStringValue(HKLM, subkey, 'DisplayVersion', result) then
    begin
        if Not RegQueryStringValue(HKCU, subkey, 'DisplayVersion', result) then
        begin
            if IsWin64 then
            begin
                if Not RegQueryStringValue(HKLM64, subkey, 'DisplayVersion', result) then
                begin
                    if Not RegQueryStringValue(HKCU64, subkey, 'DisplayVersion', result) then
                    begin
                        { Couldn't determine the previous version, so result is '' }
                    end;
                end;
            end;
        end;
    end;
end;

procedure ConfirmUpgradeDialog;
begin
    if MsgBox('We have detected an existing KA Lite installation; would you like to upgrade?', mbInformation,  MB_YESNO or MB_DEFBUTTON1) = IDYES then
    begin
        isUpgrade := True;
    end
    else if MsgBox('Installing fresh will delete all of your existing data; is this what you really want to do?', mbInformation,  MB_YESNO or MB_DEFBUTTON2) = IDYES then
    begin
        isUpgrade := False;
    end
    else
    begin
        isUpgrade := True;
    end;
end;

{ Copy files a la the gitmigrate management command, but use native windows executables instead. }
{ We assume the installing user is the main user of the app, so content goes into that user's .kalite dir}
procedure DoGitMigrate;
var
    retCodeContent, retCodeDB, retCode : integer;
begin
    MsgBox('Migrating old data to current user''s %USERPROFILE%\.kalite\ directory.', mbInformation, MB_OK);
    Exec(ExpandConstant('{cmd}'), '/S /C "mkdir "%USERPROFILE%\.kalite""', '', SW_SHOW, ewWaitUntilTerminated, retCode);
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + WizardForm.PrevAppDir + '\ka-lite\content" "%USERPROFILE%\.kalite\content\" /Y"', '', SW_SHOW, ewWaitUntilTerminated, retCodeContent);
    Exec(ExpandConstant('{cmd}'), '/S /C "xcopy "' + WizardForm.PrevAppDir + '\ka-lite\kalite\database" "%USERPROFILE%\.kalite\database\" /Y"', '', SW_SHOW, ewWaitUntilTerminated, retCodeDB);
    if (retCodeContent <> 0) or (retCodeDB <> 0) then
    begin
        MsgBox('Something went wrong! Unable to backup your data. Continuing installation.', mbError, MB_OK);
    end;
end;

{ In version 0.13.x or below, users who selected the "Run KA Lite at system startup" option ran KA Lite as the }
{ SYSTEM user. Starting in 0.16.0, it will be run as the current user. Consequently, data must be migrated from the }
{ SYSTEM user's profile to the new location. }
procedure MoveSystemKaliteData;
var
    systemKaliteDir: String;
    userKaliteDir: String;
    userKaliteDirBackup: String;
    resultCode: Integer;
begin
    systemKaliteDir := 'C:\Windows\System32\config\systemprofile\.kalite';
    if DirExists(systemKaliteDir) then
    begin
        if(MsgBox('You may need to migrate data from the SYSTEM user''s profile to the current user''s profile.' #13#13
                  'This is because of a change in the behavior of KA Lite using the "Run KA Lite at system startup" option.' #13
                  'If you use this option, we recommend clicking yes. Your data will be backed up.' #13#13
                  'Would you like to migrate data from the SYSTEM user''s profile to the current user''s profile?', mbConfirmation, MB_YESNO) = idYes) then
        begin
            userKaliteDir := ExpandConstant('{%USERPROFILE}\.kalite');
            userKaliteDirBackup := userKaliteDir + '.backup';
            if DirExists(userKaliteDir) then
            begin
                MsgBox(userKaliteDir + ' already exists, backing up to ' + userKaliteDirBackup, mbInformation, MB_OK);
                if not Exec(ExpandConstant('{cmd}'), '/C "xcopy  "' + userKaliteDir +'" "' + userKaliteDirBackup +'\" /Y /S"', '', SW_SHOW, ewWaitUntilTerminated, resultCode) then
                begin
                    MsgBox('Backup .kalite file copy fail.', mbInformation, MB_OK);
                end;
            end;
            if not Exec(ExpandConstant('{cmd}'), '/C "xcopy  "' + systemKaliteDir +'" "' + userKaliteDir +'\" /Y /S"', '', SW_SHOW, ewWaitUntilTerminated, resultCode) then
            begin
                MsgBox('System .kalite file copy fail.', mbInformation, MB_OK);
            end;
        end;
    end;
end;

procedure HandleUpgrade(targetPath : String);
var
    prevVerStr : String;
    retCode: Integer;
begin
    prevVerStr := GetPreviousVersion();
    if (CompareStr('{#TargetVersion}', prevVerStr) >= 0) and not (prevVerStr = '') then
    begin
        ConfirmUpgradeDialog;
        if Not isUpgrade then
        begin
            if Not DeleteFile(targetPath + '\ka-lite\kalite\database\data.sqlite') then
            begin
                MsgBox('Error' #13#13 'Failed to delete the old database as requested; aborting the install.', mbError, MB_OK);
                forceCancel := True;
                WizardForm.Close;
            end;
        end
        else
        begin
            { This is where version-specific migration stuff should happen. }

            if CompareStr(prevVerStr, '0.13.99') < 0 then
            begin
                if CompareStr('{#TargetVersion}', '0.14.0') >= 0 then
                begin
                    DoGitMigrate;
                end;
            end;

            { A special case where we'd like to remove a scheduled task, since it should now be run as current user }
            { instead of the SYSTEM user. }
            if CompareStr(prevVerStr, '0.15.99') < 0 then
            begin
                if CompareStr('{#TargetVersion}', '0.16.0') >= 0 then
                begin
                    Exec(ExpandConstant('{cmd}'),'/C "schtasks /delete /tn "KALite" /f"', '', SW_SHOW, ewWaitUntilTerminated, retCode);
                end;
            end;

            { Migrating from 0.14.x and 0.15.x to 0.16.x }
            if (CompareStr(prevVerStr, '0.14.0') >= 0) and (CompareStr(prevVerStr, '0.15.99') < 0) then
            begin
                if CompareStr('{#TargetVersion}', '0.16.0') >= 0 then
                begin
                    MoveSystemKaliteData;
                end;
            end;
        end;

        { forceCancel will be true if something went awry in DoGitMigrate... abort instead of trampling the user's data. }
        if Not forceCancel then
        begin
            RemoveOldInstallation(targetPath);
        end;
    end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
    result := True;

    if CurPageID = wpLicense then
    begin
        if WizardForm.PrevAppDir <> nil then
            HandleUpgrade(WizardForm.PrevAppDir);
    end;

    if CurPageID = wpSelectDir then
    begin
        { Unclear what the logic here is. This is only executed if HandleUpgrade was not previously run. }
        if Not isUpgrade then
            HandleUpgrade(ExpandConstant('{app}'));
    end;
end;

{REF: http://stackoverflow.com/questions/4438506/exit-from-inno-setup-instalation-from-code}
procedure ExitProcess(uExitCode: Integer);
  external 'ExitProcess@kernel32.dll stdcall';

procedure HandlePythonSetup;
var
    installPythonErrorCode : Integer;
begin
    if(MsgBox('KA Lite requires Python to be installed on your system.' + #13#10 + 'This wizard will proceed to install Python 2.7.12, and then continue with  KA Lite installation.' + #13#10 + #13#10 + 'Click OK to continue.', mbConfirmation, MB_OKCANCEL) = idCancel) then
        if(MsgBox('Are you sure you want to cancel the installation of Python 2.7.12?' + #13#10 + 'If you select Yes, this installer will close and KA Lite will not be installed on your system.', mbConfirmation, MB_YESNO) = idYes) then
          begin
            forceCancel := True;
            ExitProcess(1);
          end
        else begin
             HandlePythonSetup();
             exit;
        end
    else
        ExtractTemporaryFile('python-2.7.12.msi');
        ExtractTemporaryFile('python-2.7.12.amd64.msi');
        ExtractTemporaryFile('python-exe.bat');
        ShellExec('open', ExpandConstant('{tmp}')+'\python-exe.bat', '', '', SW_HIDE, ewWaitUntilTerminated, installPythonErrorCode);
end;

{ Used in GetPipPath below }
const
    DEFAULT_PIP_PATH = '\Python27\Scripts\pip.exe';
    DEFAULT_PYTHON_PATH = '\Python27\python.exe';

{ Returns the path of pip.exe on the system. }
{ Tries several different locations before prompting user. }
function GetPipPath: string;
var
    kalitePythonEnv: string;
    path : string;
    i : integer;
begin
    kalitePythonEnv := GetEnv('KALITE_PYTHON');
    Log(kalitePythonEnv)
    if kalitePythonEnv = '' then
      begin
        path := DEFAULT_PIP_PATH;
        if FileExists(path) then
        begin
            Result := path;
            exit;
        end
      end
    else
      begin
        if FileExists(kalitePythonEnv) then
            Result := ExtractFileDir(kalitePythonEnv) + '\Scripts\pip.exe';
            exit;
      end

    MsgBox('Could not find pip.exe. Please select the location of pip.exe to continue installation.', mbInformation, MB_OK);
    if GetOpenFileName('Please select pip.exe', path, '', 'All files (*.*)|*.*', 'exe') then
    begin
        Result := path;
    end
    else begin
        MsgBox('Fatal error'#13#13'Please install pip and try again.', mbError, MB_OK);
        forceCancel := True;
        Result := '';
    end;
end;

procedure HandlePipSetup;
var
    PipCommand: string;
    PipPath: string;
    pythonPath: string;
    checkEnc: string;
    ErrorCode: integer;

begin
    PipPath := GetPipPath;
    if PipPath = '' then
        exit;
    PipCommand := 'install "' + ExpandConstant('{app}') + '\ka-lite\ka_lite_static-' + '{#TargetVersion}' + '-py2-none-any' + '.whl"';

    MsgBox('Setup will now install kalite source files to your Python site-packages.', mbInformation, MB_OK);
    if not Exec(PipPath, PipCommand, '', SW_SHOW, ewWaitUntilTerminated, ErrorCode) then
    begin
      MsgBox('Critical error.' #13#13 'Dependencies have failed to install. Error Number: ' + IntToStr(ErrorCode), mbInformation, MB_OK);
      forceCancel := True;
      WizardForm.Close;
    end

    { Must set this environment variable so the systray executable knows where to find the installed kalite.bat script}
    { Should by in the same directory as pip.exe, e.g. 'C:\Python27\Scripts' }
    RegWriteStringValue(
        HKLM,
        'System\CurrentControlSet\Control\Session Manager\Environment',
        'KALITE_SCRIPT_DIR',
        ExtractFileDir(PipPath)
    );
    pythonPath := ExtractFileDir(ExtractFileDir(PipPath)) + '\python.exe';
    FileCopy(ExpandConstant('{app}') + '\ka-lite\scripts\kalite.bat', ExtractFileDir(PipPath) + '\kalite.bat', False);
    RegWriteStringValue(
        HKLM,
        'System\CurrentControlSet\Control\Session Manager\Environment',
        'KALITE_PYTHON',
        pythonPath
    );
end;

function InitializeSetup(): Boolean;
var
  PythonVersionCodeCheck: integer;
  killErrorCode: integer;
begin
    installFlag:=true;
    Result := true;
    startupFlag:='';

    ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, killErrorCode)
    ShellExec('open', 'tskill.exe', ' "KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, killErrorCode);

    RegDeleteValue(HKCU, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', ExpandConstant('{#MyAppName}'));

    if ShellExec('open', 'python.exe','-c "import sys; (sys.version_info >= (2, 7, 11,) and sys.version_info < (3,) and sys.exit(0)) or sys.exit(1)"', '', SW_HIDE, ewWaitUntilTerminated, PythonVersionCodeCheck) then
    begin
        if PythonVersionCodeCheck = 1 then
        begin
            HandlePythonSetup();
        end;
    end
    else
    begin
        HandlePythonSetup();
    end;
end;

function InitializeUninstall(): Boolean;
var
ErrorCode: Integer;
begin
  ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  ShellExec('open', ExpandConstant('{app}') + '\ka-lite\bin\windows\kalite.bat stop', '', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
  result := True;
end;

procedure DoSetup;
var
    retCode: integer;
begin
    { Used to have more responsibility, but we delegated those to the app itself! }
    { Unpacks the English content pack. }
    Exec(ExpandConstant('{cmd}'), '/S /C "' + ExpandConstant('"{reg:HKLM\System\CurrentControlSet\Control\Session Manager\Environment,KALITE_SCRIPT_DIR}\kalite.bat"') + ' manage retrievecontentpack local en en.zip --foreground"', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, retCode);
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  moveKaliteFolderTemp: integer;
  moveContentFolderTemp: integer;
  cleanKaliteFolder: integer;
  restoreKaliteFolder: integer;
  restoreContentFolder: integer;
  informationBoxFlagged: boolean;

begin
    if CurStep = ssInstall then
    begin
        informationBoxFlagged :=False;

        ShellExec('open', 'taskkill.exe', '/F /T /im "KA Lite.exe"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        ShellExec('open', 'tskill.exe', '"KA Lite"', '', SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C ka-lite\bin\windows\kalite.bat stop', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, stopServerCode);
        Exec(ExpandConstant('{cmd}'),'/C del winshortcut.vbs', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, removeOldGuiTool);

        if DirExists(ExpandConstant('{app}') + '\kalite') then
        begin
            MsgBox('KA Lite old data structure' #13#13 'Setup detected that you have the old file structure. Setup will now move data to update the structure. Please be patient; this may take some time.', mbInformation, MB_OK);
            informationBoxFlagged :=True;
            Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\kalite & xcopy /y /s kalite\* '+ExpandConstant('{tmp}')+'\ka-lite\kalite', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, moveKaliteFolderTemp);
        end;

        if DirExists(ExpandConstant('{app}') + '\content') then
        begin
            if Not informationBoxFlagged then
            begin
                MsgBox('KA Lite old data structure' #13#13 'Setup detected that you have the old file structure. Setup will now move data to update the structure. Please be patient; this may take some time.', mbInformation, MB_OK);
                informationBoxFlagged :=True;
            end;
            Exec(ExpandConstant('{cmd}'),'/C mkdir '+ExpandConstant('{tmp}')+'\ka-lite\content & xcopy /y /s content\* '+ExpandConstant('{tmp}')+'\ka-lite\content', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, moveContentFolderTemp);
        end;

        if informationBoxFlagged then
        begin
            Exec(ExpandConstant('{cmd}'),'/C cd .. & del /q "'+ExpandConstant('{app}')+'\*" & for /d %x in ( "'+ExpandConstant('{app}')+'\*" ) do @rd /s /q "%x"', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, cleanKaliteFolder);

            if DirExists(ExpandConstant('{tmp}')+'\ka-lite\kalite') then
            begin
                Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\kalite & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\kalite\* ka-lite\kalite', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, restoreKaliteFolder);
            end;

            if DirExists(ExpandConstant('{tmp}')+'\ka-lite\content') then
            begin
                Exec(ExpandConstant('{cmd}'),'/C mkdir ka-lite\content & xcopy /y /s '+ExpandConstant('{tmp}')+'\ka-lite\content\* ka-lite\content', ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, restoreContentFolder);
            end;
        end;

    end;

    if CurStep = ssPostInstall then
    begin
        if installFlag then
        begin
            HandlePipSetup();
            begin
                DoSetup;
            end;
        end;
    end;
end;

{ Called just prior to uninstall finishing. }
{ Clean up things we did during uninstall: }
{ * Remove environment variable KALITE_SCRIPT_DIR, which is set starting in version 0.16.x }
{ * Previously (versions 0.13.x to 0.15.x) KALITE_ROOT_DATA_PATH was set -- it should be unset by the respective }
{   uninstallers of those versions }
procedure DeinitializeUninstall();
begin
    RegDeleteValue(
        HKLM,
        'System\CurrentControlSet\Control\Session Manager\Environment',
        'KALITE_SCRIPT_DIR'
    )
end;


Fixed bug 1189532.

Fixed bug 1189532.

; -- xins.iss --
;
; $Id$

[Setup]
AppName=XINS
AppVerName=XINS version 1.2.0-beta2
DefaultDirName={pf}\xins-1.2.0-beta2
VersionInfoVersion=1.2.0
OutputDir=c:\projects
OutputBaseFilename=xins-1.2.0-beta2
SetupIconFile=xins.ico
WizardImageFile=bigxinslogo.bmp
WizardSmallImageFile=smallxinslogo.bmp
UninstallDisplayIcon={app}\xins.ico
DefaultGroupName=Xins
DisableProgramGroupPage=yes
LicenseFile=c:\projects\xins-1.2.0-beta2\COPYRIGHT
InfoBeforeFile=xins-info1.txt

[Files]
Source: "c:\projects\xins-1.2.0-beta2\*"; DestDir: "{app}"; Flags: recursesubdirs
Source: "xins.ico"; DestDir: "{app}"

[Icons]

[Registry]
Root: HKCU; Subkey: "Environment"; ValueType: string; ValueName: "XINS_HOME"; ValueData: "{code:AddQuotes|{app}}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "PATH"; ValueData: "{code:GetNewPath|{app}\bin}"; Flags: preservestringtype
;"{app}\bin;{reg:HKCU\Environment,PATH|""}"; Flags: preservestringtype

[Run]
Filename: "{app}\README.html"; Description: "View the README file."; Flags: postinstall nowait shellexec skipifsilent
Filename: "cmd"; Parameters: "/c ""set XINS_HOME=""{app}""&cd ""{app}\demo\xins-project""&""{app}\bin\xins.bat"" all-myproject&""{app}\bin\xins.bat"" -Dorg.xins.server.config=..\xins.properties  run-myproject"""; Description: "Compile and run demo."; Flags: postinstall nowait skipifsilent unchecked

[UninstallDelete]
Type: filesandordirs; Name: "{app}\demo\xins-project\build\*"
Type: dirifempty; Name: "{app}\demo\xins-project\build"
Type: dirifempty; Name: "{app}\demo\xins-project"
Type: dirifempty; Name: "{app}\demo"
Type: dirifempty; Name: "{app}"

[Code]
var
  CurrentPath: String;
  UsersPath: String;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
  { Do no show the InfoBeforeFile page if the environment variables are correct. }
  if (PageID = wpInfoBefore) and (not (GetEnv('ANT_HOME') = '')) and (not (GetEnv('JAVA_HOME') = '')) then begin
    Result := True;
  end else begin
    Result := False;
  end;
end;

function GetNewPath(XPath: String): String;
begin
  CurrentPath := ExpandConstant('{reg:HKCU\Environment,PATH}');
  UsersPath := ExpandConstant('{reg:HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment,PATH}');
  if (Length(CurrentPath) = 0) then begin
    Result := XPath;
  end else if ((Pos(XPath, CurrentPath) = 0) and (Pos(XPath, UsersPath) = 0)) then begin
    Result := XPath + ';' + CurrentPath;
  end else begin
    Result := CurrentPath;
  end;
end;

; -- xins.iss --
;
; $Id$

[Setup]
AppName=XINS
AppVerName=XINS version 1.2.0-beta2
DefaultDirName={pf}\xins-1.2.0-beta2
VersionInfoVersion=1.2.0
OutputDir=c:\projects
OutputBaseFilename=xins-1.2.0-beta2
SetupIconFile=xins.ico
WizardImageFile=bigxinslogo.bmp
WizardSmallImageFile=smallxinslogo.bmp
UninstallDisplayIcon={app}\xins.ico
DefaultGroupName=Xins
DisableProgramGroupPage=yes
LicenseFile=c:\projects\xins-1.2.0-beta2\COPYRIGHT
InfoBeforeFile=xins-info1.txt

[Files]
Source: "c:\projects\xins-1.2.0-beta2\*"; DestDir: "{app}"; Flags: recursesubdirs
Source: "xins.ico"; DestDir: "{app}"

[Icons]

[Registry]
Root: HKCU; Subkey: "Environment"; ValueType: string; ValueName: "XINS_HOME"; ValueData: """{app}"""; Flags: uninsdeletevalue
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "PATH"; ValueData: "{app}\bin;{reg:HKCU\Environment,PATH|""}"; Flags: preservestringtype

[Run]
Filename: "{app}\README.html"; Description: "View the README file."; Flags: postinstall nowait shellexec skipifsilent
Filename: "cmd"; Parameters: "/c ""set XINS_HOME=""{app}""&cd ""{app}\demo\xins-project""&""{app}\bin\xins.bat"" all-myproject&""{app}\bin\xins.bat"" -Dorg.xins.server.config=..\xins.properties  run-myproject"""; Description: "Compile and run demo."; Flags: postinstall nowait skipifsilent unchecked

[UninstallDelete]
Type: filesandordirs; Name: "{app}\demo\xins-project\build\*"
Type: dirifempty; Name: "{app}\demo\xins-project\build"
Type: dirifempty; Name: "{app}\demo\xins-project"
Type: dirifempty; Name: "{app}\demo"
Type: dirifempty; Name: "{app}"

[Code]
function ShouldSkipPage(PageID: Integer): Boolean;
begin
  { Do no show the InfoBeforeFile page if the environment variables are correct. }
  if (PageID = wpInfoBefore) and (not (GetEnv('ANT_HOME') = '')) and (not (GetEnv('JAVA_HOME') = '')) then begin
    Result := True;
  end else begin
    Result := False;
  end;
end;


Change install command to npx @iobroker/install

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

#define MyAppName "ioBroker automation platform"
#define MyAppShortName "ioBroker"
#define MyAppLCShortName "iobroker"
#define MyAppVersion "@@version"
#define MyAppPublisher "ioBroker GmbH"
#define MyAppURL "https://www.ioBroker.net/"
#define MyAppIcon "ioBroker.ico"

[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={{97DA02F5-2E8C-4B96-BB42-61ED2BBF34DF}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={drive:{commonpf}}\ioBroker
;DisableDirPage=yes
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=..\..\delivery
OutputBaseFilename={#MyAppShortName}Installer.{#MyAppVersion}
SetupIconFile={#MyAppIcon}
Compression=lzma
SolidCompression=yes
UsePreviousAppDir=yes
ArchitecturesInstallIn64BitMode=x64
UninstallDisplayIcon={app}\{#MyAppIcon}
CloseApplications=yes
MissingRunOnceIdsWarning=no

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "german";  MessagesFile: "compiler:Languages\German.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

; enable scripting to force admin mode
[Registry]
Root: HKLM; Subkey: "Software\Microsoft\Windows Script Host\Settings"; ValueType: dword; ValueName: "Enabled"; ValueData: "00000001"

[Files]
Source: "nodejs\node.msi"; DestDir: "{app}"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode
Source: "nodejs\node-x64.msi"; DestDir: "{app}"; DestName: "node.msi"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode
Source: "{#MyAppIcon}"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppShortName} Settings"; Filename: "http://localhost:8081"; IconFilename: "{app}\{#MyAppIcon}"
Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}"; IconFilename: {app}\{#MyAppIcon};
Name: "{group}\{#MyAppShortName} Uninstall"; Filename: "{uninstallexe}"; IconFilename: {app}\{#MyAppIcon};
Name: "{group}\Start {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "start"
Name: "{group}\Stop {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "stop"
Name: "{group}\Restart {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "restart"

[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
  ResultCode: integer;
begin
  Result := '';
  if FileExists(ExpandConstant('{app}\serviceIoBroker.bat')) then begin
     Exec(ExpandConstant('{app}\serviceIoBroker.bat'), 'stop', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;

function FileReplaceString(const FileName, SearchString, ReplaceString: string):boolean;
var
  MyFile : TStrings;
  MyText : string;
begin
  MyFile := TStringList.Create;

  try
    result := true;

    try
      MyFile.LoadFromFile(FileName);
      MyText := MyFile.Text;

      if StringChangeEx(MyText, SearchString, ReplaceString, True) > 0 then //Only save if text has been changed.
      begin;
        MyFile.Text := MyText;
        MyFile.SaveToFile(FileName);
      end;
    except
      result := false;
    end;
  finally
    MyFile.Free;
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  fileName : string;
  lang : string;
begin
  if  CurStep=ssPostInstall then
    begin
      lang := ActiveLanguage();
      if lang = 'russian' then begin
        lang := 'ru';
      end
      else begin
          if lang = 'german' then begin
            lang := 'de';
          end
          else begin
            lang := '';
          end;
      end;
      if lang <> '' then begin
          fileName := ExpandConstant('{app}\settings-dist.json');
          //FileReplaceString(fileName, '"language": "en"', '"language": "' + lang + '"');
      end;
    end;
end;

function NodeJsNeedsInstall():boolean;
var
  ResultCode: integer;
begin

  result := true;
  if IsWin64 then begin
      result := not FileExists(ExpandConstant('{commonpf64}\nodejs\node.exe'));

      if result then begin
        result := not FileExists(ExpandConstant('{commonpf32}\nodejs\node.exe'));
      end;
  end;

  if result then begin
    result := not FileExists(ExpandConstant('{commonpf}\nodejs\node.exe'));
  end;

  if not DirExists(ExpandConstant('{userappdata}\npm')) then begin
     Exec(ExpandConstant('mkdir'), ExpandConstant('{userappdata}\npm'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
  if not DirExists(ExpandConstant('{userappdata}\npm-cache')) then begin
     Exec(ExpandConstant('mkdir'), ExpandConstant('{userappdata}\npm-cache'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;

function NodeJsPath(Param: String):String;
begin
  result := '';

  if DirExists(ExpandConstant('{commonpf}\nodejs')) then begin
    result := ExpandConstant('{commonpf}\nodejs');
  end;

  if IsWin64 then begin
      if DirExists(ExpandConstant('{commonpf32}\nodejs')) then begin
        result := ExpandConstant('{commonpf32}\nodejs');
      end;

      if DirExists(ExpandConstant('{commonpf64}\nodejs')) then begin
        result := ExpandConstant('{commonpf64}\nodejs');
      end;
  end;
end;

function GetAdminPageText(Param: String):String;
begin
  result := 'Open settings page';

  if ActiveLanguage() = 'german' then begin
    result := 'Einstellungen aufmachen';
  end;

  if ActiveLanguage() = 'russian' then begin
      result := 'Открыть настройки';
  end;
end;

[Run]
; postinstall launch
Filename: "msiexec.exe"; Parameters: "/i ""{app}\node.msi"" /passive"; Check: NodeJsNeedsInstall
;
;Filename: "{code:NodeJsPath}\npm.cmd"; Parameters: "install iobroker --prefix ""{app}""";
;Filename: "{code:NodeJsPath}\npm.cmd"; Parameters: "install --production"; WorkingDir: "{app}";
;Filename: "{app}\serviceIoBroker.bat"; Parameters: "start"; WorkingDir: "{app}";
;
;Filename: "{code:NodeJsPath}\npx.cmd"; Parameters: "github:iobroker/iobroker#windows-installer"; WorkingDir: "{app}";
Filename: "{code:NodeJsPath}\npx.cmd"; Parameters: "npx @iobroker/install"; WorkingDir: "{app}";
;
; Add Firewall Rules
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""Node In"" program=""{code:NodeJsPath}\node.exe"" dir=in action=allow enable=yes"; Flags: runhidden;
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""Node Out"" program=""{code:NodeJsPath}\node.exe"" dir=out action=allow enable=yes"; Flags: runhidden;
Filename: http://localhost:8081/; Description: "{code:GetAdminPageText}"; Flags: postinstall shellexec

[UninstallDelete]
Type: filesandordirs; Name: "{app}\daemon"
Type: filesandordirs; Name: "{app}\node_modules"
Type: filesandordirs; Name: "{app}\install"
Type: filesandordirs; Name: "{app}\iobroker-data"
Type: filesandordirs; Name: "{app}\log"
Type: filesandordirs; Name: "{app}\*.js"
Type: filesandordirs; Name: "{app}\*.md"
Type: filesandordirs; Name: "{app}\*.cmd"
Type: filesandordirs; Name: "{app}\*.bat"
Type: filesandordirs; Name: "{app}\*.json"
Type: filesandordirs; Name: "{app}\*.ps1"
Type: filesandordirs; Name: "{app}\*.sh"
Type: filesandordirs; Name: "{app}\LICENSE"
Type: filesandordirs; Name: "{app}\semver"

[UninstallRun]
; Removes System Service
Filename: "{code:NodeJsPath}\node.exe"; Parameters: """{app}\uninstall.js"""; Flags: runhidden;
;Filename: "{sys}\del"; Parameters: "/Q /S ""{app}\daemon""";
;Filename: "{sys}\rmdir"; Parameters: "/Q /S ""{app}\daemon""";
;Filename: "{sys}\del"; Parameters: "/Q /S ""{app}\node_modules""";
;Filename: "{sys}\rmdir"; Parameters: "/Q /S ""{app}\node_modules""";
; Remove Firewall Rules
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Node In"" program=""{code:NodeJsPath}\node.exe"""; Flags: runhidden;
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Node Out"" program=""{code:NodeJsPath}\node.exe"""; Flags: runhidden;
; Remove all leftovers

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

#define MyAppName "ioBroker automation platform"
#define MyAppShortName "ioBroker"
#define MyAppLCShortName "iobroker"
#define MyAppVersion "@@version"
#define MyAppPublisher "ioBroker GmbH"
#define MyAppURL "https://www.ioBroker.net/"
#define MyAppIcon "ioBroker.ico"

[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={{97DA02F5-2E8C-4B96-BB42-61ED2BBF34DF}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={drive:{commonpf}}\ioBroker
;DisableDirPage=yes
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=..\..\delivery
OutputBaseFilename={#MyAppShortName}Installer.{#MyAppVersion}
SetupIconFile={#MyAppIcon}
Compression=lzma
SolidCompression=yes
UsePreviousAppDir=yes
ArchitecturesInstallIn64BitMode=x64
UninstallDisplayIcon={app}\{#MyAppIcon}
CloseApplications=yes
MissingRunOnceIdsWarning=no

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "german";  MessagesFile: "compiler:Languages\German.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

; enable scripting to force admin mode
[Registry]
Root: HKLM; Subkey: "Software\Microsoft\Windows Script Host\Settings"; ValueType: dword; ValueName: "Enabled"; ValueData: "00000001"

[Files]
Source: "nodejs\node.msi"; DestDir: "{app}"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode
Source: "nodejs\node-x64.msi"; DestDir: "{app}"; DestName: "node.msi"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode
Source: "{#MyAppIcon}"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppShortName} Settings"; Filename: "http://localhost:8081"; IconFilename: "{app}\{#MyAppIcon}"
Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}"; IconFilename: {app}\{#MyAppIcon};
Name: "{group}\{#MyAppShortName} Uninstall"; Filename: "{uninstallexe}"; IconFilename: {app}\{#MyAppIcon};
Name: "{group}\Start {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "start"
Name: "{group}\Stop {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "stop"
Name: "{group}\Restart {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "restart"

[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
  ResultCode: integer;
begin
  Result := '';
  if FileExists(ExpandConstant('{app}\serviceIoBroker.bat')) then begin
     Exec(ExpandConstant('{app}\serviceIoBroker.bat'), 'stop', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;

function FileReplaceString(const FileName, SearchString, ReplaceString: string):boolean;
var
  MyFile : TStrings;
  MyText : string;
begin
  MyFile := TStringList.Create;

  try
    result := true;

    try
      MyFile.LoadFromFile(FileName);
      MyText := MyFile.Text;

      if StringChangeEx(MyText, SearchString, ReplaceString, True) > 0 then //Only save if text has been changed.
      begin;
        MyFile.Text := MyText;
        MyFile.SaveToFile(FileName);
      end;
    except
      result := false;
    end;
  finally
    MyFile.Free;
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  fileName : string;
  lang : string;
begin
  if  CurStep=ssPostInstall then
    begin
      lang := ActiveLanguage();
      if lang = 'russian' then begin
        lang := 'ru';
      end
      else begin
          if lang = 'german' then begin
            lang := 'de';
          end
          else begin
            lang := '';
          end;
      end;
      if lang <> '' then begin
          fileName := ExpandConstant('{app}\settings-dist.json');
          //FileReplaceString(fileName, '"language": "en"', '"language": "' + lang + '"');
      end;
    end;
end;

function NodeJsNeedsInstall():boolean;
var
  ResultCode: integer;
begin

  result := true;
  if IsWin64 then begin
      result := not FileExists(ExpandConstant('{commonpf64}\nodejs\node.exe'));

      if result then begin
        result := not FileExists(ExpandConstant('{commonpf32}\nodejs\node.exe'));
      end;
  end;

  if result then begin
    result := not FileExists(ExpandConstant('{commonpf}\nodejs\node.exe'));
  end;

  if not DirExists(ExpandConstant('{userappdata}\npm')) then begin
     Exec(ExpandConstant('mkdir'), ExpandConstant('{userappdata}\npm'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
  if not DirExists(ExpandConstant('{userappdata}\npm-cache')) then begin
     Exec(ExpandConstant('mkdir'), ExpandConstant('{userappdata}\npm-cache'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;

function NodeJsPath(Param: String):String;
begin
  result := '';

  if DirExists(ExpandConstant('{commonpf}\nodejs')) then begin
    result := ExpandConstant('{commonpf}\nodejs');
  end;

  if IsWin64 then begin
      if DirExists(ExpandConstant('{commonpf32}\nodejs')) then begin
        result := ExpandConstant('{commonpf32}\nodejs');
      end;

      if DirExists(ExpandConstant('{commonpf64}\nodejs')) then begin
        result := ExpandConstant('{commonpf64}\nodejs');
      end;
  end;
end;

function GetAdminPageText(Param: String):String;
begin
  result := 'Open settings page';

  if ActiveLanguage() = 'german' then begin
    result := 'Einstellungen aufmachen';
  end;

  if ActiveLanguage() = 'russian' then begin
      result := 'Открыть настройки';
  end;
end;

[Run]
; postinstall launch
Filename: "msiexec.exe"; Parameters: "/i ""{app}\node.msi"" /passive"; Check: NodeJsNeedsInstall
;
;Filename: "{code:NodeJsPath}\npm.cmd"; Parameters: "install iobroker --prefix ""{app}""";
;Filename: "{code:NodeJsPath}\npm.cmd"; Parameters: "install --production"; WorkingDir: "{app}";
;Filename: "{app}\serviceIoBroker.bat"; Parameters: "start"; WorkingDir: "{app}";
;
;Filename: "{code:NodeJsPath}\npx.cmd"; Parameters: "github:iobroker/iobroker#windows-installer"; WorkingDir: "{app}";
Filename: "{code:NodeJsPath}\npx.cmd"; Parameters: "iobroker"; WorkingDir: "{app}";
;
; Add Firewall Rules
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""Node In"" program=""{code:NodeJsPath}\node.exe"" dir=in action=allow enable=yes"; Flags: runhidden;
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""Node Out"" program=""{code:NodeJsPath}\node.exe"" dir=out action=allow enable=yes"; Flags: runhidden;
Filename: http://localhost:8081/; Description: "{code:GetAdminPageText}"; Flags: postinstall shellexec

[UninstallDelete]
Type: filesandordirs; Name: "{app}\daemon"
Type: filesandordirs; Name: "{app}\node_modules"
Type: filesandordirs; Name: "{app}\install"
Type: filesandordirs; Name: "{app}\iobroker-data"
Type: filesandordirs; Name: "{app}\log"
Type: filesandordirs; Name: "{app}\*.js"
Type: filesandordirs; Name: "{app}\*.md"
Type: filesandordirs; Name: "{app}\*.cmd"
Type: filesandordirs; Name: "{app}\*.bat"
Type: filesandordirs; Name: "{app}\*.json"
Type: filesandordirs; Name: "{app}\*.ps1"
Type: filesandordirs; Name: "{app}\*.sh"
Type: filesandordirs; Name: "{app}\LICENSE"
Type: filesandordirs; Name: "{app}\semver"

[UninstallRun]
; Removes System Service
Filename: "{code:NodeJsPath}\node.exe"; Parameters: """{app}\uninstall.js"""; Flags: runhidden;
;Filename: "{sys}\del"; Parameters: "/Q /S ""{app}\daemon""";
;Filename: "{sys}\rmdir"; Parameters: "/Q /S ""{app}\daemon""";
;Filename: "{sys}\del"; Parameters: "/Q /S ""{app}\node_modules""";
;Filename: "{sys}\rmdir"; Parameters: "/Q /S ""{app}\node_modules""";
; Remove Firewall Rules
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Node In"" program=""{code:NodeJsPath}\node.exe"""; Flags: runhidden;
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Node Out"" program=""{code:NodeJsPath}\node.exe"""; Flags: runhidden;
; Remove all leftovers


delete node

delete node

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

#define MyAppName "ioBroker automation platform"
#define MyAppShortName "ioBroker"
#define MyAppLCShortName "iobroker"
#define MyAppVersion "@@version"
#define MyAppPublisher "ioBroker.net"
#define MyAppURL "http://ioBroker.net/"
#define MyAppIcon "ioBroker.ico"

[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={{97DA02F5-2E8C-4B96-BB42-61ED2BBF34DF}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={drive:{commonpf}}\ioBroker
;DisableDirPage=yes
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=..\..\delivery
OutputBaseFilename={#MyAppShortName}Installer.{#MyAppVersion}
SetupIconFile={#MyAppIcon}
Compression=lzma
SolidCompression=yes
UsePreviousAppDir=yes
ArchitecturesInstallIn64BitMode=x64
UninstallDisplayIcon={app}\{#MyAppIcon}
CloseApplications=yes

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "german";  MessagesFile: "compiler:Languages\German.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

; enable scripting to force admin mode
[Registry]
Root: HKLM; Subkey: "Software\Microsoft\Windows Script Host\Settings"; ValueType: dword; ValueName: "Enabled"; ValueData: "00000001"

[Files]
Source: "nodejs\node.msi"; DestDir: "{app}"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode
Source: "nodejs\node-x64.msi"; DestDir: "{app}"; DestName: "node.msi"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode
;Source: "redis-v2.4.6\redis-2.4.6-setup-32-bit.exe"; DestDir: "{app}"; DestName: "redisSetup.exe"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode
;Source: "redis-v2.4.6\redis-2.4.6-setup-64-bit.exe"; DestDir: "{app}"; DestName: "redisSetup.exe"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode
;Source: "couchDB\couchDBsetup.exe"; DestDir: "{app}"; Flags: ignoreversion deleteafterinstall;
;Source: "*.js"; DestDir: "{app}"; Flags: ignoreversion
;Source: "install.bat"; DestDir: "{app}"; Flags: ignoreversion
;Source: "package.json"; DestDir: "{app}"; Flags: ignoreversion
;Source: "npm.cmd"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MyAppIcon}"; DestDir: "{app}"; Flags: ignoreversion
;Source: "..\.windows-ready\data\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
;Source: "node_modules\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppShortName} Settings"; Filename: "http://localhost:8081"; IconFilename: "{app}\{#MyAppIcon}"
Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}"; IconFilename: {app}\{#MyAppIcon};
Name: "{group}\{#MyAppShortName} Uninstall"; Filename: "{uninstallexe}"; IconFilename: {app}\{#MyAppIcon};
Name: "{group}\Start {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "start"
Name: "{group}\Stop {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "stop"
Name: "{group}\Restart {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "restart"

[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
  ResultCode: integer;
begin
  Result := '';
  if FileExists(ExpandConstant('{app}\serviceIoBroker.bat')) then begin
     Exec(ExpandConstant('{app}\serviceIoBroker.bat'), 'stop', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;

function FileReplaceString(const FileName, SearchString, ReplaceString: string):boolean;
var
  MyFile : TStrings;
  MyText : string;
begin
  MyFile := TStringList.Create;

  try
    result := true;

    try
      MyFile.LoadFromFile(FileName);
      MyText := MyFile.Text;

      if StringChangeEx(MyText, SearchString, ReplaceString, True) > 0 then //Only save if text has been changed.
      begin;
        MyFile.Text := MyText;
        MyFile.SaveToFile(FileName);
      end;
    except
      result := false;
    end;
  finally
    MyFile.Free;
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  fileName : string;
  lang : string;
begin
  if  CurStep=ssPostInstall then
    begin
      lang := ActiveLanguage();
      if lang = 'russian' then begin
        lang := 'ru';
      end
      else begin
          if lang = 'german' then begin
            lang := 'de';
          end
          else begin
            lang := '';
          end;
      end;
      if lang <> '' then begin
          fileName := ExpandConstant('{app}\settings-dist.json');
          //FileReplaceString(fileName, '"language": "en"', '"language": "' + lang + '"');
      end;
    end;
end;

function RedisNeedsInstall():boolean;
begin
   result := not FileExists(ExpandConstant('{commonpf}\Redis\redis-service.exe'));
end;

function CouchNeedsInstall():boolean;
begin
   result := not FileExists(ExpandConstant('{commonpf32}\Apache Software Foundation\CouchDB\Install.exe'));
end;

function NodeJsNeedsInstall():boolean;
var
  ResultCode: integer;
begin

  result := true;
  if IsWin64 then begin
      result := not FileExists(ExpandConstant('{commonpf64}\nodejs\node.exe'));

      if result then begin
        result := not FileExists(ExpandConstant('{commonpf32}\nodejs\node.exe'));
      end;
  end;

  if result then begin
    result := not FileExists(ExpandConstant('{commonpf}\nodejs\node.exe'));
  end;

  if not DirExists(ExpandConstant('{userappdata}\npm')) then begin
     Exec(ExpandConstant('mkdir'), ExpandConstant('{userappdata}\npm'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
  if not DirExists(ExpandConstant('{userappdata}\npm-cache')) then begin
     Exec(ExpandConstant('mkdir'), ExpandConstant('{userappdata}\npm-cache'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;

function NodeJsPath(Param: String):String;
begin
  result := '';

  if DirExists(ExpandConstant('{commonpf}\nodejs')) then begin
    result := ExpandConstant('{commonpf}\nodejs');
  end;

  if IsWin64 then begin
      if DirExists(ExpandConstant('{commonpf32}\nodejs')) then begin
        result := ExpandConstant('{commonpf32}\nodejs');
      end;

      if DirExists(ExpandConstant('{commonpf64}\nodejs')) then begin
        result := ExpandConstant('{commonpf64}\nodejs');
      end;
  end;
end;

function GetAdminPageText(Param: String):String;
begin
  result := 'Open settings page';

  if ActiveLanguage() = 'german' then begin
    result := 'Einstellungen aufmachen';
  end;

  if ActiveLanguage() = 'russian' then begin
      result := 'Открыть настройки';
  end;
end;

[Run]
; postinstall launch
Filename: "msiexec.exe"; Parameters: "/i ""{app}\node.msi"" /passive"; Check: NodeJsNeedsInstall
;
;Filename: "{code:NodeJsPath}\npm.cmd"; Parameters: "install iobroker --prefix ""{app}""";
;Filename: "{code:NodeJsPath}\npm.cmd"; Parameters: "install --production"; WorkingDir: "{app}";
;Filename: "{app}\serviceIoBroker.bat"; Parameters: "start"; WorkingDir: "{app}";
;
Filename: "{code:NodeJsPath}\npx.cmd"; Parameters: "github:iobroker/iobroker#windows-installer"; WorkingDir: "{app}";
;
;Filename: "{app}\redisSetup.exe"; Check: RedisNeedsInstall
;Filename: "{app}\couchDBsetup.exe"; Parameters: "/SILENT"; Check: CouchNeedsInstall
;Filename: "{sys}\net.exe"; Parameters: "start redis"
;Filename: "{app}\install.bat"
;Filename: "{code:NodeJsPath}\node.exe"; Parameters: """{app}\install.js"""; Flags: runhidden;
; Add Firewall Rules
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""Node In"" program=""{code:NodeJsPath}\node.exe"" dir=in action=allow enable=yes"; Flags: runhidden;
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""Node Out"" program=""{code:NodeJsPath}\node.exe"" dir=out action=allow enable=yes"; Flags: runhidden;
Filename: http://localhost:8081/; Description: "{code:GetAdminPageText}"; Flags: postinstall shellexec

[UninstallDelete]
Type: filesandordirs; Name: "{app}\daemon"
Type: filesandordirs; Name: "{app}\node_modules"
Type: filesandordirs; Name: "{app}\install"
Type: filesandordirs; Name: "{app}\iobroker-data"
Type: filesandordirs; Name: "{app}\log"
Type: filesandordirs; Name: "{app}\*.js"
Type: filesandordirs; Name: "{app}\*.md"
Type: filesandordirs; Name: "{app}\*.cmd"
Type: filesandordirs; Name: "{app}\*.bat"
Type: filesandordirs; Name: "{app}\*.json"
Type: filesandordirs; Name: "{app}\*.ps1"
Type: filesandordirs; Name: "{app}\*.sh"
Type: filesandordirs; Name: "{app}\LICENSE"
Type: filesandordirs; Name: "{app}\semver"

[UninstallRun]
; Removes System Service
Filename: "{code:NodeJsPath}\node.exe"; Parameters: """{app}\uninstall.js"""; Flags: runhidden;
;Filename: "{sys}\del"; Parameters: "/Q /S ""{app}\daemon""";
;Filename: "{sys}\rmdir"; Parameters: "/Q /S ""{app}\daemon""";
;Filename: "{sys}\del"; Parameters: "/Q /S ""{app}\node_modules""";
;Filename: "{sys}\rmdir"; Parameters: "/Q /S ""{app}\node_modules""";
;Filename: "{sys}\net"; Parameters: "stop redis"; Flags: runhidden;
;Filename: "{commonpf}\Redis\unins000.exe"
;Filename: "{commonpf32}\Apache Software Foundation\CouchDB\unins000.exe"
; Remove Firewall Rules
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Node In"" program=""{code:NodeJsPath}\node.exe"""; Flags: runhidden;
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Node Out"" program=""{code:NodeJsPath}\node.exe"""; Flags: runhidden;
; Remove all leftovers

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

#define MyAppName "ioBroker automation platform"
#define MyAppShortName "ioBroker"
#define MyAppLCShortName "iobroker"
#define MyAppVersion "@@version"
#define MyAppPublisher "ioBroker.net"
#define MyAppURL "http://ioBroker.net/"
#define MyAppIcon "ioBroker.ico"

[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={{97DA02F5-2E8C-4B96-BB42-61ED2BBF34DF}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={drive:{commonpf}}\ioBroker
;DisableDirPage=yes
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=..\..\delivery
OutputBaseFilename={#MyAppShortName}Installer.{#MyAppVersion}
SetupIconFile={#MyAppIcon}
Compression=lzma
SolidCompression=yes
UsePreviousAppDir=yes
ArchitecturesInstallIn64BitMode=x64
UninstallDisplayIcon={app}\{#MyAppIcon}
CloseApplications=yes

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "german";  MessagesFile: "compiler:Languages\German.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"

; enable scripting to force admin mode
[Registry]
Root: HKLM; Subkey: "Software\Microsoft\Windows Script Host\Settings"; ValueType: dword; ValueName: "Enabled"; ValueData: "00000001"

[Files]
Source: "nodejs\node.msi"; DestDir: "{app}"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode
Source: "nodejs\node-x64.msi"; DestDir: "{app}"; DestName: "node.msi"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode
;Source: "redis-v2.4.6\redis-2.4.6-setup-32-bit.exe"; DestDir: "{app}"; DestName: "redisSetup.exe"; Flags: ignoreversion deleteafterinstall; Check: not Is64BitInstallMode
;Source: "redis-v2.4.6\redis-2.4.6-setup-64-bit.exe"; DestDir: "{app}"; DestName: "redisSetup.exe"; Flags: ignoreversion deleteafterinstall; Check: Is64BitInstallMode
;Source: "couchDB\couchDBsetup.exe"; DestDir: "{app}"; Flags: ignoreversion deleteafterinstall;
;Source: "*.js"; DestDir: "{app}"; Flags: ignoreversion
;Source: "install.bat"; DestDir: "{app}"; Flags: ignoreversion
;Source: "package.json"; DestDir: "{app}"; Flags: ignoreversion
;Source: "npm.cmd"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MyAppIcon}"; DestDir: "{app}"; Flags: ignoreversion
;Source: "..\.windows-ready\data\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
;Source: "node_modules\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}\{#MyAppShortName} Settings"; Filename: "http://localhost:8081"; IconFilename: "{app}\{#MyAppIcon}"
Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}"; IconFilename: {app}\{#MyAppIcon};
Name: "{group}\{#MyAppShortName} Uninstall"; Filename: "{uninstallexe}"; IconFilename: {app}\{#MyAppIcon};
Name: "{group}\Start {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "start"
Name: "{group}\Stop {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "stop"
Name: "{group}\Restart {#MyAppShortName} Service"; Filename: "{app}\serviceIoBroker.bat"; Parameters: "restart"

[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
  ResultCode: integer;
begin
  Result := '';
  if FileExists(ExpandConstant('{app}\serviceIoBroker.bat')) then begin
     Exec(ExpandConstant('{app}\serviceIoBroker.bat'), 'stop', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;

function FileReplaceString(const FileName, SearchString, ReplaceString: string):boolean;
var
  MyFile : TStrings;
  MyText : string;
begin
  MyFile := TStringList.Create;

  try
    result := true;

    try
      MyFile.LoadFromFile(FileName);
      MyText := MyFile.Text;

      if StringChangeEx(MyText, SearchString, ReplaceString, True) > 0 then //Only save if text has been changed.
      begin;
        MyFile.Text := MyText;
        MyFile.SaveToFile(FileName);
      end;
    except
      result := false;
    end;
  finally
    MyFile.Free;
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  fileName : string;
  lang : string;
begin
  if  CurStep=ssPostInstall then
    begin
      lang := ActiveLanguage();
      if lang = 'russian' then begin
        lang := 'ru';
      end
      else begin
          if lang = 'german' then begin
            lang := 'de';
          end
          else begin
            lang := '';
          end;
      end;
      if lang <> '' then begin
          fileName := ExpandConstant('{app}\settings-dist.json');
          //FileReplaceString(fileName, '"language": "en"', '"language": "' + lang + '"');
      end;
    end;
end;

function RedisNeedsInstall():boolean;
begin
   result := not FileExists(ExpandConstant('{commonpf}\Redis\redis-service.exe'));
end;

function CouchNeedsInstall():boolean;
begin
   result := not FileExists(ExpandConstant('{commonpf32}\Apache Software Foundation\CouchDB\Install.exe'));
end;

function NodeJsNeedsInstall():boolean;
var
  ResultCode: integer;
begin

  result := true;
  if IsWin64 then begin
      result := not FileExists(ExpandConstant('{commonpf64}\nodejs\node.exe'));

      if result then begin
        result := not FileExists(ExpandConstant('{commonpf32}\nodejs\node.exe'));
      end;
  end;

  if result then begin
    result := not FileExists(ExpandConstant('{commonpf}\nodejs\node.exe'));
  end;

  if not DirExists(ExpandConstant('{userappdata}\npm')) then begin
     Exec(ExpandConstant('mkdir'), ExpandConstant('{userappdata}\npm'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
  if not DirExists(ExpandConstant('{userappdata}\npm-cache')) then begin
     Exec(ExpandConstant('mkdir'), ExpandConstant('{userappdata}\npm-cache'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;

function NodeJsPath(Param: String):String;
begin
  result := '';

  if DirExists(ExpandConstant('{commonpf}\nodejs')) then begin
    result := ExpandConstant('{commonpf}\nodejs');
  end;

  if IsWin64 then begin
      if DirExists(ExpandConstant('{commonpf32}\nodejs')) then begin
        result := ExpandConstant('{commonpf32}\nodejs');
      end;

      if DirExists(ExpandConstant('{commonpf64}\nodejs')) then begin
        result := ExpandConstant('{commonpf64}\nodejs');
      end;
  end;
end;

function GetAdminPageText(Param: String):String;
begin
  result := 'Open settings page';

  if ActiveLanguage() = 'german' then begin
    result := 'Einstellungen aufmachen';
  end;

  if ActiveLanguage() = 'russian' then begin
      result := 'Открыть настройки';
  end;
end;

[Run]
; postinstall launch
Filename: "msiexec.exe"; Parameters: "/i ""{app}\node.msi"" /passive"; Check: NodeJsNeedsInstall
;
;Filename: "{code:NodeJsPath}\npm.cmd"; Parameters: "install iobroker --prefix ""{app}""";
;Filename: "{code:NodeJsPath}\npm.cmd"; Parameters: "install --production"; WorkingDir: "{app}";
;Filename: "{app}\serviceIoBroker.bat"; Parameters: "start"; WorkingDir: "{app}";
;
Filename: "{code:NodeJsPath}\npx.cmd"; Parameters: "github:iobroker/iobroker#windows-installer"; WorkingDir: "{app}";
;
;Filename: "{app}\redisSetup.exe"; Check: RedisNeedsInstall
;Filename: "{app}\couchDBsetup.exe"; Parameters: "/SILENT"; Check: CouchNeedsInstall
;Filename: "{sys}\net.exe"; Parameters: "start redis"
;Filename: "{app}\install.bat"
;Filename: "{code:NodeJsPath}\node.exe"; Parameters: """{app}\install.js"""; Flags: runhidden;
; Add Firewall Rules
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""Node In"" program=""{code:NodeJsPath}\node.exe"" dir=in action=allow enable=yes"; Flags: runhidden;
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""Node Out"" program=""{code:NodeJsPath}\node.exe"" dir=out action=allow enable=yes"; Flags: runhidden;
Filename: http://localhost:8081/; Description: "{code:GetAdminPageText}"; Flags: postinstall shellexec

[UninstallRun]
; Removes System Service
Filename: "{code:NodeJsPath}\node.exe"; Parameters: """{app}\uninstall.js"""; Flags: runhidden;
Filename: "{sys}\del"; Parameters: "/Q /S ""{app}\daemon""";
Filename: "{sys}\rmdir"; Parameters: "/Q /S ""{app}\daemon""";
Filename: "{sys}\del"; Parameters: "/Q /S ""{app}\node_modules""";
Filename: "{sys}\rmdir"; Parameters: "/Q /S ""{app}\node_modules""";
;Filename: "{sys}\net"; Parameters: "stop redis"; Flags: runhidden;
;Filename: "{commonpf}\Redis\unins000.exe"
;Filename: "{commonpf32}\Apache Software Foundation\CouchDB\unins000.exe"
; Remove Firewall Rules
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Node In"" program=""{code:NodeJsPath}\node.exe"""; Flags: runhidden;
; Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Node Out"" program=""{code:NodeJsPath}\node.exe"""; Flags: runhidden;
; Remove all leftovers


Update sql2005express.iss

Update sql2005express.iss

// SQL Server Express is supported on x64 and EMT64 systems in Windows On Windows (WOW). SQL Server Express is not supported on IA64 systems
// requires Microsoft .NET Framework 2.0 or later
// SQLEXPR32.EXE is a smaller package that can be used to install SQL Server Express on 32-bit operating systems only. The larger SQLEXPR.EXE package supports installing onto both 32-bit and 64-bit (WOW install) operating systems. There is no other difference between these packages.
// http://www.microsoft.com/download/en/details.aspx?id=15291

[CustomMessages]
sql2005express_title=SQL Server 2005 Express SP3

en.sql2005express_size=38.1 MB
de.sql2005express_size=38,1 MB
es.sql2005express_size=38,1 MB

en.sql2005express_size_x64=58.1 MB
de.sql2005express_size_x64=58,1 MB
es.sql2005express_size_x64=58,1 MB

[Code]
const
	sql2005express_url = 'http://download.microsoft.com/download/4/B/E/4BED5810-C8C0-4697-BDC3-DBC114B8FF6D/SQLEXPR32_NLA.EXE';
	sql2005express_url_x64 = 'http://download.microsoft.com/download/4/B/E/4BED5810-C8C0-4697-BDC3-DBC114B8FF6D/SQLEXPR_NLA.EXE';

procedure sql2005express();
var
	version: string;
begin
	//CHECK NOT FINISHED YET
	//RTM: 9.00.1399.06
	//Service Pack 1: 9.1.2047.00
	//Service Pack 2: 9.2.3042.00
	// TODO: Newer detection method required for SP3 and x64
	//Service Pack 3: 9.00.4035.00
	//RegQueryDWordValue(HKLM, 'Software\Microsoft\Microsoft SQL Server\90\DTS\Setup', 'Install', version);
	RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\SQLEXPRESS\MSSQLServer\CurrentVersion', 'CurrentVersion', version);
	if (version < '9.00.4035') then begin
		if (not IsIA64()) then
			AddProduct('sql2005express' + GetArchitectureString() + '.exe',
				'/qb ADDLOCAL=ALL INSTANCENAME=SQLEXPRESS',
				CustomMessage('sql2005express_title'),
				CustomMessage('sql2005express_size' + GetArchitectureString()),
				GetString(sql2005express_url, sql2005express_url_x64, ''),
				false, false);
	end;
end;

// SQL Server Express is supported on x64 and EMT64 systems in Windows On Windows (WOW). SQL Server Express is not supported on IA64 systems
// requires Microsoft .NET Framework 2.0 or later
// SQLEXPR32.EXE is a smaller package that can be used to install SQL Server Express on 32-bit operating systems only. The larger SQLEXPR.EXE package supports installing onto both 32-bit and 64-bit (WOW install) operating systems. There is no other difference between these packages.
// http://www.microsoft.com/download/en/details.aspx?id=15291

[CustomMessages]
sql2005express_title=SQL Server 2005 Express SP3

en.sql2005express_size=38.1 MB
de.sql2005express_size=38,1 MB

en.sql2005express_size_x64=58.1 MB
de.sql2005express_size_x64=58,1 MB

[Code]
const
	sql2005express_url = 'http://download.microsoft.com/download/4/B/E/4BED5810-C8C0-4697-BDC3-DBC114B8FF6D/SQLEXPR32_NLA.EXE';
	sql2005express_url_x64 = 'http://download.microsoft.com/download/4/B/E/4BED5810-C8C0-4697-BDC3-DBC114B8FF6D/SQLEXPR_NLA.EXE';

procedure sql2005express();
var
	version: string;
begin
	//CHECK NOT FINISHED YET
	//RTM: 9.00.1399.06
	//Service Pack 1: 9.1.2047.00
	//Service Pack 2: 9.2.3042.00
	// TODO: Newer detection method required for SP3 and x64
	//Service Pack 3: 9.00.4035.00
	//RegQueryDWordValue(HKLM, 'Software\Microsoft\Microsoft SQL Server\90\DTS\Setup', 'Install', version);
	RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\SQLEXPRESS\MSSQLServer\CurrentVersion', 'CurrentVersion', version);
	if (version < '9.00.4035') then begin
		if (not IsIA64()) then
			AddProduct('sql2005express' + GetArchitectureString() + '.exe',
				'/qb ADDLOCAL=ALL INSTANCENAME=SQLEXPRESS',
				CustomMessage('sql2005express_title'),
				CustomMessage('sql2005express_size' + GetArchitectureString()),
				GetString(sql2005express_url, sql2005express_url_x64, ''),
				false, false);
	end;
end;