Added Generate QR-Code option in context menu.

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

#define MyAppName "WeblocOpener"
#define MyAppVersion "1.4.2"
#define MyAppPublisher "Eugene Zrazhevsky"
#define MyAppURL "https://benchdoos.github.io/"
#define MyAppExeName "WeblocOpener.exe"
#define MyAppIconsFile "icons.icl"

[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={{F1300E10-BBB2-4695-AC2F-3D58DC0BC0A6}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputDir=F:\Developer\JAVA\WeblocOpener\out\setup
OutputBaseFilename=WeblocOpenerSetup
SetupIconFile="F:\Developer\JAVA\WeblocOpener\build\installer\icon.ico"

WizardImageFile="F:\Developer\JAVA\WeblocOpener\build\installer\installer_1.bmp"
WizardSmallImageFile="F:\Developer\JAVA\WeblocOpener\build\installer\installer_3.bmp"
UninstallDisplayIcon={app}\{#MyAppIconsFile},2

ArchitecturesInstallIn64BitMode=x64

Compression=lzma
SolidCompression=yes
ChangesAssociations=yes
PrivilegesRequired=admin

[Registry]
; File association
Root: HKCR; Subkey: ".webloc"; ValueType: string; ValueName: ""; ValueData: "Webloc"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "Webloc"; ValueType: string; ValueName: ""; ValueData: "Webloc link"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Webloc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppIconsFile},3"; Flags: uninsdeletevalue
;Root: HKCR; Subkey: "Webloc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\webloc.ico"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "Webloc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletevalue

; Add new file .webloc
Root: HKCR; Subkey: ".webloc\ShellNew"; ValueType: string; ValueName: "ItemName"; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".webloc\ShellNew"; ValueType: string; ValueName: "FileName"; ValueData: "{app}\Template.webloc"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".webloc\ShellNew"; ValueType: string; ValueName: "NullFile"; ValueData: ""; Flags: uninsdeletevalue

; Add edit file menu

Root: HKCR; Subkey: "Webloc\shell\edit\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""-edit"" ""%1"" "; Flags: uninsdeletevalue

; Add edit file menu
Root: HKCR; Subkey: "Webloc\shell\GenerateQRCode"; ValueType: string; ValueName: ""; ValueData: {cm:GenerateQrCode}; Flags: uninsdeletevalue
Root: HKCR; Subkey: "Webloc\shell\GenerateQRCode"; ValueType: string; ValueName: "icon"; ValueData: """{app}\{#MyAppIconsFile}"",5"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "Webloc\shell\GenerateQRCode\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""-qr"" ""%1"" "; Flags: uninsdeletevalue

; Add updater autorun
Root: HKCU; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "WeblocOpenerUpdater"; ValueData: """{app}\Updater.jar"" ""-s"""; Flags: uninsdeletevalue

; Add app info
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: ""; ValueData: ""; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "Name"; ValueData: "{#MyAppName}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "URLUpdateInfo"; ValueData: "{#MyAppURL}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "CurrentVersion"; ValueData: "{#MyAppVersion}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "InstallLocation"; ValueData: "{app}\"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "AutoUpdateEnabled"; ValueData: "true"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "Browser"; ValueData: "default"; Flags: uninsdeletevalue

Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}\Capabilities"; ValueType: string; ValueName: "ApplicationDescription"; ValueData: "Open, edit and create .webloc links on Windows"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}\Capabilities\FileAssociations"; ValueType: string; ValueName: ".webloc"; ValueData: "Webloc link"; Flags: uninsdeletevalue
; Adds start command to cmd
Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\{#MyAppName}.exe"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletevalue
Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\{#MyAppName}.exe"; ValueType: string; ValueName: "Path"; ValueData: "{app}\"; Flags: uninsdeletevalue

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

[Files]
Source: "F:\Developer\JAVA\WeblocOpener\out\artifacts\WeblocOpener\WeblocOpener.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "F:\Developer\JAVA\WeblocOpener\out\artifacts\WeblocOpener\Template.webloc"; DestDir: "{app}"; Flags: ignoreversion
Source: "F:\Developer\JAVA\WeblocOpener\out\artifacts\Updater\Updater.jar"; DestDir: "{app}"; Flags: ignoreversion
Source: "F:\Developer\JAVA\WeblocOpener\Build\icons.icl"; DestDir: "{app}"; Flags: ignoreversion
;Source: "F:\Developer\JAVA\WeblocOpener\Build\webloc.ico"; DestDir: "{app}"; Flags: ignoreversion

;Source: "F:\Developer\JAVA\WeblocOpener\readme.rtf"; DestDir: "{app}"; Flags: ignoreversion isreadme
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[InstallDelete]
;Deletes old files
Type: files; Name: "{group}\{#MyAppName}.lnk"
Type: files; Name: "{group}\Updater.lnk"
Type: files; Name: "{app}\readme.rtf"

[Icons]
Name: "{group}\Settings - {#MyAppName}"; Filename: "{app}\{#MyAppExeName}";
Name: "{group}\Updater - {#MyAppName}"; Filename: "{app}\Updater.jar"; IconFilename: "{app}\{#MyAppIconsFile}"; IconIndex: 4;
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"; IconFilename: "{app}\{#MyAppIconsFile}"; IconIndex: 1;

[Run]
Filename: https://benchdoos.github.io/; Description: "{cm:ProgramOnTheWeb,{#MyAppName}}"; Flags: postinstall shellexec  unchecked

[Code]
/////////////////////////////////////////////////////////////////////
function GetUninstallString(): String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
  sUnInstallString := '';
  if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
    RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
  Result := sUnInstallString;
end;

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

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

  // default return value
  Result := 0;

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

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

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

#define MyAppName "WeblocOpener"
#define MyAppVersion "1.4.2"
#define MyAppPublisher "Eugene Zrazhevsky"
#define MyAppURL "https://benchdoos.github.io/"
#define MyAppExeName "WeblocOpener.exe"
#define MyAppIconsFile "icons.icl"

[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={{F1300E10-BBB2-4695-AC2F-3D58DC0BC0A6}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputDir=F:\Developer\JAVA\WeblocOpener\out\setup
OutputBaseFilename=WeblocOpenerSetup
SetupIconFile="F:\Developer\JAVA\WeblocOpener\build\installer\icon.ico"

WizardImageFile="F:\Developer\JAVA\WeblocOpener\build\installer\installer_1.bmp"
WizardSmallImageFile="F:\Developer\JAVA\WeblocOpener\build\installer\installer_3.bmp"
UninstallDisplayIcon={app}\{#MyAppIconsFile},2

ArchitecturesInstallIn64BitMode=x64

Compression=lzma
SolidCompression=yes
ChangesAssociations=yes
PrivilegesRequired=admin

[Registry]
; File association
Root: HKCR; Subkey: ".webloc"; ValueType: string; ValueName: ""; ValueData: "Webloc"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "Webloc"; ValueType: string; ValueName: ""; ValueData: "Webloc link"; Flags: uninsdeletekey
Root: HKCR; Subkey: "Webloc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppIconsFile},3"; Flags: uninsdeletevalue
;Root: HKCR; Subkey: "Webloc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\webloc.ico"; Flags: uninsdeletevalue
Root: HKCR; Subkey: "Webloc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletevalue

; Add new file .webloc
Root: HKCR; Subkey: ".webloc\ShellNew"; ValueType: string; ValueName: "ItemName"; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".webloc\ShellNew"; ValueType: string; ValueName: "FileName"; ValueData: "{app}\Template.webloc"; Flags: uninsdeletevalue
Root: HKCR; Subkey: ".webloc\ShellNew"; ValueType: string; ValueName: "NullFile"; ValueData: ""; Flags: uninsdeletevalue

; Add edit file menu
Root: HKCR; Subkey: "Webloc\shell\edit\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""-edit"" ""%1"" "; Flags: uninsdeletevalue

; Add updater autorun
Root: HKCU; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "WeblocOpenerUpdater"; ValueData: """{app}\Updater.jar"" ""-s"""; Flags: uninsdeletevalue

; Add app info
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: ""; ValueData: ""; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "Name"; ValueData: "{#MyAppName}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "URLUpdateInfo"; ValueData: "{#MyAppURL}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "CurrentVersion"; ValueData: "{#MyAppVersion}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "InstallLocation"; ValueData: "{app}\"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "AutoUpdateEnabled"; ValueData: "true"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}"; ValueType: string; ValueName: "Browser"; ValueData: "default"; Flags: uninsdeletevalue

Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}\Capabilities"; ValueType: string; ValueName: "ApplicationDescription"; ValueData: "Open, edit and create .webloc links on Windows"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\{#MyAppName}\Capabilities\FileAssociations"; ValueType: string; ValueName: ".webloc"; ValueData: "Webloc link"; Flags: uninsdeletevalue
; Adds start command to cmd
Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\{#MyAppName}.exe"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletevalue
Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\{#MyAppName}.exe"; ValueType: string; ValueName: "Path"; ValueData: "{app}\"; Flags: uninsdeletevalue

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

[Files]
Source: "F:\Developer\JAVA\WeblocOpener\out\artifacts\WeblocOpener\WeblocOpener.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "F:\Developer\JAVA\WeblocOpener\out\artifacts\WeblocOpener\Template.webloc"; DestDir: "{app}"; Flags: ignoreversion
Source: "F:\Developer\JAVA\WeblocOpener\out\artifacts\Updater\Updater.jar"; DestDir: "{app}"; Flags: ignoreversion
Source: "F:\Developer\JAVA\WeblocOpener\Build\icons.icl"; DestDir: "{app}"; Flags: ignoreversion
;Source: "F:\Developer\JAVA\WeblocOpener\Build\webloc.ico"; DestDir: "{app}"; Flags: ignoreversion

;Source: "F:\Developer\JAVA\WeblocOpener\readme.rtf"; DestDir: "{app}"; Flags: ignoreversion isreadme
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[InstallDelete]
;Deletes old files
Type: files; Name: "{group}\{#MyAppName}.lnk"
Type: files; Name: "{group}\Updater.lnk"
Type: files; Name: "{app}\readme.rtf"

[Icons]
Name: "{group}\Settings - {#MyAppName}"; Filename: "{app}\{#MyAppExeName}";
Name: "{group}\Updater - {#MyAppName}"; Filename: "{app}\Updater.jar"; IconFilename: "{app}\{#MyAppIconsFile}"; IconIndex: 4;
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"; IconFilename: "{app}\{#MyAppIconsFile}"; IconIndex: 1;

[Run]
Filename: https://benchdoos.github.io/; Description: "{cm:ProgramOnTheWeb,{#MyAppName}}"; Flags: postinstall shellexec  unchecked

[Code]
/////////////////////////////////////////////////////////////////////
function GetUninstallString(): String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
  sUnInstallString := '';
  if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
    RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
  Result := sUnInstallString;
end;

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

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

  // default return value
  Result := 0;

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

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


Added VS2010 property sheets to the SDK installer.

[Setup]
; include either setup-sdk-win32.txt or setup-sdk-x64.txt
#include "setup-sdk-win32.txt"
;#include "setup-sdk-x64.txt"

[Types]
Name: full; Description: Full installation
Name: sdk; Description: SDK installation
Name: docs; Description: Documentation installation
Name: custom; Description: Custom installation; Flags: iscustom

[Components]
Name: sdk; Description: UniMRCP SDK (client, server and plugin development); Types: full sdk
Name: docs; Description: UniMRCP documentation; Types: full docs
Name: docs\design; Description: Design concepts; Types: full docs
Name: docs\api; Description: API; Types: full docs

[Files]
Source: {#= uni_src}\libs\apr\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\apr-toolkit\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mpf\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\message\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\control\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\resources\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-engine\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-signaling\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcpv2-transport\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-client\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-server\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\platforms\libunimrcp-client\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\platforms\libunimrcp-server\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\{#= release_dir}\lib\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\apr\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\apr-util\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\sofia-sip\win32\libsofia-sip-ua\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\build\props\sdk\*.props; DestDir: {app}\props; Components: sdk; AfterInstall: SetProjectPath(ExpandConstant('{app}\props\unimrcpsdk.props'))
Source: {#= uni_src}\build\vsprops\sdk\*.vsprops; DestDir: {app}\vsprops; Components: sdk; AfterInstall: SetProjectPath(ExpandConstant('{app}\vsprops\unimrcpsdk.vsprops'))
Source: {#= uni_src}\docs\ea\*; DestDir: {app}\doc\ea; Components: docs/design; Flags: recursesubdirs
Source: {#= uni_src}\docs\dox\*; DestDir: {app}\doc\dox; Components: docs/api; Flags: recursesubdirs

[Icons]
Name: {group}\UniMRCP Docs\Design concepts; Filename: {app}\doc\ea\index.htm; Components: docs\design
Name: {group}\UniMRCP Docs\API; Filename: {app}\doc\dox\html\index.html; Components: docs\api
Name: {group}\Uninstall; Filename: {uninstallexe}

[Code]
procedure SetProjectPath(PropertySheetFile: String);
var
  Content: String;
begin
  LoadStringFromFile (PropertySheetFile, Content);
  StringChange (Content, 'C:\Program Files\UniMRCP', ExpandConstant('{app}'));
  SaveStringToFile (PropertySheetFile, Content, False);
end;

[Setup]
; include either setup-sdk-win32.txt or setup-sdk-x64.txt
#include "setup-sdk-win32.txt"
;#include "setup-sdk-x64.txt"

[Types]
Name: full; Description: Full installation
Name: sdk; Description: SDK installation
Name: docs; Description: Documentation installation
Name: custom; Description: Custom installation; Flags: iscustom

[Components]
Name: sdk; Description: UniMRCP SDK (client, server and plugin development); Types: full sdk
Name: docs; Description: UniMRCP documentation; Types: full docs
Name: docs\design; Description: Design concepts; Types: full docs
Name: docs\api; Description: API; Types: full docs

[Files]
Source: {#= uni_src}\libs\apr\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\apr-toolkit\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mpf\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\message\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\control\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp\resources\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-engine\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-signaling\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcpv2-transport\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-client\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\libs\mrcp-server\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\platforms\libunimrcp-client\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\platforms\libunimrcp-server\include\*.h; DestDir: {app}\include; Components: sdk
Source: {#= uni_src}\{#= release_dir}\lib\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\apr\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\apr-util\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\libs\sofia-sip\win32\libsofia-sip-ua\{#= release_dir}\*.lib; DestDir: {app}\lib; Components: sdk
Source: {#= uni_src}\build\vsprops\sdk\*.vsprops; DestDir: {app}\vsprops; Components: sdk; AfterInstall: SetProjectPath()
Source: {#= uni_src}\docs\ea\*; DestDir: {app}\doc\ea; Components: docs/design; Flags: recursesubdirs
Source: {#= uni_src}\docs\dox\*; DestDir: {app}\doc\dox; Components: docs/api; Flags: recursesubdirs

[Icons]
Name: {group}\UniMRCP Docs\Design concepts; Filename: {app}\doc\ea\index.htm; Components: docs\design
Name: {group}\UniMRCP Docs\API; Filename: {app}\doc\dox\html\index.html; Components: docs\api
Name: {group}\Uninstall; Filename: {uninstallexe}

[Code]
procedure SetProjectPath();
var
  VspropsFile: String;
  Content: String;
begin
  VspropsFile := ExpandConstant('{app}\vsprops\unimrcpsdk.vsprops');
  LoadStringFromFile (VspropsFile, Content);
  StringChange (Content, 'Value="C:\Program Files\UniMRCP"', ExpandConstant('Value="{app}"'));
  SaveStringToFile (VspropsFile, Content, False);
end;


Escape userdata arguments

Escape userdata arguments

[Code]

const
  SID_START = 'S-1-5-21-';

type
  TUserDataRec = record
    User      : String;
    Folder    : String;
    Caption   : String;
    Delete    : Boolean;
    Local     : Boolean;
  end;

type
  TUserFolderRec = record
    User      : String;
    Home      : String;
    Cache     : String;
  end;

type
  TUserDataList = array of TUserDataRec;

type
  TUserProfileRec = record
    User      : String;
    Profile   : String;
  end;

type
  TUserProfileList = array of TUserProfileRec;

type
  TDataForm = record
    Main: TSetupForm;
    ListBox: TNewCheckListBox;
  end;

var
  GUserForm: TDataForm;

const
  DELETE_NONE = 0;
  DELETE_LOCAL = 1;
  DELETE_ALL = 2;

function DeleteData(HParent: HWND; DirList: String; Silent: Boolean): Boolean;
  external 'DeleteData@{app}\{#DllData} stdcall delayload uninstallonly';

function GetResult(StrBuf: String; BufCount: DWord): DWord;
  external 'GetResult@{app}\{#DllData} stdcall delayload uninstallonly';

procedure UserDataDelete; forward;
function UserDataGet(Status: Integer): TUserDataList; forward;
procedure UserDataGetAll(const User: String; var List: TUserDataList); forward;
function UserGetAccountsWmi(var Accounts: TUserProfileList): Boolean; forward;
function UserGetAccountsReg(var Accounts: TUserProfileList): Boolean; forward;
function UserGetProfile(const Sid: String; var Path: String): Boolean; forward;
procedure UserAddProfileRec(const User, Profile: String; var Accounts: TUserProfileList); forward;
procedure UserAddDataItem(User, Folder, Caption: String; Local: Boolean; var List: TUserDataList); forward;
procedure UserAddDataRec(Rec: TUserFolderRec; var List: TUserDataList); forward;
function UserGetFolderPrefix(const Folder: String; var Prefix: String): Boolean; forward;
procedure UserDeleteData(List: TUserDataList; const DllData: String); forward;
function UserDataSelect(Status: Integer; var List: TUserDataList): Boolean; forward;
procedure UserDataCreateForm(Status: Integer; var Form: TDataForm); forward;
procedure UserCheckboxClick(Sender: TObject); forward;
function UserGetDelete: Integer; forward;

procedure UserDataDelete;
var
  List: TUserDataList;
  DllData: String;
  Status: Integer;

begin

  {The main function, must be called from Uninstall step usUninstall,
  otherwise the dll and app dir will not be deleted}

  DllData := ExpandConstant('{app}\{#DllData}');
  Status := UserGetDelete();

  try

    List := UserDataGet(Status);

    if UninstallSilent or UserDataSelect(Status, List) then
      UserDeleteData(List, DllData);

  finally
    {Important to unload dll, or it will not be deleted}
    UnloadDLL(DllData);
  end;

end;

function UserDataGet(Status: Integer): TUserDataList;
var
  Rec: TUserFolderRec;
  I: Integer;

begin

  {Add current user as first item}
  Rec.User := GetUserNameString;
  Rec.Home := ExpandConstant('{userappdata}\Composer');
  Rec.Cache := ExpandConstant('{localappdata}\Composer');
  UserAddDataRec(Rec, Result);

  if IsAdminLoggedOn then
    UserDataGetAll(Rec.User, Result);

  for I := 0 to GetArrayLength(Result) - 1 do
  begin

    case Status of
      DELETE_NONE: Result[I].Delete := False;
      DELETE_LOCAL: Result[I].Delete := Result[I].Local;
      DELETE_ALL: Result[I].Delete := True;
    end;

  end;

end;

procedure UserDataGetAll(const User: String; var List: TUserDataList);
var
  HomeSuffix: String;
  CacheSuffix: String;
  Accounts: TUserProfileList;
  I: Integer;
  SafeDir: String;
  SystemDir: String;
  Rec: TUserFolderRec;

begin

  {We use Windows wmi as this is a reliable way to get the correct user name
  for each local account. If this is not available (it is missing from XP Home),
  we fallback to using the registry.}

  if UserGetFolderPrefix('AppData', HomeSuffix) then
    HomeSuffix := AddBackslash(HomeSuffix) + 'Composer'
  else
    Exit;

  if UserGetFolderPrefix('Local AppData', CacheSuffix) then
    CacheSuffix := AddBackslash(CacheSuffix) + 'Composer'
  else
    Exit;

  if not (UserGetAccountsWmi(Accounts) or UserGetAccountsReg(Accounts)) then
    Exit;

  SystemDir := AnsiLowercase(GetSystemDir());

  {Check profile paths and add suffixes}
  for I := 0 to GetArrayLength(Accounts) - 1 do
  begin

    {Ignore current user - first item in List}
    if CompareText(User, Accounts[I].User) = 0 then
      Continue;

    SafeDir := NormalizePath(Accounts[I].Profile);

    if (SafeDir = '') or (Pos('\\',SafeDir) = 1) or (Pos(SystemDir, AnsiLowercase(SafeDir)) = 1) then
      Continue;

    Rec.User := Accounts[I].User;
    Rec.Home := AddBackslash(SafeDir) + HomeSuffix;
    Rec.Cache := AddBackslash(SafeDir) + CacheSuffix;
    UserAddDataRec(Rec, List);

  end;

end;

function UserGetAccountsWmi(var Accounts: TUserProfileList): Boolean;
var
  Cmd: String;
  Dir: String;
  Output: String;
  Params: String;
  ExitCode: Longint;
  SList: TStringList;
  Line: String;
  I: Integer;
  P: Integer;
  Sid: String;
  User: String;
  Profile: String;

begin

  Result := False;

  Cmd := ExpandConstant('{cmd}');
  Dir := ExpandConstant('{tmp}');
  Output := Dir + '\result.txt';

  Params := Format('/c "%s %s > %s"', ['wmic', 'USERACCOUNT GET Name,SID,Disabled', ArgCmd(Output)]);
  Debug('Calling cmd.exe with params: ' + Params);

  if not (Exec(Cmd, Params, Dir, 0, ewWaitUntilTerminated, ExitCode)) or (ExitCode <> 0) then
    Exit;

  {We use TStringList because this handles the BOM produced in the output file}
  SList := TStringList.Create();

  try

    SList.LoadFromFile(Output);

    {Format is always: Disabled (TRUE/FALSE) tab UserName tab SID, for example:
    FALSE    Fred    S-1-5-21-2053653857-3368111017-1490883677-1002}

    for I := 0 to SList.Count - 1 do
    begin

      Line := Trim(SList.Strings[I]);

      {Check and strip FALSE (ie not disabled)}
      if Pos('FALSE', Line) = 1 then
        Line := TrimLeft(Copy(Line, 6, MaxInt))
      else
        Continue;

      {Check for relevant SID}
      P := Pos(SID_START, Line);

      if P > 0 then
      begin

        Sid := Copy(Line, P, MaxInt);
        User := TrimRight(Copy(Line, 1, P - 1));

        if UserGetProfile(Sid, Profile) then
          UserAddProfileRec(User, Profile, Accounts);

      end;

    end;

  finally
    SList.Free;
  end;

  Result := GetArrayLength(Accounts) > 0;

end;

function UserGetAccountsReg(var Accounts: TUserProfileList): Boolean;
var
  SubKey: String;
  Sids: TArrayofString;
  I: Integer;
  Profile: String;

begin

  Result := False;

  SubKey := 'Software\Microsoft\Windows NT\CurrentVersion\ProfileList'

  if not RegGetSubkeyNames(HKLM, SubKey, Sids) then
    Exit;

  for I := 0 to GetArrayLength(Sids) - 1 do
  begin

    if Pos(SID_START, Sids[I]) <> 0 then
    begin

      if UserGetProfile(Sids[I], Profile) then
        UserAddProfileRec(ExtractFileName(Profile), Profile, Accounts);

    end;

  end;

  Result := GetArrayLength(Accounts) > 0;

end;

function UserGetProfile(const Sid: String; var Path: String): Boolean;
var
  SubKey: String;

begin

  Result := False;
  Path := '';

  SubKey := 'Software\Microsoft\Windows NT\CurrentVersion\ProfileList\' + Sid;

  if RegQueryStringValue(HKLM, SubKey, 'ProfileImagePath', Path) then
    Result := True;

end;

procedure UserAddProfileRec(const User, Profile: String; var Accounts: TUserProfileList);
var
  Index: Integer;

begin

  Index := GetArrayLength(Accounts);
  SetArrayLength(Accounts, Index + 1);
  Accounts[Index].User := User;
  Accounts[Index].Profile := Profile;

end;

procedure UserAddDataItem(User, Folder, Caption: String; Local: Boolean; var List: TUserDataList);
var
  Index: Integer;

begin

  Index := GetArrayLength(List);
  SetArrayLength(List, Index + 1);
  List[Index].User := User;
  List[Index].Folder := Folder;
  List[Index].Caption := Caption;
  List[Index].Local := Local;

end;

procedure UserAddDataRec(Rec: TUserFolderRec; var List: TUserDataList);
var
  User: String;
  Caption: String;
  Local: Boolean;

begin

  if DirExists(Rec.Cache) then
  begin
    User := Rec.User + ': local';
    Caption := 'cache';
    Local := True;
    UserAddDataItem(User, Rec.Cache, Caption, Local, List);
  end;

  if DirExists(Rec.Home) then
  begin
    User := Rec.User + ': roaming';
    Caption := 'config';
    Local := False;

    if DirExists(Rec.Home + '\vendor') then
      Caption := Caption + ', bin';

    UserAddDataItem(User, Rec.Home, Caption, Local, List);
  end;

end;

function UserGetFolderPrefix(const Folder: String; var Prefix: String): Boolean;
var
  SubKey: String;
  Profile: String;

begin

  Result := False;
  Prefix := '';

  SubKey := '.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders';

  if not RegQueryStringValue(HKEY_USERS, SubKey, Folder, Prefix) then
    Exit;

  Profile := '%USERPROFILE%';

  if Pos(Profile, Prefix) <> 1 then
    Exit;

  Prefix := Copy(Prefix, Length(Profile) + 1, MaxInt);
  StringChangeEx(Prefix, '/', '\', True);
  Result := Prefix <> '';

end;

procedure UserDeleteData(List: TUserDataList; const DllData: String);
var
  Data: String;
  I: Integer;
  CharCount: DWord;
  InfoList: TStringList;

begin

  for I := 0 to GetArrayLength(List) - 1 do
  begin

    if List[I].Delete then
      Data := Data + List[I].Folder + ';';

  end;

  if Data = '' then
    Exit;

  Debug('Calling dll: ' + DllData);
  DeleteData(UninstallProgressForm.Handle, Data, UninstallSilent);

  CharCount := 0;
  CharCount := GetResult(Data, CharCount);
  SetLength(Data, CharCount);

  if GetResult(Data, CharCount) <> CharCount then
    Exit;

  Data := TrimRight(Data);
  StringChangeEx(Data, ';', #13, True);

  InfoList := TStringList.Create;

  try
    InfoList.Text := Data;

    for I := 0 to InfoList.Count - 1 do
      Debug(InfoList.Strings[I]);

  finally
    InfoList.Free;
  end;

  {Update uninstall form so it repaints}
  Sleep(10);
  UninstallProgressForm.Update;

end;

function UserDataSelect(Status: Integer; var List: TUserDataList): Boolean;
var
  I: Integer;
  Index: Integer;

begin

  Result := False;

  if GetArrayLength(List) = 0 then
  begin
    Debug('No user data found');
    Exit;
  end;

  {Create the form}
  UserDataCreateForm(Status, GUserForm);

  try

    {Populate the listbox}
    for I := 0 to GetArrayLength(List) - 1 do
    begin
      GUserForm.ListBox.AddCheckBox(List[I].User, List[I].Caption, 0,
        List[I].Delete, True, False, False, TObject(I));
    end;

    {Show the form}
    GUserForm.Main.ShowModal();

    {Transfer checked items to Delete field}
    for I := 0 to GUserForm.ListBox.Items.Count - 1 do
    begin

      Index := Integer(GUserForm.ListBox.ItemObject[I]);
      List[Index].Delete := GUserForm.ListBox.Checked[I];

      if GUserForm.ListBox.Checked[I] then
        Result := True;

    end;

    if Result then
      Debug('User chose to delete data')
    else
      Debug('User chose not to delete data');

  finally
    GUserForm.Main.Free();
  end;

end;

procedure UserDataCreateForm(Status: Integer; var Form: TDataForm);
var
  Left: Integer;
  Width: Integer;
  Text: TNewStaticText;
  Checkbox: TNewCheckbox;
  OkButton: TButton;

begin

  Form.Main := CreateCustomForm();

  Form.Main.ClientWidth := ScaleX(380);
  Form.Main.ClientHeight := ScaleY(255);
  Form.Main.Caption := 'Delete User Data';
  Form.Main.CenterInsideControl(UninstallProgressForm, False);

  Left := ScaleX(20);
  Width := Form.Main.ClientWidth - (Left * 2);

  Text := TNewStaticText.Create(Form.Main);
  Text.Top := ScaleY(16);
  Text.Parent := Form.Main;
  Text.Left := Left;
  Text.Width := Width;
  Text.AutoSize := True;
  Text.WordWrap := True;
  Text.Caption := 'Please select the user data you want to delete.';

  Form.ListBox := TNewCheckListBox.Create(Form.Main);
  Form.ListBox.Top := Text.Top + Text.Height + ScaleY(10);
  Form.ListBox.Parent := Form.Main;
  Form.ListBox.Left := Left;
  Form.ListBox.Width := Width;
  Form.ListBox.Height := ScaleY(148);

  Checkbox := TNewCheckbox.Create(Form.Main);
  Checkbox.Top := Form.ListBox.Top + Form.ListBox.Height + ScaleY(6);
  Checkbox.Left := Left;
  Checkbox.Parent := Form.Main;
  Checkbox.Caption := 'Select All';
  Checkbox.Checked := Status = DELETE_ALL;
  Checkbox.OnClick := @UserCheckboxClick;

  OkButton := TButton.Create(Form.Main);
  OkButton.Parent := Form.Main;
  OkButton.Width := ScaleX(75);
  OkButton.Height := ScaleY(23);
  OkButton.Left := Form.Main.ClientWidth - (ScaleX(75) + Left);
  OkButton.Top := Form.Main.ClientHeight - ScaleY(23 + 16);
  OkButton.Caption := '&OK';
  OkButton.ModalResult := mrOk;
  OKButton.Default := True;

  Form.Main.ActiveControl := OkButton;

end;

procedure UserCheckboxClick(Sender: TObject);
var
  Checkbox: TNewCheckbox;
  I: Integer;

begin

  Checkbox := Sender as TNewCheckbox;

  for I := 0 to GUserForm.ListBox.Items.Count - 1 do
    GUserForm.ListBox.Checked[I] := Checkbox.Checked;

end;

function UserGetDelete: Integer;
var
  Param: String;

begin

  Result := DELETE_NONE;
  Param := ExpandConstant('{param:delete}');

  if CompareText(Param, 'local') = 0 then
    Result := DELETE_LOCAL
  else if CompareText(Param, 'all') = 0 then
    Result := DELETE_ALL;

end;

[Code]

const
  SID_START = 'S-1-5-21-';

type
  TUserDataRec = record
    User      : String;
    Folder    : String;
    Caption   : String;
    Delete    : Boolean;
    Local     : Boolean;
  end;

type
  TUserFolderRec = record
    User      : String;
    Home      : String;
    Cache     : String;
  end;

type
  TUserDataList = array of TUserDataRec;

type
  TUserProfileRec = record
    User      : String;
    Profile   : String;
  end;

type
  TUserProfileList = array of TUserProfileRec;

type
  TDataForm = record
    Main: TSetupForm;
    ListBox: TNewCheckListBox;
  end;

var
  GUserForm: TDataForm;

const
  DELETE_NONE = 0;
  DELETE_LOCAL = 1;
  DELETE_ALL = 2;

function DeleteData(HParent: HWND; DirList: String; Silent: Boolean): Boolean;
  external 'DeleteData@{app}\{#DllData} stdcall delayload uninstallonly';

function GetResult(StrBuf: String; BufCount: DWord): DWord;
  external 'GetResult@{app}\{#DllData} stdcall delayload uninstallonly';

procedure UserDataDelete; forward;
function UserDataGet(Status: Integer): TUserDataList; forward;
procedure UserDataGetAll(const User: String; var List: TUserDataList); forward;
function UserGetAccountsWmi(var Accounts: TUserProfileList): Boolean; forward;
function UserGetAccountsReg(var Accounts: TUserProfileList): Boolean; forward;
function UserGetProfile(const Sid: String; var Path: String): Boolean; forward;
procedure UserAddProfileRec(const User, Profile: String; var Accounts: TUserProfileList); forward;
procedure UserAddDataItem(User, Folder, Caption: String; Local: Boolean; var List: TUserDataList); forward;
procedure UserAddDataRec(Rec: TUserFolderRec; var List: TUserDataList); forward;
function UserGetFolderPrefix(const Folder: String; var Prefix: String): Boolean; forward;
procedure UserDeleteData(List: TUserDataList; const DllData: String); forward;
function UserDataSelect(Status: Integer; var List: TUserDataList): Boolean; forward;
procedure UserDataCreateForm(Status: Integer; var Form: TDataForm); forward;
procedure UserCheckboxClick(Sender: TObject); forward;
function UserGetDelete: Integer; forward;

procedure UserDataDelete;
var
  List: TUserDataList;
  DllData: String;
  Status: Integer;

begin

  {The main function, must be called from Uninstall step usUninstall,
  otherwise the dll and app dir will not be deleted}

  DllData := ExpandConstant('{app}\{#DllData}');
  Status := UserGetDelete();

  try

    List := UserDataGet(Status);

    if UninstallSilent or UserDataSelect(Status, List) then
      UserDeleteData(List, DllData);

  finally
    {Important to unload dll, or it will not be deleted}
    UnloadDLL(DllData);
  end;

end;

function UserDataGet(Status: Integer): TUserDataList;
var
  Rec: TUserFolderRec;
  I: Integer;

begin

  {Add current user as first item}
  Rec.User := GetUserNameString;
  Rec.Home := ExpandConstant('{userappdata}\Composer');
  Rec.Cache := ExpandConstant('{localappdata}\Composer');
  UserAddDataRec(Rec, Result);

  if IsAdminLoggedOn then
    UserDataGetAll(Rec.User, Result);

  for I := 0 to GetArrayLength(Result) - 1 do
  begin

    case Status of
      DELETE_NONE: Result[I].Delete := False;
      DELETE_LOCAL: Result[I].Delete := Result[I].Local;
      DELETE_ALL: Result[I].Delete := True;
    end;

  end;

end;

procedure UserDataGetAll(const User: String; var List: TUserDataList);
var
  HomeSuffix: String;
  CacheSuffix: String;
  Accounts: TUserProfileList;
  I: Integer;
  SafeDir: String;
  SystemDir: String;
  Rec: TUserFolderRec;

begin

  {We use Windows wmi as this is a reliable way to get the correct user name
  for each local account. If this is not available (it is missing from XP Home),
  we fallback to using the registry.}

  if UserGetFolderPrefix('AppData', HomeSuffix) then
    HomeSuffix := AddBackslash(HomeSuffix) + 'Composer'
  else
    Exit;

  if UserGetFolderPrefix('Local AppData', CacheSuffix) then
    CacheSuffix := AddBackslash(CacheSuffix) + 'Composer'
  else
    Exit;

  if not (UserGetAccountsWmi(Accounts) or UserGetAccountsReg(Accounts)) then
    Exit;

  SystemDir := AnsiLowercase(GetSystemDir());

  {Check profile paths and add suffixes}
  for I := 0 to GetArrayLength(Accounts) - 1 do
  begin

    {Ignore current user - first item in List}
    if CompareText(User, Accounts[I].User) = 0 then
      Continue;

    SafeDir := NormalizePath(Accounts[I].Profile);

    if (SafeDir = '') or (Pos('\\',SafeDir) = 1) or (Pos(SystemDir, AnsiLowercase(SafeDir)) = 1) then
      Continue;

    Rec.User := Accounts[I].User;
    Rec.Home := AddBackslash(SafeDir) + HomeSuffix;
    Rec.Cache := AddBackslash(SafeDir) + CacheSuffix;
    UserAddDataRec(Rec, List);

  end;

end;

function UserGetAccountsWmi(var Accounts: TUserProfileList): Boolean;
var
  Cmd: String;
  Output: String;
  Params: String;
  ExitCode: Longint;
  SList: TStringList;
  Line: String;
  I: Integer;
  P: Integer;
  Sid: String;
  User: String;
  Profile: String;

begin

  Result := False;

  Cmd := ExpandConstant('{cmd}');
  Output := AddBackslash(ExpandConstant('{tmp}')) + 'result.txt';
  Params := Format('/c "%s %s > %s"', ['wmic', 'USERACCOUNT GET Name,SID,Disabled', AddQuotes(Output)]);
  Debug('Calling cmd.exe with params: ' + Params);

  if not (Exec(Cmd, Params, GTmpDir, 0, ewWaitUntilTerminated, ExitCode)) or (ExitCode <> 0) then
    Exit;

  {We use TStringList because this handles the BOM produced in the output file}
  SList := TStringList.Create();

  try

    SList.LoadFromFile(Output);

    {Format is always: Disabled (TRUE/FALSE) tab UserName tab SID, for example:
    FALSE    Fred    S-1-5-21-2053653857-3368111017-1490883677-1002}

    for I := 0 to SList.Count - 1 do
    begin

      Line := Trim(SList.Strings[I]);

      {Check and strip FALSE (ie not disabled)}
      if Pos('FALSE', Line) = 1 then
        Line := TrimLeft(Copy(Line, 6, MaxInt))
      else
        Continue;

      {Check for relevant SID}
      P := Pos(SID_START, Line);

      if P > 0 then
      begin

        Sid := Copy(Line, P, MaxInt);
        User := TrimRight(Copy(Line, 1, P - 1));

        if UserGetProfile(Sid, Profile) then
          UserAddProfileRec(User, Profile, Accounts);

      end;

    end;

  finally
    SList.Free;
  end;

  Result := GetArrayLength(Accounts) > 0;

end;

function UserGetAccountsReg(var Accounts: TUserProfileList): Boolean;
var
  SubKey: String;
  Sids: TArrayofString;
  I: Integer;
  Profile: String;

begin

  Result := False;

  SubKey := 'Software\Microsoft\Windows NT\CurrentVersion\ProfileList'

  if not RegGetSubkeyNames(HKLM, SubKey, Sids) then
    Exit;

  for I := 0 to GetArrayLength(Sids) - 1 do
  begin

    if Pos(SID_START, Sids[I]) <> 0 then
    begin

      if UserGetProfile(Sids[I], Profile) then
        UserAddProfileRec(ExtractFileName(Profile), Profile, Accounts);

    end;

  end;

  Result := GetArrayLength(Accounts) > 0;

end;

function UserGetProfile(const Sid: String; var Path: String): Boolean;
var
  SubKey: String;

begin

  Result := False;
  Path := '';

  SubKey := 'Software\Microsoft\Windows NT\CurrentVersion\ProfileList\' + Sid;

  if RegQueryStringValue(HKLM, SubKey, 'ProfileImagePath', Path) then
    Result := True;

end;

procedure UserAddProfileRec(const User, Profile: String; var Accounts: TUserProfileList);
var
  Index: Integer;

begin

  Index := GetArrayLength(Accounts);
  SetArrayLength(Accounts, Index + 1);
  Accounts[Index].User := User;
  Accounts[Index].Profile := Profile;

end;

procedure UserAddDataItem(User, Folder, Caption: String; Local: Boolean; var List: TUserDataList);
var
  Index: Integer;

begin

  Index := GetArrayLength(List);
  SetArrayLength(List, Index + 1);
  List[Index].User := User;
  List[Index].Folder := Folder;
  List[Index].Caption := Caption;
  List[Index].Local := Local;

end;

procedure UserAddDataRec(Rec: TUserFolderRec; var List: TUserDataList);
var
  User: String;
  Caption: String;
  Local: Boolean;

begin

  if DirExists(Rec.Cache) then
  begin
    User := Rec.User + ': local';
    Caption := 'cache';
    Local := True;
    UserAddDataItem(User, Rec.Cache, Caption, Local, List);
  end;

  if DirExists(Rec.Home) then
  begin
    User := Rec.User + ': roaming';
    Caption := 'config';
    Local := False;

    if DirExists(Rec.Home + '\vendor') then
      Caption := Caption + ', bin';

    UserAddDataItem(User, Rec.Home, Caption, Local, List);
  end;

end;

function UserGetFolderPrefix(const Folder: String; var Prefix: String): Boolean;
var
  SubKey: String;
  Profile: String;

begin

  Result := False;
  Prefix := '';

  SubKey := '.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders';

  if not RegQueryStringValue(HKEY_USERS, SubKey, Folder, Prefix) then
    Exit;

  Profile := '%USERPROFILE%';

  if Pos(Profile, Prefix) <> 1 then
    Exit;

  Prefix := Copy(Prefix, Length(Profile) + 1, MaxInt);
  StringChangeEx(Prefix, '/', '\', True);
  Result := Prefix <> '';

end;

procedure UserDeleteData(List: TUserDataList; const DllData: String);
var
  Data: String;
  I: Integer;
  CharCount: DWord;
  InfoList: TStringList;

begin

  for I := 0 to GetArrayLength(List) - 1 do
  begin

    if List[I].Delete then
      Data := Data + List[I].Folder + ';';

  end;

  if Data = '' then
    Exit;

  Debug('Calling dll: ' + DllData);
  DeleteData(UninstallProgressForm.Handle, Data, UninstallSilent);

  CharCount := 0;
  CharCount := GetResult(Data, CharCount);
  SetLength(Data, CharCount);

  if GetResult(Data, CharCount) <> CharCount then
    Exit;

  Data := TrimRight(Data);
  StringChangeEx(Data, ';', #13, True);

  InfoList := TStringList.Create;

  try
    InfoList.Text := Data;

    for I := 0 to InfoList.Count - 1 do
      Debug(InfoList.Strings[I]);

  finally
    InfoList.Free;
  end;

  {Update uninstall form so it repaints}
  Sleep(10);
  UninstallProgressForm.Update;

end;

function UserDataSelect(Status: Integer; var List: TUserDataList): Boolean;
var
  I: Integer;
  Index: Integer;

begin

  Result := False;

  if GetArrayLength(List) = 0 then
  begin
    Debug('No user data found');
    Exit;
  end;

  {Create the form}
  UserDataCreateForm(Status, GUserForm);

  try

    {Populate the listbox}
    for I := 0 to GetArrayLength(List) - 1 do
    begin
      GUserForm.ListBox.AddCheckBox(List[I].User, List[I].Caption, 0,
        List[I].Delete, True, False, False, TObject(I));
    end;

    {Show the form}
    GUserForm.Main.ShowModal();

    {Transfer checked items to Delete field}
    for I := 0 to GUserForm.ListBox.Items.Count - 1 do
    begin

      Index := Integer(GUserForm.ListBox.ItemObject[I]);
      List[Index].Delete := GUserForm.ListBox.Checked[I];

      if GUserForm.ListBox.Checked[I] then
        Result := True;

    end;

    if Result then
      Debug('User chose to delete data')
    else
      Debug('User chose not to delete data');

  finally
    GUserForm.Main.Free();
  end;

end;

procedure UserDataCreateForm(Status: Integer; var Form: TDataForm);
var
  Left: Integer;
  Width: Integer;
  Text: TNewStaticText;
  Checkbox: TNewCheckbox;
  OkButton: TButton;

begin

  Form.Main := CreateCustomForm();

  Form.Main.ClientWidth := ScaleX(380);
  Form.Main.ClientHeight := ScaleY(255);
  Form.Main.Caption := 'Delete User Data';
  Form.Main.CenterInsideControl(UninstallProgressForm, False);

  Left := ScaleX(20);
  Width := Form.Main.ClientWidth - (Left * 2);

  Text := TNewStaticText.Create(Form.Main);
  Text.Top := ScaleY(16);
  Text.Parent := Form.Main;
  Text.Left := Left;
  Text.Width := Width;
  Text.AutoSize := True;
  Text.WordWrap := True;
  Text.Caption := 'Please select the user data you want to delete.';

  Form.ListBox := TNewCheckListBox.Create(Form.Main);
  Form.ListBox.Top := Text.Top + Text.Height + ScaleY(10);
  Form.ListBox.Parent := Form.Main;
  Form.ListBox.Left := Left;
  Form.ListBox.Width := Width;
  Form.ListBox.Height := ScaleY(148);

  Checkbox := TNewCheckbox.Create(Form.Main);
  Checkbox.Top := Form.ListBox.Top + Form.ListBox.Height + ScaleY(6);
  Checkbox.Left := Left;
  Checkbox.Parent := Form.Main;
  Checkbox.Caption := 'Select All';
  Checkbox.Checked := Status = DELETE_ALL;
  Checkbox.OnClick := @UserCheckboxClick;

  OkButton := TButton.Create(Form.Main);
  OkButton.Parent := Form.Main;
  OkButton.Width := ScaleX(75);
  OkButton.Height := ScaleY(23);
  OkButton.Left := Form.Main.ClientWidth - (ScaleX(75) + Left);
  OkButton.Top := Form.Main.ClientHeight - ScaleY(23 + 16);
  OkButton.Caption := '&OK';
  OkButton.ModalResult := mrOk;
  OKButton.Default := True;

  Form.Main.ActiveControl := OkButton;

end;

procedure UserCheckboxClick(Sender: TObject);
var
  Checkbox: TNewCheckbox;
  I: Integer;

begin

  Checkbox := Sender as TNewCheckbox;

  for I := 0 to GUserForm.ListBox.Items.Count - 1 do
    GUserForm.ListBox.Checked[I] := Checkbox.Checked;

end;

function UserGetDelete: Integer;
var
  Param: String;

begin

  Result := DELETE_NONE;
  Param := ExpandConstant('{param:delete}');

  if CompareText(Param, 'local') = 0 then
    Result := DELETE_LOCAL
  else if CompareText(Param, 'all') = 0 then
    Result := DELETE_ALL;

end;


Make the built installer land in an existing directory.

; Basic setup script for the Inno Setep installer builder.  For more
; information on the free installer builder, see www.jrsoftware.org.
;
; This script was contributed by Tim Peters.

[Setup]
AppName=expat
AppId=expat
AppVersion=1.95.2
AppVerName=expat 1.95.2
AppCopyright=Copyright  1998-2001 Thai Open Source Software Center and Clark Cooper
DefaultDirName={sd}\Expat-1.95.2
AppPublisher=The Expat Developers
AppPublisherURL=http://expat.sourceforge.net/
AppSupportURL=http://expat.sourceforge.net/
AppUpdatesURL=http://expat.sourceforge.net/

CompressLevel=9
SourceDir=..
OutputDir=win32
DisableStartupPrompt=yes
AllowNoIcons=yes
DisableProgramGroupPage=yes
DisableReadyPage=yes

[Files]
Source: lib\*.c;             DestDir: "{app}\Source";  CopyMode: alwaysoverwrite
Source: lib\*.h;             DestDir: "{app}\Source";  CopyMode: alwaysoverwrite
Source: lib\*.dsp;           DestDir: "{app}\Source";  CopyMode: alwaysoverwrite
Source: lib\Release\*.dll;   DestDir: "{app}\Libs";    CopyMode: alwaysoverwrite
Source: lib\Release\*.lib;   DestDir: "{app}\Libs";    CopyMode: alwaysoverwrite
Source: doc\*.html;          DestDir: "{app}\Doc";     CopyMode: alwaysoverwrite
Source: doc\*.css;           DestDir: "{app}\Doc";     CopyMode: alwaysoverwrite
Source: xmlwf\Release\*.exe; DestDir: "{app}";         CopyMode: alwaysoverwrite
Source: win32\MANIFEST.txt;  DestDir: "{app}";         CopyMode: alwaysoverwrite
Source: COPYING;             DestDir: "{app}";         CopyMode: alwaysoverwrite; DestName: COPYING.txt
Source: README;              DestDir: "{app}";         CopyMode: alwaysoverwrite; DestName: README.txt

; Basic setup script for the Inno Setep installer builder.  For more
; information on the free installer builder, see www.jrsoftware.org.
;
; This script was contributed by Tim Peters.

[Setup]
AppName=expat
AppId=expat
AppVersion=1.95.2
AppVerName=expat 1.95.2
AppCopyright=Copyright  1998-2001 Thai Open Source Software Center and Clark Cooper
DefaultDirName={sd}\Expat-1.95.2
AppPublisher=The Expat Developers
AppPublisherURL=http://expat.sourceforge.net/
AppSupportURL=http://expat.sourceforge.net/
AppUpdatesURL=http://expat.sourceforge.net/
SourceDir=..

DisableStartupPrompt=yes
AllowNoIcons=yes
DisableProgramGroupPage=yes
DisableReadyPage=yes

[Files]
Source: lib\*.c;             DestDir: "{app}\Source";  CopyMode: alwaysoverwrite
Source: lib\*.h;             DestDir: "{app}\Source";  CopyMode: alwaysoverwrite
Source: lib\*.dsp;           DestDir: "{app}\Source";  CopyMode: alwaysoverwrite
Source: lib\Release\*.dll;   DestDir: "{app}\Libs";    CopyMode: alwaysoverwrite
Source: lib\Release\*.lib;   DestDir: "{app}\Libs";    CopyMode: alwaysoverwrite
Source: doc\*.html;          DestDir: "{app}\Doc";     CopyMode: alwaysoverwrite
Source: doc\*.css;           DestDir: "{app}\Doc";     CopyMode: alwaysoverwrite
Source: xmlwf\Release\*.exe; DestDir: "{app}";         CopyMode: alwaysoverwrite
Source: win32\MANIFEST.txt;  DestDir: "{app}";         CopyMode: alwaysoverwrite
Source: COPYING;             DestDir: "{app}";         CopyMode: alwaysoverwrite; DestName: COPYING.txt
Source: README;              DestDir: "{app}";         CopyMode: alwaysoverwrite; DestName: README.txt


Set WizardStyle=modern for InnoSetup

Set WizardStyle=modern for InnoSetup


Require at least XP SP3 in the installer.

This is a requirement of VS 2012's XP support.

;
;   This file is part of Poedit (http://www.poedit.net)
;
;   Copyright (C) 1999-2013 Vaclav Slavik
;
;   Permission is hereby granted, free of charge, to any person obtaining a
;   copy of this software and associated Docsumentation files (the "Software"),
;   to deal in the Software without restriction, including without limitation
;   the rights to use, copy, modify, merge, publish, distribute, sublicense,
;   and/or sell copies of the Software, and to permit persons to whom the
;   Software is furnished to do so, subject to the following conditions:
;
;   The above copyright notice and this permission notice shall be included in
;   all copies or substantial portions of the Software.
;
;   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
;   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;   DEALINGS IN THE SOFTWARE.
;
;   Inno Setup installer script
;

#define VERSION          "1.5.5"
#define VERSION_FULL     "1.5.5"

#ifndef CONFIG
#define Config           "Release"
#endif

#ifndef CRT_REDIST
#define CRT_REDIST       GetEnv("PROGRAMFILES") + "\Microsoft Visual Studio 11.0\VC\redist\x86\Microsoft.VC110.CRT"
#endif

[Setup]
OutputBaseFilename=Poedit-{#VERSION_FULL}-setup
AppName=Poedit
AppVerName=Poedit {#VERSION_FULL}

PrivilegesRequired=none
ChangesAssociations=true
AlwaysShowComponentsList=false
SourceDir=..
DefaultDirName={pf}\Poedit
DefaultGroupName=Poedit
AllowNoIcons=true
LicenseFile=COPYING
OutputDir={#CONFIG}
InfoAfterFile=
Compression=lzma2
WindowShowCaption=true
WindowStartMaximized=false
FlatComponentsList=true
WindowResizable=true
SolidCompression=true
ShowLanguageDialog=no
DisableWelcomePage=true
AllowUNCPath=true
InternalCompressLevel=ultra
AppID={{68EB2C37-083A-4303-B5D8-41FA67E50B8F}
VersionInfoVersion={#VERSION}
VersionInfoTextVersion={#VERSION_FULL}
AppCopyright= 1999-2013 Vaclav Slavik
AppPublisher=Vaclav Slavik
AppSupportURL=http://www.poedit.net/support.php
AppUpdatesURL=http://www.poedit.net/download.php
AppVersion={#VERSION_FULL}
AppContact=poedit@googlegroups.com
UninstallDisplayIcon={app}\bin\poedit.exe
UninstallDisplayName=Poedit
MinVersion=0,5.01.2600sp3
WizardSmallImageFile=icons\installer_wizard_image.bmp
AppPublisherURL=http://www.poedit.net/
DisableProgramGroupPage=true

#ifdef SIGNTOOL
SignTool={#SIGNTOOL}
#endif

[Files]
Source: {#CONFIG}\*.exe; DestDir: {app}; Flags: ignoreversion
Source: {#CONFIG}\*.dll; DestDir: {app}; Flags: ignoreversion
Source: deps\gettext\COPYING; DestDir: {app}\Docs; DestName: GNU_Gettext_COPYING.txt
Source: COPYING; DestDir: {app}\Docs; DestName: Copying.txt
Source: NEWS; DestDir: {app}\Docs; DestName: News.txt
Source: icons\mime-win32\xp\*.ico; DestDir: {app}\Resources; OnlyBelowVersion: 0,6.0.6000
Source: icons\mime-win32\vista\*.ico; DestDir: {app}\Resources; MinVersion: 0,6.0.6000
Source: {#CRT_REDIST}\*.dll; DestDir: {app}
Source: "{#CONFIG}\Resources\*"; DestDir: "{app}\Resources"; Flags: recursesubdirs
Source: "{#CONFIG}\Translations\*"; DestDir: "{app}\Translations"; Flags: recursesubdirs

[InstallDelete]
; delete files from previous versions that are no longer needed (and in case of
; poedit.exe.manifest, actually harmful):
Type: filesandordirs; Name: "{app}\bin"
Type: filesandordirs; Name: "{app}\doc"
Type: filesandordirs; Name: "{app}\share"

[Registry]
Root: HKCR; SubKey: .po; ValueType: string; ValueData: GettextFile; Flags: uninsdeletekey noerror
Root: HKCR; SubKey: GettextFile; ValueType: string; ValueData: Gettext message catalog; Flags: uninsdeletekey noerror
Root: HKCR; SubKey: GettextFile\Shell\Open\Command; ValueType: string; ValueData: """{app}\Poedit.exe"" ""%1"""; Flags: uninsdeletevalue noerror
Root: HKCR; Subkey: GettextFile\DefaultIcon; ValueType: string; ValueData: {app}\Resources\poedit-translation-generic.ico; Flags: uninsdeletekey noerror
Root: HKCU; Subkey: Software\Vaclav Slavik; Flags: uninsdeletekeyifempty dontcreatekey
Root: HKCU; Subkey: Software\Vaclav Slavik\poedit; Flags: uninsdeletekey dontcreatekey

[Icons]
Name: {commonprograms}\Poedit; Filename: {app}\Poedit.exe; WorkingDir: {app}; IconIndex: 0; Comment: Translate applications and other message catalogs.

[Run]
Filename: {app}\Poedit.exe; WorkingDir: {app}; Description: Open Poedit after installation; Flags: postinstall nowait skipifsilent runasoriginaluser

[_ISTool]
UseAbsolutePaths=false

[Dirs]
Name: {app}\Docs
Name: {app}\Resources
Name: {app}\Translations

[Messages]
BeveledLabel=http://www.poedit.net

[ThirdParty]
CompileLogMethod=append

;
;   This file is part of Poedit (http://www.poedit.net)
;
;   Copyright (C) 1999-2013 Vaclav Slavik
;
;   Permission is hereby granted, free of charge, to any person obtaining a
;   copy of this software and associated Docsumentation files (the "Software"),
;   to deal in the Software without restriction, including without limitation
;   the rights to use, copy, modify, merge, publish, distribute, sublicense,
;   and/or sell copies of the Software, and to permit persons to whom the
;   Software is furnished to do so, subject to the following conditions:
;
;   The above copyright notice and this permission notice shall be included in
;   all copies or substantial portions of the Software.
;
;   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
;   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;   DEALINGS IN THE SOFTWARE.
;
;   Inno Setup installer script
;

#define VERSION          "1.5.5"
#define VERSION_FULL     "1.5.5"

#ifndef CONFIG
#define Config           "Release"
#endif

#ifndef CRT_REDIST
#define CRT_REDIST       GetEnv("PROGRAMFILES") + "\Microsoft Visual Studio 11.0\VC\redist\x86\Microsoft.VC110.CRT"
#endif

[Setup]
OutputBaseFilename=Poedit-{#VERSION_FULL}-setup
AppName=Poedit
AppVerName=Poedit {#VERSION_FULL}

PrivilegesRequired=none
ChangesAssociations=true
AlwaysShowComponentsList=false
SourceDir=..
DefaultDirName={pf}\Poedit
DefaultGroupName=Poedit
AllowNoIcons=true
LicenseFile=COPYING
OutputDir={#CONFIG}
InfoAfterFile=
Compression=lzma2
WindowShowCaption=true
WindowStartMaximized=false
FlatComponentsList=true
WindowResizable=true
SolidCompression=true
ShowLanguageDialog=no
DisableWelcomePage=true
AllowUNCPath=true
InternalCompressLevel=ultra
AppID={{68EB2C37-083A-4303-B5D8-41FA67E50B8F}
VersionInfoVersion={#VERSION}
VersionInfoTextVersion={#VERSION_FULL}
AppCopyright= 1999-2013 Vaclav Slavik
AppPublisher=Vaclav Slavik
AppSupportURL=http://www.poedit.net/support.php
AppUpdatesURL=http://www.poedit.net/download.php
AppVersion={#VERSION_FULL}
AppContact=poedit@googlegroups.com
UninstallDisplayIcon={app}\bin\poedit.exe
UninstallDisplayName=Poedit
MinVersion=0,5.0.2195
WizardSmallImageFile=icons\installer_wizard_image.bmp
AppPublisherURL=http://www.poedit.net/
DisableProgramGroupPage=true

#ifdef SIGNTOOL
SignTool={#SIGNTOOL}
#endif

[Files]
Source: {#CONFIG}\*.exe; DestDir: {app}; Flags: ignoreversion
Source: {#CONFIG}\*.dll; DestDir: {app}; Flags: ignoreversion
Source: deps\gettext\COPYING; DestDir: {app}\Docs; DestName: GNU_Gettext_COPYING.txt
Source: COPYING; DestDir: {app}\Docs; DestName: Copying.txt
Source: NEWS; DestDir: {app}\Docs; DestName: News.txt
Source: icons\mime-win32\xp\*.ico; DestDir: {app}\Resources; OnlyBelowVersion: 0,6.0.6000
Source: icons\mime-win32\vista\*.ico; DestDir: {app}\Resources; MinVersion: 0,6.0.6000
Source: {#CRT_REDIST}\*.dll; DestDir: {app}
Source: "{#CONFIG}\Resources\*"; DestDir: "{app}\Resources"; Flags: recursesubdirs
Source: "{#CONFIG}\Translations\*"; DestDir: "{app}\Translations"; Flags: recursesubdirs

[InstallDelete]
; delete files from previous versions that are no longer needed (and in case of
; poedit.exe.manifest, actually harmful):
Type: filesandordirs; Name: "{app}\bin"
Type: filesandordirs; Name: "{app}\doc"
Type: filesandordirs; Name: "{app}\share"

[Registry]
Root: HKCR; SubKey: .po; ValueType: string; ValueData: GettextFile; Flags: uninsdeletekey noerror
Root: HKCR; SubKey: GettextFile; ValueType: string; ValueData: Gettext message catalog; Flags: uninsdeletekey noerror
Root: HKCR; SubKey: GettextFile\Shell\Open\Command; ValueType: string; ValueData: """{app}\Poedit.exe"" ""%1"""; Flags: uninsdeletevalue noerror
Root: HKCR; Subkey: GettextFile\DefaultIcon; ValueType: string; ValueData: {app}\Resources\poedit-translation-generic.ico; Flags: uninsdeletekey noerror
Root: HKCU; Subkey: Software\Vaclav Slavik; Flags: uninsdeletekeyifempty dontcreatekey
Root: HKCU; Subkey: Software\Vaclav Slavik\poedit; Flags: uninsdeletekey dontcreatekey

[Icons]
Name: {commonprograms}\Poedit; Filename: {app}\Poedit.exe; WorkingDir: {app}; IconIndex: 0; Comment: Translate applications and other message catalogs.

[Run]
Filename: {app}\Poedit.exe; WorkingDir: {app}; Description: Open Poedit after installation; Flags: postinstall nowait skipifsilent runasoriginaluser

[_ISTool]
UseAbsolutePaths=false

[Dirs]
Name: {app}\Docs
Name: {app}\Resources
Name: {app}\Translations

[Messages]
BeveledLabel=http://www.poedit.net

[ThirdParty]
CompileLogMethod=append


Update inno installer scripts (version)

Update inno installer scripts (version)

; Script generated by the Inno Setup Script Wizard.
; Script was modified to include drivers silent install by madnerd.org
; By madnerd.org , Licence MIT
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "LibreConnect"
#define MyAppVersion "1.0"
#define MyAppPublisher "madnerd.org"
#define MyAppURL "http://github.com/madnerdorg/libreconnect"
#define MyAppExeName "usb_scanner.exe"

;CHANGE PATHS before compiling!
#define APP "E:\user\Google Drive\MADNERD\github\libreconnect\dist"
#define DRIVERS "c:\nano"

[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={{4053C9DE-794C-42AE-AD80-40C2C4CB27B8}}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DisableProgramGroupPage=yes
OutputBaseFilename=libreconnect_setup
Compression=lzma
SolidCompression=yes

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

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

[Files]
Source: "{#APP}\usb_scanner.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#APP}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "{#DRIVERS}\*"; DestDir: "{app}\nano"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

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

[Run]
;Silent install for arduino nano ch340g drivers
Filename: {app}\nano\setup.exe; Parameters: "/s"; WorkingDir: {app}\nano;
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

; Script generated by the Inno Setup Script Wizard.
; Script was modified to include drivers silent install by madnerd.org
; By madnerd.org , Licence MIT
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "LibreConnect"
#define MyAppVersion "97f9aff"
#define MyAppPublisher "madnerd.org"
#define MyAppURL "http://github.com/madnerdorg/libreconnect"
#define MyAppExeName "usb_scanner.exe"

;CHANGE PATHS before compiling!
#define APP "E:\user\Downloads\libreconnect"
#define DRIVERS "c:\nano"

[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={{64DDC058-59CF-4CE8-9250-FC22260FAA12}}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DisableProgramGroupPage=yes
OutputBaseFilename=libreconnect_setup
Compression=lzma
SolidCompression=yes

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

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

[Files]
Source: "{#APP}\usb_scanner.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#APP}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "{#DRIVERS}\*"; DestDir: "{app}\nano"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

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

[Run]
;Silent install for arduino nano ch340g drivers
Filename: {app}\nano\setup.exe; Parameters: "/s"; WorkingDir: {app}\nano;
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent


same again

same again

;
;          _\|/_
;          (o o)
; +-----oOO-{_}-OOo------------------------------------------------------+
; |                                                                      |
; |  Unknown-Horizons - Inno Setup Script File                           |
; |  -------------------------------------------------------             |
; |                                                                      |
; |  Author:   Jens A. Koch <jakoch@web.de>                              |
; |  Author:   Thomas Kowaliczek-Schmer <thomas.kowaliczek@posteo.de>    |
; |  License:  MIT                                                       |
; |                                                                      |
; |  For the full copyright and license information, please view         |
; |  the LICENSE file that was distributed with this source code.        |
; |                                                                      |
; |  Note for developers                                                 |
; |  -------------------                                                 |
; |  A good resource for developing and understanding                    |
; |  Inno Setup Script files is the official "Inno Setup Help".          |
; |  Website:  http://jrsoftware.org/ishelp/index.php                    |
; |                                                                      |
; +---------------------------------------------------------------------<3

; version is set here, when the version isn't passed to the compiler on invocation
#ifndef APP_VERSION
#define APP_VERSION          "2019.1"
#endif

#define APP_NAME             "Unknown-Horizons"
#define APP_COMPILER         "VC15"
#define APP_PUBLISHER        "Unknown-Horizons Team"
#define APP_URL              "http://www.unknown-horizons.org/"
#define APP_SUPPORT_URL      "https://github.com/unknown-horizons/unknown-horizons/issues"
#define COPYRIGHT_YEAR        GetDateTimeString('yyyy', '', '');

[Setup]
AppId={{797B9070-BD1B-4DD9-8434-3A02697F9984}

; set application meta-data
AppName={#APP_NAME}
AppVerName={#APP_NAME} {#APP_VERSION}
AppVersion={#APP_VERSION}
AppCopyright=© {#APP_PUBLISHER}
AppPublisher={#APP_PUBLISHER}
AppPublisherURL={#APP_URL}
AppSupportURL={#APP_SUPPORT_URL}
AppUpdatesURL={#APP_URL}
UninstallDisplayIcon={app}\unknown-horizons\content\gfx\uh.ico
UninstallDisplayName={#APP_NAME}

; default installation folder is "C:\Unknown-Horizons". users might change this via dialog.
DefaultDirName=C:\Unknown-Horizons
DefaultGroupName={#APP_NAME}
DirExistsWarning=No
EnableDirDoesntExistWarning=Yes
AllowNoIcons=yes

; compression
Compression=lzma2/ultra
LZMAUseSeparateProcess=yes
LZMANumBlockThreads=2
InternalCompressLevel=max
SolidCompression=true

; style
WizardImageFile=images\WizardImage.bmp
WizardSmallImageFile=images\WizardSmallImage.bmp
SetupIconFile=images\uh.ico

; this creates the installer executable in the build folder
; for example: "_build\Unknown-Horizons-2019.1-Setup-VC15-x86.exe"
OutputBaseFilename={#APP_NAME}-{#APP_VERSION}-Setup-{#APP_COMPILER}-x86
OutputDir=..\_build

; disable wizard pages: Welcome (by default), Ready
DisableReadyPage=yes

; enable wizard pages: Select Destination Location
DisableDirPage=no

; Tell Windows to reload the environment, because Registry change (env PATH change)
ChangesEnvironment=yes

; Logging
SetupLogging=yes

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

; Define the types of installations
; The user gets a drop-down list to select one of these types.
; Selecting a type will selected a set of components.
[Types]
Name: "full";          Description: "Full installation (game and engine)"
Name: "custom";        Description: "Custom installation"; Flags: iscustom

; Define components to install
[Components]
Name: "unknown_horizons"; Description: "[unknown-horizons] Unknown-Horizons";              Types: full
Name: vcredist2015;       Description: "[dep libs] VCRedist2015";                          Types: full

[Files]
Source: "..\repackage\unknown-horizons\*";      DestDir: "{app}\unknown-horizons";      Flags: recursesubdirs ignoreversion; Components: unknown_horizons
Source: "..\repackage\Python36\*";              DestDir: "{app}\python";                Flags: recursesubdirs ignoreversion; Components: unknown_horizons
Source: "..\repackage\vc_redist.x86.exe";       DestDir: "{tmp}";                       Flags: deleteafterinstall;           Components: unknown_horizons

[Tasks]
Name: add_startmenu;       Description: Create Startmenu entries;                         Components: unknown_horizons
Name: add_quicklaunchicon; Description: Create a &Quick Launch icon for Unknown Horizons; GroupDescription: Additional Icons:; Components: unknown_horizons
Name: add_desktopicon;     Description: Create a &Desktop icon for Unknown Horizons;      GroupDescription: Additional Icons:; Components: unknown_horizons

[Icons]
; define a group for the startmenu
Name: {group}\Start Unknown-Horizons; Filename: {app}\unknown-horizons\run_uh.bat; IconFilename: "{app}\unknown-horizons\content\gfx\uh.ico"; Tasks: add_startmenu
Name: {group}\Start Unknown-Horizons Debug; Filename: {app}\unknown-horizons\run_uh.bat; Parameters: "--debug"; IconFilename: "{app}\unknown-horizons\content\gfx\uh.ico"; Tasks: add_startmenu
Name: {group}\Uninstall Unknown-Horizons; Filename: "{uninstallexe}"; Tasks: add_startmenu
; desktop icon
Name: {userdesktop}\Unknown-Horizons; Filename: {app}\unknown-horizons\run_uh.bat; IconFilename: "{app}\unknown-horizons\content\gfx\uh.ico"; Tasks: add_desktopicon
; quick launch icon
Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Unknown Horizons; Filename: {app}\run_uh.bat; IconFilename: "{app}\unknown-horizons\content\gfx\uh.ico"; Tasks: add_quicklaunchicon

; Define items to run automatically on installation...
[Run]
; add the Parameters, WorkingDir and StatusMsg as you wish, just keep here
; the conditional installation Check
Filename: "{tmp}\vc_redist.x86.exe"; Parameters: "/q /norestart"; Check: VCRedistNeedsInstall; StatusMsg: "Installing VC++ redistributables..."

[UninstallDelete]
;Type: filesandordirs; Name: "{userdocs}\My Games\unknown-horizons"
Type: filesandordirs; Name: "{app}\python"
Type: filesandordirs; Name: "{app}\unknown-horizons"

[Registry]
; A registry change needs the following directive: [SETUP] ChangesEnvironment=yes
; add path to fife (because libpng16-16.dll and other dependencies needs to be found)
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType:string; ValueName:"PATH"; ValueData:"{olddata};{app}\python\Lib\site-packages\fife"; Flags: preservestringtype; Check: NeedsAddPathLocalMachine(ExpandConstant('{app}\python\Lib\site-packages\fife')); Components: unknown_horizons

[Code]
// modification and path lookup helper for env PATH
#include "includes\envpath.iss"

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  // Removing a path from the PATH variable works in 3 steps:
  // 1. get the old env var PATH
  if (CurUninstallStep =  usUninstall) then
  begin
    SaveOldPathLocalMachine();
  end;
  // 2. remove paths from the env var PATH
  if (CurUninstallStep = usPostUninstall) then
  begin
    RemovePathLocalMachine(ExpandConstant('{app}') + '\python\Lib\site-packages\fife');
    // 3. refresh environment, so that the modified PATH var is activated
    RefreshEnvironment();
  end;
end;

#IFDEF UNICODE
  #DEFINE AW "W"
#ELSE
  #DEFINE AW "A"
#ENDIF
type
  INSTALLSTATE = Longint;
const
  INSTALLSTATE_INVALIDARG = -2;  { An invalid parameter was passed to the function. }
  INSTALLSTATE_UNKNOWN = -1;     { The product is neither advertised or installed. }
  INSTALLSTATE_ADVERTISED = 1;   { The product is advertised but not installed. }
  INSTALLSTATE_ABSENT = 2;       { The product is installed for a different user. }
  INSTALLSTATE_DEFAULT = 5;      { The product is installed for the current user. }

  // Visual C++ 2015 Redistributable 14.0.24215.1
  VC_2015_REDIST_X86 = '{e2803110-78b3-4664-a479-3611a381656a}';
//  VC_2015_REDIST_X64 = '{d992c12e-cab2-426f-bde3-fb8c53950b0d}';

function MsiQueryProductState(szProduct: string): INSTALLSTATE;
  external 'MsiQueryProductState{#AW}@msi.dll stdcall';

function VCVersionInstalled(const ProductID: string): Boolean;
begin
  Result := MsiQueryProductState(ProductID) = INSTALLSTATE_DEFAULT;
end;

function VCRedistNeedsInstall: Boolean;
begin
  Result := not (VCVersionInstalled(VC_2015_REDIST_X86));
end;

;
;          _\|/_
;          (o o)
; +-----oOO-{_}-OOo------------------------------------------------------+
; |                                                                      |
; |  Unknown-Horizons - Inno Setup Script File                           |
; |  -------------------------------------------------------             |
; |                                                                      |
; |  Author:   Jens A. Koch <jakoch@web.de>                              |
; |  Author:   Thomas Kowaliczek-Schmer <thomas.kowaliczek@posteo.de>    |
; |  License:  MIT                                                       |
; |                                                                      |
; |  For the full copyright and license information, please view         |
; |  the LICENSE file that was distributed with this source code.        |
; |                                                                      |
; |  Note for developers                                                 |
; |  -------------------                                                 |
; |  A good resource for developing and understanding                    |
; |  Inno Setup Script files is the official "Inno Setup Help".          |
; |  Website:  http://jrsoftware.org/ishelp/index.php                    |
; |                                                                      |
; +---------------------------------------------------------------------<3

; version is set here, when the version isn't passed to the compiler on invocation
#ifndef APP_VERSION
#define APP_VERSION          "2019.1"
#endif

#define APP_NAME             "Unknown-Horizons"
#define APP_COMPILER         "VC14"
#define APP_PUBLISHER        "Unknown-Horizons Team"
#define APP_URL              "http://www.unknown-horizons.org/"
#define APP_SUPPORT_URL      "https://github.com/unknown-horizons/unknown-horizons/issues"
#define COPYRIGHT_YEAR        GetDateTimeString('yyyy', '', '');

[Setup]
AppId={{797B9070-BD1B-4DD9-8434-3A02697F9984}

; set application meta-data
AppName={#APP_NAME}
AppVerName={#APP_NAME} {#APP_VERSION}
AppVersion={#APP_VERSION}
AppCopyright=© {#APP_PUBLISHER}
AppPublisher={#APP_PUBLISHER}
AppPublisherURL={#APP_URL}
AppSupportURL={#APP_SUPPORT_URL}
AppUpdatesURL={#APP_URL}
UninstallDisplayIcon={app}\unknown-horizons\content\gfx\uh.ico
UninstallDisplayName={#APP_NAME}

; default installation folder is "C:\Unknown-Horizons". users might change this via dialog.
DefaultDirName=C:\Unknown-Horizons
DefaultGroupName={#APP_NAME}
DirExistsWarning=No
EnableDirDoesntExistWarning=Yes
AllowNoIcons=yes

; compression
Compression=lzma2/ultra
LZMAUseSeparateProcess=yes
LZMANumBlockThreads=2
InternalCompressLevel=max
SolidCompression=true

; style
WizardImageFile=images\WizardImage.bmp
WizardSmallImageFile=images\WizardSmallImage.bmp
SetupIconFile=images\uh.ico

; this creates the installer executable in the build folder
; for example: "_build\Unknown-Horizons-2019.1-Setup-VC15-x86.exe"
OutputBaseFilename={#APP_NAME}-{#APP_VERSION}-Setup-{#APP_COMPILER}-x86
OutputDir=..\_build

; disable wizard pages: Welcome (by default), Ready
DisableReadyPage=yes

; enable wizard pages: Select Destination Location
DisableDirPage=no

; Tell Windows to reload the environment, because Registry change (env PATH change)
ChangesEnvironment=yes

; Logging
SetupLogging=yes

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

; Define the types of installations
; The user gets a drop-down list to select one of these types.
; Selecting a type will selected a set of components.
[Types]
Name: "full";          Description: "Full installation (game and engine)"
Name: "custom";        Description: "Custom installation"; Flags: iscustom

; Define components to install
[Components]
Name: "unknown_horizons"; Description: "[unknown-horizons] Unknown-Horizons";              Types: full
Name: vcredist2015;       Description: "[dep libs] VCRedist2015";                          Types: full

[Files]
Source: "..\repackage\unknown-horizons\*";      DestDir: "{app}\unknown-horizons";      Flags: recursesubdirs ignoreversion; Components: unknown_horizons
Source: "..\repackage\Python27\*";              DestDir: "{app}\python";                Flags: recursesubdirs ignoreversion; Components: unknown_horizons
Source: "..\repackage\vc_redist.x86.exe";       DestDir: "{tmp}";                       Flags: deleteafterinstall;           Components: unknown_horizons

[Tasks]
Name: add_startmenu;       Description: Create Startmenu entries;                         Components: unknown_horizons
Name: add_quicklaunchicon; Description: Create a &Quick Launch icon for Unknown Horizons; GroupDescription: Additional Icons:; Components: unknown_horizons
Name: add_desktopicon;     Description: Create a &Desktop icon for Unknown Horizons;      GroupDescription: Additional Icons:; Components: unknown_horizons

[Icons]
; define a group for the startmenu
Name: {group}\Start Unknown-Horizons; Filename: {app}\unknown-horizons\run_uh.bat; IconFilename: "{app}\unknown-horizons\content\gfx\uh.ico"; Tasks: add_startmenu
Name: {group}\Start Unknown-Horizons Debug; Filename: {app}\unknown-horizons\run_uh.bat; Parameters: "--debug"; IconFilename: "{app}\unknown-horizons\content\gfx\uh.ico"; Tasks: add_startmenu
Name: {group}\Uninstall Unknown-Horizons; Filename: "{uninstallexe}"; Tasks: add_startmenu
; desktop icon
Name: {userdesktop}\Unknown-Horizons; Filename: {app}\unknown-horizons\run_uh.bat; IconFilename: "{app}\unknown-horizons\content\gfx\uh.ico"; Tasks: add_desktopicon
; quick launch icon
Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\Unknown Horizons; Filename: {app}\run_uh.bat; IconFilename: "{app}\unknown-horizons\content\gfx\uh.ico"; Tasks: add_quicklaunchicon

; Define items to run automatically on installation...
[Run]
; add the Parameters, WorkingDir and StatusMsg as you wish, just keep here
; the conditional installation Check
Filename: "{tmp}\vc_redist.x86.exe"; Parameters: "/q /norestart"; Check: VCRedistNeedsInstall; StatusMsg: "Installing VC++ redistributables..."

[UninstallDelete]
;Type: filesandordirs; Name: "{userdocs}\My Games\unknown-horizons"
Type: filesandordirs; Name: "{app}\python"
Type: filesandordirs; Name: "{app}\unknown-horizons"

[Registry]
; A registry change needs the following directive: [SETUP] ChangesEnvironment=yes
; add path to fife (because libpng16-16.dll and other dependencies needs to be found)
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType:string; ValueName:"PATH"; ValueData:"{olddata};{app}\python\Lib\site-packages\fife"; Flags: preservestringtype; Check: NeedsAddPathLocalMachine(ExpandConstant('{app}\python\Lib\site-packages\fife')); Components: unknown_horizons

[Code]
// modification and path lookup helper for env PATH
#include "includes\envpath.iss"

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  // Removing a path from the PATH variable works in 3 steps:
  // 1. get the old env var PATH
  if (CurUninstallStep =  usUninstall) then
  begin
    SaveOldPathLocalMachine();
  end;
  // 2. remove paths from the env var PATH
  if (CurUninstallStep = usPostUninstall) then
  begin
    RemovePathLocalMachine(ExpandConstant('{app}') + '\python\Lib\site-packages\fife');
    // 3. refresh environment, so that the modified PATH var is activated
    RefreshEnvironment();
  end;
end;

#IFDEF UNICODE
  #DEFINE AW "W"
#ELSE
  #DEFINE AW "A"
#ENDIF
type
  INSTALLSTATE = Longint;
const
  INSTALLSTATE_INVALIDARG = -2;  { An invalid parameter was passed to the function. }
  INSTALLSTATE_UNKNOWN = -1;     { The product is neither advertised or installed. }
  INSTALLSTATE_ADVERTISED = 1;   { The product is advertised but not installed. }
  INSTALLSTATE_ABSENT = 2;       { The product is installed for a different user. }
  INSTALLSTATE_DEFAULT = 5;      { The product is installed for the current user. }

  // Visual C++ 2015 Redistributable 14.0.24215.1
  VC_2015_REDIST_X86 = '{e2803110-78b3-4664-a479-3611a381656a}';
//  VC_2015_REDIST_X64 = '{d992c12e-cab2-426f-bde3-fb8c53950b0d}';

function MsiQueryProductState(szProduct: string): INSTALLSTATE;
  external 'MsiQueryProductState{#AW}@msi.dll stdcall';

function VCVersionInstalled(const ProductID: string): Boolean;
begin
  Result := MsiQueryProductState(ProductID) = INSTALLSTATE_DEFAULT;
end;

function VCRedistNeedsInstall: Boolean;
begin
  Result := not (VCVersionInstalled(VC_2015_REDIST_X86));
end;


Fix UTF-8 encoding

Fix UTF-8 encoding

#define MyAppName "Gmail Notifier"
#define MyAppVersion "1.0.3.0"
#define MyAppPublisher "Xavier Foucrier"
#define MyAppURL "https://github.com/xavierfoucrier/gmail-notifier"
#define MyAppExeName "Gmail notifier.exe"

[Setup]
AppId={{7E60E047-C79B-49A4-8CF6-B33D5565B2E8}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppCopyright=Copyright  2016
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile=..\LICENSE.md
OutputDir=..\setup
ArchitecturesInstallIn64BitMode=x64
OutputBaseFilename=Gmail Notifier setup
Compression=lzma
SolidCompression=yes

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1

[Files]
Source: "..\Gmail notifier\bin\Release 32 bits (x86)\Gmail notifier.exe"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "..\Gmail notifier\bin\Release 32 bits (x86)\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Check: not Is64BitInstallMode
Source: "..\Gmail notifier\bin\Release 64 bits (x64)\Gmail notifier.exe"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "..\Gmail notifier\bin\Release 64 bits (x64)\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Check: Is64BitInstallMode

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

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

#define MyAppName "Gmail Notifier"
#define MyAppVersion "1.0.3.0"
#define MyAppPublisher "Xavier Foucrier"
#define MyAppURL "https://github.com/xavierfoucrier/gmail-notifier"
#define MyAppExeName "Gmail notifier.exe"

[Setup]
AppId={{7E60E047-C79B-49A4-8CF6-B33D5565B2E8}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppCopyright=Copyright © 2016
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
LicenseFile=..\LICENSE.md
OutputDir=..\setup
ArchitecturesInstallIn64BitMode=x64
OutputBaseFilename=Gmail Notifier setup
Compression=lzma
SolidCompression=yes

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1

[Files]
Source: "..\Gmail notifier\bin\Release 32 bits (x86)\Gmail notifier.exe"; DestDir: "{app}"; Flags: ignoreversion; Check: not Is64BitInstallMode
Source: "..\Gmail notifier\bin\Release 32 bits (x86)\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Check: not Is64BitInstallMode
Source: "..\Gmail notifier\bin\Release 64 bits (x64)\Gmail notifier.exe"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitInstallMode
Source: "..\Gmail notifier\bin\Release 64 bits (x64)\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Check: Is64BitInstallMode

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

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