Browse Source

Merge pull request #77 from PixiEditor/master

0.1.3.2 Installer update
Krzysztof Krysiński 4 years ago
parent
commit
4cff6db8f4
70 changed files with 2063 additions and 284 deletions
  1. 68 7
      Installer/installer-setup-x64-light.iss
  2. 0 63
      Installer/installer-setup-x64.iss
  3. 69 8
      Installer/installer-setup-x86-light.iss
  4. 0 63
      Installer/installer-setup-x86.iss
  5. 49 0
      Installer/scripts/isxdl/chinese.ini
  6. 53 0
      Installer/scripts/isxdl/czech.ini
  7. 49 0
      Installer/scripts/isxdl/dutch.ini
  8. 49 0
      Installer/scripts/isxdl/english.ini
  9. 45 0
      Installer/scripts/isxdl/french.ini
  10. 45 0
      Installer/scripts/isxdl/french2.ini
  11. 46 0
      Installer/scripts/isxdl/french3.ini
  12. 49 0
      Installer/scripts/isxdl/german.ini
  13. BIN
      Installer/scripts/isxdl/isxdl.dll
  14. 12 0
      Installer/scripts/isxdl/isxdl.iss
  15. 49 0
      Installer/scripts/isxdl/italian.ini
  16. 49 0
      Installer/scripts/isxdl/japanese.ini
  17. 49 0
      Installer/scripts/isxdl/korean.ini
  18. 47 0
      Installer/scripts/isxdl/norwegian.ini
  19. 45 0
      Installer/scripts/isxdl/polish.ini
  20. 45 0
      Installer/scripts/isxdl/portugues.ini
  21. 46 0
      Installer/scripts/isxdl/portuguese.ini
  22. 49 0
      Installer/scripts/isxdl/russian.ini
  23. 46 0
      Installer/scripts/isxdl/spanish.ini
  24. 48 0
      Installer/scripts/isxdl/swedish.ini
  25. 18 0
      Installer/scripts/lang/chinese.iss
  26. 18 0
      Installer/scripts/lang/dutch.iss
  27. 15 0
      Installer/scripts/lang/english.iss
  28. 18 0
      Installer/scripts/lang/french.iss
  29. 18 0
      Installer/scripts/lang/german.iss
  30. 18 0
      Installer/scripts/lang/italian.iss
  31. 18 0
      Installer/scripts/lang/japanese.iss
  32. 18 0
      Installer/scripts/lang/polish.iss
  33. 18 0
      Installer/scripts/lang/russian.iss
  34. 4 0
      Installer/scripts/products.iss
  35. 324 0
      Installer/scripts/products.pas
  36. 92 0
      Installer/scripts/products/dotnetfxversion.iss
  37. 27 0
      Installer/scripts/products/netcore31.iss
  38. 27 0
      Installer/scripts/products/netcore31desktop.iss
  39. 32 0
      Installer/scripts/products/netcorecheck.iss
  40. 60 0
      Installer/scripts/products/stringversion.iss
  41. 47 0
      Installer/scripts/products/winversion.iss
  42. BIN
      Installer/src/netcorecheck.exe
  43. BIN
      Installer/src/netcorecheck_x64.exe
  44. 1 0
      PixiEditor.UpdateInstaller/PixiEditor.UpdateInstaller.csproj
  45. 5 4
      PixiEditor.UpdateInstaller/ViewModelMain.cs
  46. 76 0
      PixiEditor.UpdateInstaller/app.manifest
  47. 11 3
      PixiEditor.UpdateModule/UpdateDownloader.cs
  48. 9 5
      PixiEditor.UpdateModule/UpdateInstaller.cs
  49. 4 4
      PixiEditor/Models/Controllers/BitmapManager.cs
  50. 25 0
      PixiEditor/Models/Processes/ProcessHelper.cs
  51. 2 2
      PixiEditor/Models/Tools/ToolSettings/Settings/BoolSetting.cs
  52. 1 1
      PixiEditor/Models/Tools/ToolSettings/Settings/ColorSetting.cs
  53. 1 1
      PixiEditor/Models/Tools/ToolSettings/Settings/DropdownSetting.cs
  54. 1 1
      PixiEditor/Models/Tools/ToolSettings/Settings/FloatSetting.cs
  55. 19 8
      PixiEditor/Models/Tools/ToolSettings/Settings/Setting.cs
  56. 2 2
      PixiEditor/Models/Tools/ToolSettings/Settings/SizeSetting.cs
  57. 30 8
      PixiEditor/Models/Tools/ToolSettings/Toolbars/Toolbar.cs
  58. 4 4
      PixiEditor/Models/Tools/Tools/BrightnessTool.cs
  59. 4 5
      PixiEditor/Models/Tools/Tools/CircleTool.cs
  60. 2 2
      PixiEditor/Models/Tools/Tools/EraserTool.cs
  61. 3 4
      PixiEditor/Models/Tools/Tools/LineTool.cs
  62. 4 5
      PixiEditor/Models/Tools/Tools/PenTool.cs
  63. 4 3
      PixiEditor/Models/Tools/Tools/RectangleTool.cs
  64. 2 2
      PixiEditor/Models/Tools/Tools/SelectTool.cs
  65. 2 2
      PixiEditor/Properties/AssemblyInfo.cs
  66. 13 3
      PixiEditor/ViewModels/ViewModelMain.cs
  67. 16 4
      PixiEditor/Views/MainWindow.xaml.cs
  68. 41 8
      PixiEditorTests/ModelsTests/ToolsTests/ToolbarTests/ToolbarBaseTests.cs
  69. 1 31
      windows-x64-release.yml
  70. 1 31
      windows-x86-release.yml

+ 68 - 7
Installer/installer-setup-x64-light.iss

@@ -1,5 +1,5 @@
-; Script generated by the Inno Setup Script Wizard.
-; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+// contribute: https://github.com/domgho/InnoDependencyInstaller
+// official article: https://www.codeproject.com/Articles/20868/Inno-Setup-Dependency-Installer
 
 
 #define MyAppName "PixiEditor"
 #define MyAppName "PixiEditor"
 #define MyAppVersion GetFileVersion("..\Builds\PixiEditor-x64-light\PixiEditor\PixiEditor.exe")     ;Not perfect solution, it's enviroment dependend
 #define MyAppVersion GetFileVersion("..\Builds\PixiEditor-x64-light\PixiEditor\PixiEditor.exe")     ;Not perfect solution, it's enviroment dependend
@@ -28,16 +28,59 @@ LicenseFile=..\LICENSE
 ; Uncomment the following line to run in non administrative install mode (install for current user only.)
 ; Uncomment the following line to run in non administrative install mode (install for current user only.)
 ;PrivilegesRequired=lowest
 ;PrivilegesRequired=lowest
 OutputDir=Assets\PixiEditor-{#TargetPlatform}
 OutputDir=Assets\PixiEditor-{#TargetPlatform}
-OutputBaseFilename=PixiEditor-{#MyAppVersion}-setup-{#TargetPlatform}
+OutputBaseFilename=PixiEditor-{#MyAppVersion}-setup-x64
 SetupIconFile=..\icon.ico
 SetupIconFile=..\icon.ico
 Compression=lzma
 Compression=lzma
 SolidCompression=yes
 SolidCompression=yes
 WizardStyle=modern
 WizardStyle=modern
 ChangesAssociations = yes
 ChangesAssociations = yes
 
 
-[Languages]
-Name: "english"; MessagesFile: "compiler:Default.isl"
+PrivilegesRequired=admin
+ArchitecturesAllowed=x86 x64 ia64
+ArchitecturesInstallIn64BitMode=x64 ia64
 
 
+// downloading and installing dependencies will only work if the memo/ready page is enabled (default and current behaviour)
+DisableReadyPage=no
+DisableReadyMemo=no
+
+// requires netcorecheck.exe and netcorecheck_x64.exe in src dir
+#define use_netcorecheck
+#define use_netcore31
+#define use_netcore31desktop
+// supported languages
+#include "scripts\lang\english.iss"
+#include "scripts\lang\german.iss"
+#include "scripts\lang\french.iss"
+#include "scripts\lang\italian.iss"
+#include "scripts\lang\dutch.iss"
+
+#ifdef UNICODE
+#include "scripts\lang\chinese.iss"
+#include "scripts\lang\polish.iss"
+#include "scripts\lang\russian.iss"
+#include "scripts\lang\japanese.iss"
+#endif
+
+// shared code for installing the products
+#include "scripts\products.iss"
+
+// helper functions
+#include "scripts\products\stringversion.iss"
+#include "scripts\products\winversion.iss"
+#include "scripts\products\dotnetfxversion.iss"
+
+#ifdef use_netcorecheck
+#include "scripts\products\netcorecheck.iss"
+#endif
+#ifdef use_netcore31
+#include "scripts\products\netcore31.iss"
+#endif
+#ifdef use_netcore31desktop
+#include "scripts\products\netcore31desktop.iss"
+#endif
+
+// content
+[Tasks]
 [Tasks]
 [Tasks]
 Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
 Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
 Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode
 Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode
@@ -45,7 +88,6 @@ Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescrip
 [Files]
 [Files]
 Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\PixiEditor.exe"; DestDir: "{app}"; Flags: ignoreversion
 Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\PixiEditor.exe"; DestDir: "{app}"; Flags: ignoreversion
 Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
 Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
-; NOTE: Don't use "Flags: ignoreversion" on any shared system files
 
 
 [Icons]
 [Icons]
 Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
 Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
@@ -60,4 +102,23 @@ Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChang
 Root: HKCR; Subkey: ".pixi";                             ValueData: "{#MyAppName}";          Flags: uninsdeletevalue; ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: ".pixi";                             ValueData: "{#MyAppName}";          Flags: uninsdeletevalue; ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: "{#MyAppName}";                     ValueData: "Program {#MyAppName}";  Flags: uninsdeletekey;   ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: "{#MyAppName}";                     ValueData: "Program {#MyAppName}";  Flags: uninsdeletekey;   ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: "{#MyAppName}\DefaultIcon";             ValueData: "{app}\{#MyAppExeName},0";               ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: "{#MyAppName}\DefaultIcon";             ValueData: "{app}\{#MyAppExeName},0";               ValueType: string;  ValueName: ""
-Root: HKCR; Subkey: "{#MyAppName}\shell\open\command";  ValueData: """{app}\{#MyAppExeName}"" ""%1""";  ValueType: string;  ValueName: ""
+Root: HKCR; Subkey: "{#MyAppName}\shell\open\command";  ValueData: """{app}\{#MyAppExeName}"" ""%1""";  ValueType: string;  ValueName: ""
+
+[CustomMessages]
+DependenciesDir=MyProgramDependencies
+WindowsServicePack=Windows %1 Service Pack %2
+
+[Code]
+function InitializeSetup(): Boolean;
+begin
+	// initialize windows version
+	initwinversion();
+
+#ifdef use_netcore31
+	netcore31();
+#endif
+#ifdef use_netcore31desktop
+	netcore31desktop();
+#endif
+	Result := true;
+end;

+ 0 - 63
Installer/installer-setup-x64.iss

@@ -1,63 +0,0 @@
-; Script generated by the Inno Setup Script Wizard.
-; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
-
-#define MyAppName "PixiEditor"
-#define MyAppVersion GetFileVersion("..\Builds\PixiEditor-x64\PixiEditor\PixiEditor.exe")     ;Not perfect solution, it's enviroment dependend
-#define MyAppPublisher "PixiEditor"
-#define MyAppURL "https://github.com/PixiEditor/PixiEditor"
-#define MyAppExeName "PixiEditor.exe"
-#define TargetPlatform "x64"
-
-[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={{83DE4F2A-1F75-43AE-9546-3184F1C44517}
-AppName={#MyAppName}
-AppVersion={#MyAppVersion}
-AppVerName={#MyAppName} {#MyAppVersion}
-VersionInfoVersion={#MyAppVersion}
-AppPublisher={#MyAppPublisher}
-AppPublisherURL={#MyAppURL}
-AppSupportURL={#MyAppURL}
-AppUpdatesURL={#MyAppURL}
-DefaultDirName={autopf}\{#MyAppName}
-DisableProgramGroupPage=yes
-; The [Icons] "quicklaunchicon" entry uses {userappdata} but its [Tasks] entry has a proper IsAdminInstallMode Check.
-UsedUserAreasWarning=no
-LicenseFile=..\LICENSE
-; Uncomment the following line to run in non administrative install mode (install for current user only.)
-;PrivilegesRequired=lowest
-OutputDir=Assets\PixiEditor-{#TargetPlatform}
-OutputBaseFilename=PixiEditor-{#MyAppVersion}-setup-{#TargetPlatform}
-SetupIconFile=..\icon.ico
-Compression=lzma
-SolidCompression=yes
-WizardStyle=modern
-ChangesAssociations = yes
-
-[Languages]
-Name: "english"; MessagesFile: "compiler:Default.isl"
-
-[Tasks]
-Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
-Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode
-
-[Files]
-Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\PixiEditor.exe"; DestDir: "{app}"; Flags: ignoreversion
-Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
-; NOTE: Don't use "Flags: ignoreversion" on any shared system files
-
-[Icons]
-Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
-Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
-Name: "{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
-
-[Registry]
-
-Root: HKCR; Subkey: ".pixi";                             ValueData: "{#MyAppName}";          Flags: uninsdeletevalue; ValueType: string;  ValueName: ""
-Root: HKCR; Subkey: "{#MyAppName}";                     ValueData: "Program {#MyAppName}";  Flags: uninsdeletekey;   ValueType: string;  ValueName: ""
-Root: HKCR; Subkey: "{#MyAppName}\DefaultIcon";             ValueData: "{app}\{#MyAppExeName},0";               ValueType: string;  ValueName: ""
-Root: HKCR; Subkey: "{#MyAppName}\shell\open\command";  ValueData: """{app}\{#MyAppExeName}"" ""%1""";  ValueType: string;  ValueName: ""

+ 69 - 8
Installer/installer-setup-x86-light.iss

@@ -1,8 +1,8 @@
-; Script generated by the Inno Setup Script Wizard.
-; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+// contribute: https://github.com/domgho/InnoDependencyInstaller
+// official article: https://www.codeproject.com/Articles/20868/Inno-Setup-Dependency-Installer
 
 
 #define MyAppName "PixiEditor"
 #define MyAppName "PixiEditor"
-#define MyAppVersion GetFileVersion("..\Builds\PixiEditor-x86-light\PixiEditor\PixiEditor.exe")     ;Not perfect solution, it's enviroment dependend
+#define MyAppVersion GetFileVersion("..\Builds\PixiEditor-x64-light\PixiEditor\PixiEditor.exe")     ;Not perfect solution, it's enviroment dependend
 #define MyAppPublisher "PixiEditor"
 #define MyAppPublisher "PixiEditor"
 #define MyAppURL "https://github.com/PixiEditor/PixiEditor"
 #define MyAppURL "https://github.com/PixiEditor/PixiEditor"
 #define MyAppExeName "PixiEditor.exe"
 #define MyAppExeName "PixiEditor.exe"
@@ -28,16 +28,59 @@ LicenseFile=..\LICENSE
 ; Uncomment the following line to run in non administrative install mode (install for current user only.)
 ; Uncomment the following line to run in non administrative install mode (install for current user only.)
 ;PrivilegesRequired=lowest
 ;PrivilegesRequired=lowest
 OutputDir=Assets\PixiEditor-{#TargetPlatform}
 OutputDir=Assets\PixiEditor-{#TargetPlatform}
-OutputBaseFilename=PixiEditor-{#MyAppVersion}-setup-{#TargetPlatform}
+OutputBaseFilename=PixiEditor-{#MyAppVersion}-setup-x86
 SetupIconFile=..\icon.ico
 SetupIconFile=..\icon.ico
 Compression=lzma
 Compression=lzma
 SolidCompression=yes
 SolidCompression=yes
 WizardStyle=modern
 WizardStyle=modern
 ChangesAssociations = yes
 ChangesAssociations = yes
 
 
-[Languages]
-Name: "english"; MessagesFile: "compiler:Default.isl"
+PrivilegesRequired=admin
+ArchitecturesAllowed=x86
+ArchitecturesInstallIn64BitMode=x64 ia64
 
 
+// downloading and installing dependencies will only work if the memo/ready page is enabled (default and current behaviour)
+DisableReadyPage=no
+DisableReadyMemo=no
+
+// requires netcorecheck.exe and netcorecheck_x64.exe in src dir
+#define use_netcorecheck
+#define use_netcore31
+#define use_netcore31desktop
+// supported languages
+#include "scripts\lang\english.iss"
+#include "scripts\lang\german.iss"
+#include "scripts\lang\french.iss"
+#include "scripts\lang\italian.iss"
+#include "scripts\lang\dutch.iss"
+
+#ifdef UNICODE
+#include "scripts\lang\chinese.iss"
+#include "scripts\lang\polish.iss"
+#include "scripts\lang\russian.iss"
+#include "scripts\lang\japanese.iss"
+#endif
+
+// shared code for installing the products
+#include "scripts\products.iss"
+
+// helper functions
+#include "scripts\products\stringversion.iss"
+#include "scripts\products\winversion.iss"
+#include "scripts\products\dotnetfxversion.iss"
+
+#ifdef use_netcorecheck
+#include "scripts\products\netcorecheck.iss"
+#endif
+#ifdef use_netcore31
+#include "scripts\products\netcore31.iss"
+#endif
+#ifdef use_netcore31desktop
+#include "scripts\products\netcore31desktop.iss"
+#endif
+
+// content
+[Tasks]
 [Tasks]
 [Tasks]
 Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
 Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
 Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode
 Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode
@@ -45,7 +88,6 @@ Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescrip
 [Files]
 [Files]
 Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\PixiEditor.exe"; DestDir: "{app}"; Flags: ignoreversion
 Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\PixiEditor.exe"; DestDir: "{app}"; Flags: ignoreversion
 Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
 Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
-; NOTE: Don't use "Flags: ignoreversion" on any shared system files
 
 
 [Icons]
 [Icons]
 Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
 Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
@@ -60,4 +102,23 @@ Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChang
 Root: HKCR; Subkey: ".pixi";                             ValueData: "{#MyAppName}";          Flags: uninsdeletevalue; ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: ".pixi";                             ValueData: "{#MyAppName}";          Flags: uninsdeletevalue; ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: "{#MyAppName}";                     ValueData: "Program {#MyAppName}";  Flags: uninsdeletekey;   ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: "{#MyAppName}";                     ValueData: "Program {#MyAppName}";  Flags: uninsdeletekey;   ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: "{#MyAppName}\DefaultIcon";             ValueData: "{app}\{#MyAppExeName},0";               ValueType: string;  ValueName: ""
 Root: HKCR; Subkey: "{#MyAppName}\DefaultIcon";             ValueData: "{app}\{#MyAppExeName},0";               ValueType: string;  ValueName: ""
-Root: HKCR; Subkey: "{#MyAppName}\shell\open\command";  ValueData: """{app}\{#MyAppExeName}"" ""%1""";  ValueType: string;  ValueName: ""
+Root: HKCR; Subkey: "{#MyAppName}\shell\open\command";  ValueData: """{app}\{#MyAppExeName}"" ""%1""";  ValueType: string;  ValueName: ""
+
+[CustomMessages]
+DependenciesDir=MyProgramDependencies
+WindowsServicePack=Windows %1 Service Pack %2
+
+[Code]
+function InitializeSetup(): Boolean;
+begin
+	// initialize windows version
+	initwinversion();
+
+#ifdef use_netcore31
+	netcore31();
+#endif
+#ifdef use_netcore31desktop
+	netcore31desktop();
+#endif
+	Result := true;
+end;

+ 0 - 63
Installer/installer-setup-x86.iss

@@ -1,63 +0,0 @@
-; Script generated by the Inno Setup Script Wizard.
-; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
-
-#define MyAppName "PixiEditor"
-#define MyAppVersion GetFileVersion("..\Builds\PixiEditor-x86\PixiEditor\PixiEditor.exe")     ;Not perfect solution, it's enviroment dependend
-#define MyAppPublisher "PixiEditor"
-#define MyAppURL "https://github.com/PixiEditor/PixiEditor"
-#define MyAppExeName "PixiEditor.exe"
-#define TargetPlatform "x86"
-
-[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={{83DE4F2A-1F75-43AE-9546-3184F1C44517}
-AppName={#MyAppName}
-AppVersion={#MyAppVersion}
-AppVerName={#MyAppName} {#MyAppVersion}
-VersionInfoVersion={#MyAppVersion}
-AppPublisher={#MyAppPublisher}
-AppPublisherURL={#MyAppURL}
-AppSupportURL={#MyAppURL}
-AppUpdatesURL={#MyAppURL}
-DefaultDirName={autopf}\{#MyAppName}
-DisableProgramGroupPage=yes
-; The [Icons] "quicklaunchicon" entry uses {userappdata} but its [Tasks] entry has a proper IsAdminInstallMode Check.
-UsedUserAreasWarning=no
-LicenseFile=..\LICENSE
-; Uncomment the following line to run in non administrative install mode (install for current user only.)
-;PrivilegesRequired=lowest
-OutputDir=Assets\PixiEditor-{#TargetPlatform}
-OutputBaseFilename=PixiEditor-{#MyAppVersion}-setup-{#TargetPlatform}
-SetupIconFile=..\icon.ico
-Compression=lzma
-SolidCompression=yes
-WizardStyle=modern
-ChangesAssociations = yes
-
-[Languages]
-Name: "english"; MessagesFile: "compiler:Default.isl"
-
-[Tasks]
-Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
-Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode
-
-[Files]
-Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\PixiEditor.exe"; DestDir: "{app}"; Flags: ignoreversion
-Source: "..\Builds\PixiEditor-{#TargetPlatform}\PixiEditor\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
-; NOTE: Don't use "Flags: ignoreversion" on any shared system files
-
-[Icons]
-Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
-Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
-Name: "{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
-
-[Registry]
-
-Root: HKCR; Subkey: ".pixi";                             ValueData: "{#MyAppName}";          Flags: uninsdeletevalue; ValueType: string;  ValueName: ""
-Root: HKCR; Subkey: "{#MyAppName}";                     ValueData: "Program {#MyAppName}";  Flags: uninsdeletekey;   ValueType: string;  ValueName: ""
-Root: HKCR; Subkey: "{#MyAppName}\DefaultIcon";             ValueData: "{app}\{#MyAppExeName},0";               ValueType: string;  ValueName: ""
-Root: HKCR; Subkey: "{#MyAppName}\shell\open\command";  ValueData: """{app}\{#MyAppExeName}"" ""%1""";  ValueType: string;  ValueName: ""

+ 49 - 0
Installer/scripts/isxdl/chinese.ini

@@ -0,0 +1,49 @@
+[strings]
+; General
+100=文件下载
+101=要取消下载吗?
+102=%1 (%2 / %3)
+103=%1 KB
+104=%1 KB / %2 KB (%3%)
+
+; Status information
+110=获取文件信息
+111=正在重定向到 %1
+112=正在发送请求...
+113=正在响应 %1
+114=已连接到 %1
+115=接收...
+116=正在连接到 %1
+
+; Error messages
+120=网络连接错误\n\n%1
+121=访问出错 %1.\n\n服务器返回的状态码为 %2.
+122=URL 读取错误.\n\n%1
+123=文件写入错误 %1.\n\n%2
+124=文件打开错误 %1.\n\n%2
+125='%1' 是无效的 URL.
+126=打开出错 %1.\n\n%2
+127=发送请求出错.\n\n%1
+128=不支持的协议类型. 只支持 HTTP 和 FTP 类型.
+129=无法连接到 %1.\n\n%2
+130=查询状态码失败.\n\n%1
+131=文件请求错误.\n\n%1
+
+; Other
+144=关于...
+146=下载
+147=安装程序正在下载附加文件到计算机上.
+
+; labels
+160=文件:
+161=速度:
+162=状态:
+163=已用时间:
+164=剩余时间:
+165=当前文件:
+166=总进度:
+167=取消
+168=确定
+169=用户名和密码
+170=用户名:
+171=密码:

+ 53 - 0
Installer/scripts/isxdl/czech.ini

@@ -0,0 +1,53 @@
+[strings]
+
+; Translation (c) 2005 Martin Kozák ([email protected])
+
+; General
+100=Stažení souboru
+101=Přejete si přerušit stahování?
+102=%1 (%2 z %3)
+103=%1 KB
+104=%1 KB z %2 KB (%3%)
+
+; Status information
+110=Získávání informací o souboru...
+111=Přesměrování na %1
+112=Odesílání požadavku...
+113=Zpracování %1
+114=Spojení s %1 navázáno
+115=Přijímání...
+116=Připojování k %1
+
+; Error messages
+120=Chyba při připojování k síti Internet.\n\n%1
+121=Chyba při otevírání %1.\n\nServer nastavil návratový kód %2.
+122=Chyba při čtení URL.\n\n%1
+123=Chyba při zápisu do souboru %1.\n\n%2
+124=Chyba při otevírání souboru %1.\n\n%2
+125='%1' není platné URL.
+126=Chyba při otevírání %1.\n\n%2
+127=Chyba při zasílání požadavku.\n\n%1
+128=Nepodporovaný protokol. Podporovány jsou pouze protokoly HTTP a FTP.
+129=Pokus o připojení k %1 selhalo.\n\n%2
+130=Pokus o získání návratového kódu serveru selhal.\n\n%1
+131=Chyba při zadávání požadavku na soubor.\n\n%1
+
+; Other
+144=O knihovně...
+146=Stažení komponent
+147=Průvodce instalací stahuje přídavné komponenty do vašeho počítače.
+
+; labels
+160=Soubor:
+161=Přenosová rychlost:
+162=Stav:
+163=Uplynulý čas:
+164=Zbývající čas:
+165=Zpracovávaný soubor:
+166=Celkový průběh:
+167=Zrušit
+168=OK
+169=Uživatelské jméno a heslo
+170=Uživatelské jméno:
+171=Heslo:
+

+ 49 - 0
Installer/scripts/isxdl/dutch.ini

@@ -0,0 +1,49 @@
+[strings]
+; Algemeen
+100=Bestand downloaden
+101=Wilt u de download annuleren?
+102=1% (%2 van %3)
+103=%1 KB
+104=%1 KB van %2 KB (%3%)
+
+; Status informatie
+110=Bestandsinformatie ophalen ...
+111=omgeleid naar %1
+112=Verzoek verzenden ...
+113=oplossen %1
+114=Verbonden met 1%
+115=Het ontvangen ...
+116=Verbinden met %1
+
+; foutmeldingen
+120=Fout bij het verbinden met Internet. \n\n%1
+121=Fout bij het openen van %1.\n\nDe server terug statuscode %2.
+122=Fout bij het lezen URL.\n\n%1
+123=Fout bij het schrijven bestand %1.\n\n%2
+124=Fout bij openen bestand %1.\n\n%2
+125='%1' is een ongeldige URL.
+126=Fout bij openen %1.\n\n%2
+127=Fout bij het verzenden verzoek.\n\n%1
+128=Niet ondersteund protocol. Alleen HTTP en FTP-protocollen worden ondersteund.
+129=Kan geen verbinding maken %1.\n\n%2
+130=Kan de status code opvragen.\n\n%1
+131=Fout bij het aanvragen van het bestand.\n\n%1
+
+; anders
+144=Over ...
+146=Download
+147=Setup is nu het downloaden van extra bestanden naar uw computer.
+
+; etiket
+160=Bestand:
+161=Speed:
+162=Status:
+163=Verstreken tijd:
+164=Resterende tijd:
+165=Huidige File:
+166=Algemeen Voortgang:
+167=Annuleren
+168=OK
+169=gebruikersnaam en wachtwoord
+170=Gebruikersnaam:
+171=Wachtwoord:

+ 49 - 0
Installer/scripts/isxdl/english.ini

@@ -0,0 +1,49 @@
+[strings]
+; General
+100=File download
+101=Do you want to cancel the download?
+102=%1 (%2 of %3)
+103=%1 KB
+104=%1 KB of %2 KB (%3%)
+
+; Status information
+110=Getting file information...
+111=Redirecting to %1
+112=Sending request...
+113=Resolving %1
+114=Connected to %1
+115=Receiving...
+116=Connecting to %1
+
+; Error messages
+120=Error connecting to the internet.\n\n%1
+121=Error opening %1.\n\nThe server returned status code %2.
+122=Error reading URL.\n\n%1
+123=Error writing file %1.\n\n%2
+124=Error opening file %1.\n\n%2
+125='%1' is an invalid URL.
+126=Error opening %1.\n\n%2
+127=Error sending request.\n\n%1
+128=Unsupported protocol. Only HTTP and FTP protocols are supported.
+129=Failed to connect to %1.\n\n%2
+130=Failed to query status code.\n\n%1
+131=Error requesting file.\n\n%1
+
+; Other
+144=About...
+146=Download
+147=Setup is now downloading additional files to your computer.
+
+; labels
+160=File:
+161=Speed:
+162=Status:
+163=Elapsed Time:
+164=Remaining Time:
+165=Current File:
+166=Overall Progress:
+167=Cancel
+168=OK
+169=User Name and Password
+170=User Name:
+171=Password:

+ 45 - 0
Installer/scripts/isxdl/french.ini

@@ -0,0 +1,45 @@
+[strings]
+; General
+100=Téléchargement des fichiers
+101=Souhaitez-vous annuler le téléchargement ?
+102=%1 (%2 / %3)
+103=%1 Ko
+104=%1 Ko / %2 Ko (%3%)
+
+; Etat du téléchargement
+110=Accès au fichier...
+111=Redirection vers %1
+112=Envoi de la requête...
+113=Recherche %1
+114=Connecté à %1
+115=Réception...
+116=Connexion à %1
+
+; Messages d'erreur
+120=Impossible de se connecter à internet.\n\n%1
+121=Impossible d'ouvrir %1.\n\nLe serveur a renvoyé le code d'erreur %2.
+122=Impossible de lire l'adresse.\n\n%1
+123=Impossible de créer le fichier %1.\n\n%2
+124=Impossible d'ouvrir le fichier %1.\n\n%2
+125='%1' est une adresse incorrecte.
+126=Impossible d'ouvrir %1.\n\n%2
+127=Impossible d'accéder au serveur.\n\n%1
+128=Protocole non supporté. Seuls les protocoles HTTP et FTP sont pris en charge.
+129=Impossible de se connecter à %1.\n\n%2
+130=Impossible de récupérer le code d'état.\n\n%1
+131=Impossible de récupérer le fichier.\n\n%1
+
+; Autre
+144=A propos...
+146=Téléchargement
+147=Certains fichiers requis vont être téléchargés.
+
+; Labels
+160=Fichier :
+161=Vitesse :
+162=Etat :
+163=Temps écoulé :
+164=Temps restant :
+165=Fichier courant :
+166=Tous les fichiers :
+167=Annuler

+ 45 - 0
Installer/scripts/isxdl/french2.ini

@@ -0,0 +1,45 @@
+[strings]
+; General
+100=Téléchargement de fichier
+101=Voulez vous annuler le téléchargement ?
+102=%1 (%2 de %3)
+103=%1 Ko
+104=%1 Ko de %2 Ko (%3%)
+
+; Status information
+110=Réception des informations du fichier...
+111=Redirection vers %1
+112=envoie de la demande...
+113=Résolution %1
+114=Connecté a %1
+115=Réception...
+116=Connexion à %1
+
+; Error messages
+120=Erreur de connexion à Internet.\n\n%1
+121=Erreur d'ouverture%1.\n\nLe Serveur à répondu par le code d'état %2.
+122=Erreur de lecture de l'URL.\n\n%1
+123=Erreur d'écriture du fichier %1.\n\n%2
+124=Erreur d'ouverture du fichier %1.\n\n%2
+125='%1' est une URL invalide.
+126=Erreur d’ouverture %1.\n\n%2
+127=Erreur pendant l'envoi de la demande.\n\n%1
+128=Protocole non supporté. Seuls les protocoles HTTP et FTP sont acceptés.
+129=Echec de connexion à %1.\n\n%2
+130=Echec d'obtention du code d'état.\n\n%1
+131=Erreur lors de la demande du fichier.\n\n%1
+
+; Other
+144=A Propos...
+146=Téléchargement
+147=LiveUpdate télécharge maintenant des fichiers complémentaires sur votre ordinateur.
+
+; labels
+160=Fichier:
+161=Vitesse:
+162=Etat:
+163=Temps écoulé:
+164=Temps restant:
+165=Fichier en cours:
+166=Avancement global:
+167=Annuler

+ 46 - 0
Installer/scripts/isxdl/french3.ini

@@ -0,0 +1,46 @@
+; By Fabien ILLIDE ([email protected])
+[strings]
+; General
+100=Téléchargement de fichier
+101=Voulez-vous annuler le téléchargement ?
+102=%1 (%2 de %3)
+103=%1 Ko
+104=%1 Ko de %2 Ko (%3%)
+
+; Status information
+110=Obtention des informations du fichier...
+111=Redirection vers %1
+112=Envoi de la requête...
+113=Résolution de %1
+114=Connecté à %1
+115=Réception...
+116=Connexion à %1
+
+; Error messages
+120=Erreur de connexion à Internet.\n\n%1
+121=Erreur en ouvrant %1.\n\nLe serveur à retourné le code d'état %2.
+122=Erreur de lecture d'URL.\n\n%1
+123=Erreur d'écriture pour %1.\n\n%2
+124=Erreur en ouvrant le fichier %1.\n\n%2
+125='%1' est une URL invalide.
+126=Erreur en ouvrant %1.\n\n%2
+127=Erreur d'envoi de requête.\n\n%1
+128=Protocole non supporté. Seuls les protocoles HTTP et FTP sont supportés.
+129=Echec de connexion à %1.\n\n%2
+130=Echec de demande du code d'état.\n\n%1
+131=Erreur en demandant le fichier.\n\n%1
+
+; Other
+144=A propos...
+146=Télécharger
+147=L'installateur télécharge maintenant les fichiers additionnels sur votre ordinateur.
+
+; labels
+160=Fichier :
+161=Vitesse :
+162=Etat :
+163=Temps écoulé :
+164=Temps restant :
+165=Fichier en cours :
+166=Avancement global :
+167=Annuler

+ 49 - 0
Installer/scripts/isxdl/german.ini

@@ -0,0 +1,49 @@
+[strings]
+; General
+100=Datei herunterladen
+101=Möchten Sie das Herunterladen der Datei abbrechen?
+102=%1 (%2 von %3)
+103=%1 KB
+104=%1 KB von %2 KB (%3%)
+
+; Status information
+110=Dateiinformationen werden ermittelt...
+111=Weiterleitung zu %1
+112=Anforderung wird gesendet...
+113=Auflösen von %1
+114=Verbunden mit %1
+115=Empfange...
+116=Verbinden mit %1
+
+; Error messages
+120=Fehler beim Verbinden mit dem Internet.\n\n%1
+121=Fehler beim Öffnen von %1.\n\nDer Server meldet Statuscode %2.
+122=Fehler beim Lesen der URL.\n\n%1
+123=Fehler beim Schreiben der Datei %1.\n\n%2
+124=Fehler beim Öffnen der Datei %1.\n\n%2
+125='%1' ist eine ungültige URL.
+126=Fehler beim Öffnen von %1.\n\n%2
+127=Fehler beim Senden der Anforderung.\n\n%1
+128=Protokoll wird nicht unterstützt. Nur HTTP und FTP werden unterstützt.
+129=Verbindung zu %1 fehlgeschlagen.\n\n%2
+130=Fehler bei der Abfrage des Statuscodes.\n\n%1
+131=Fehler bei der Anforderung der Datei.\n\n%1
+
+; Other
+144=Über...
+146=Download
+147=Das Setup lädt nun zusätzliche Dateien auf Ihren Computer.
+
+; labels
+160=Datei:
+161=Geschwindigkeit:
+162=Status:
+163=Bisherige Zeit:
+164=Verbleibende Zeit:
+165=Aktuelle Datei:
+166=Gesamter Vorgang:
+167=Abbrechen
+168=OK
+169=Benutzername und Kennwort
+170=Benutzername:
+171=Kennwort:

BIN
Installer/scripts/isxdl/isxdl.dll


+ 12 - 0
Installer/scripts/isxdl/isxdl.iss

@@ -0,0 +1,12 @@
+[Files]
+Source: "scripts\isxdl\isxdl.dll"; Flags: dontcopy noencryption
+
+[Code]
+procedure isxdl_AddFile(URL, Filename: PAnsiChar);
+external 'isxdl_AddFile@files:isxdl.dll stdcall';
+
+function isxdl_DownloadFiles(hWnd: Integer): Integer;
+external 'isxdl_DownloadFiles@files:isxdl.dll stdcall';
+
+function isxdl_SetOption(Option, Value: PAnsiChar): Integer;
+external 'isxdl_SetOption@files:isxdl.dll stdcall';

+ 49 - 0
Installer/scripts/isxdl/italian.ini

@@ -0,0 +1,49 @@
+[strings]
+; Generale
+100=Download del file
+101=Vuoi annullare il download?
+102=%1 (%2 di %3)
+103=%1 KB
+104=%1 KB di %2 KB (%3%)
+
+; Informazioni di servizio
+110=Raccolta informazioni sul file...
+111=Reindirizzamento a %1
+112=Invio richiesta...
+113=Risoluzione %1
+114=Connesso al %1
+115=Ricezione...
+116=Collegamento a %1
+
+; Messaggi di errore
+120=Errore nel collegamento a Internet.\n\n%1
+121=Errore nell'apertura di %1.\n\nIl server ha restituito il codice %2.
+122=Errore nella lettura dell'URL.\n\n%1
+123=Errore nella scrittura del file %1.\n\n%2
+124=Errore nell'apertura del file %1.\n\n%2
+125='%1' è un URL non valido.
+126=Errore nell'apertura di %1.\n\n%2
+127=Errore durante l'invio della richiesta.\n\n%1
+128=Protocollo non supportato. Sono supportati solo i protocolli HTTP e FTP.
+129=Impossibile connettersi a %1.\n\n%2
+130=Impossibile risolvere il codice di servizio.\n\n%1
+131=Errore nella richiesta del file.\n\n%1
+
+; Altro
+144=Informazioni su...
+146=Download
+147=Il programma d'installazione sta scaricando sul computer i files aggiuntivi.
+
+; Etichette
+160=File:
+161=Velocità:
+162=Stato:
+163=Tempo trascorso:
+164=Tempo rimanente:
+165=File attuale:
+166=Avanzamento generale:
+167=Annulla
+168=OK
+169=Nome utente e password
+170=Nome utente:
+171=Password:

+ 49 - 0
Installer/scripts/isxdl/japanese.ini

@@ -0,0 +1,49 @@
+[strings]
+; General
+100=ファイルダウンロード
+101=ダウンロードをキャンセルしますか?
+102=%1 (%2 of %3)
+103=%1 KB
+104=%1 KB of %2 KB (%3%)
+
+; Status information
+110=ファイル情報を取得中...
+111=リダイレクト %1
+112=リクエスト送信...
+113=解決中 %1
+114=接続完了 %1
+115=受信中...
+116=接続中 %1
+
+; Error messages
+120=インターネット接続エラー.\n\n%1
+121=開始エラー %1.\n\nサーバーのステータスコード %2.
+122=URL読み取りエラー.\n\n%1
+123=ファイル書込みエラー %1.\n\n%2
+124=ファイルオープンエラー %1.\n\n%2
+125='%1' は不正なURLです.
+126=オープンエラー %1.\n\n%2
+127=リクエスト送信エラー.\n\n%1
+128=サポートされていないプロトコルです. HTTPとFTPプロトコルだけがサポートされています.
+129=接続に失敗しました %1.\n\n%2
+130=ステータスコードの問い合わせ失敗.\n\n%1
+131=ファイルリクエストエラー.\n\n%1
+
+; Other
+144=About...
+146=ダウンロード
+147=セットアップはコンピューターに追加のファイルをダウンロードしています.
+
+; labels
+160=ファイル:
+161=速度:
+162=状態:
+163=経過時間:
+164=残り時間:
+165=現在のファイル:
+166=全体の進捗状況:
+167=キャンセル
+168=OK
+169=ユーザーとパスワード
+170=ユーザー:
+171=パスワード:

+ 49 - 0
Installer/scripts/isxdl/korean.ini

@@ -0,0 +1,49 @@
+[strings]
+; General
+100=파일 다운로드
+101=다운로드를 취소하시겠습니까?
+102=%1 (%2 중 %3)
+103=%1 KB
+104=%1 KB 중 %2 KB (%3%)
+
+; Status information
+110=파일 정보를 받고 있습니다...
+111=Redirecting to %1
+112=요청을 보내고 있습니다...
+113= %1
+114=%1(으)로 연결되었습니다.
+115=받는중...
+116=%1(으)로 연결중입니다.
+
+; Error messages
+120=인터넷 연결중 문제가 발생했습니다.\n\n%1
+121=여는도중 애러 발생 %1.\n\n서버 상태 메시지 %2.
+122=URL을 읽는 도중 문제가 발생했습니다.\n\n%1
+123=파일을 쓰는 도중 문제가 발생했습니다 %1.\n\n%2
+124=파일을 여는 도중 문제가 발생했습니다 %1.\n\n%2
+125='%1' 은 잘못된 URL입니다.
+126=여는 도중 문제가 발생했습니다 %1.\n\n%2
+127=요청을 보내는 도중 문제가 발생했습니다\n\n%1
+128=지원하지 않는 프로토콜입니다. HTTP 와 FTP 만을 지원합니다.
+129=%1로 연결이 실패하였습니다.\n\n%2
+130=쿼리가 실패했습니다. 상태 코드는 다음과 같습니다.\n\n%1
+131=파일 요청중 문제가 발생했습니다.\n\n%1
+
+; Other
+144=About...
+146=다운로드
+147=이 설치 프로그램은 추가적으로 이 파일들을 다운로드 하게 됩니다.
+
+; labels
+160=파일:
+161=속도:
+162=상태:
+163=경과 시간:
+164=남은 시간:
+165=현재 파일:
+166=전체 진행도:
+167=취소
+168=확인
+169=사용자명과 패스워드
+170=사용자명:
+171=패스워드:

+ 47 - 0
Installer/scripts/isxdl/norwegian.ini

@@ -0,0 +1,47 @@
+[strings]
+; General
+100=Nedlasting
+101=Vil du avbryte nedlastinga?
+102=%1 (%2 av %3)
+103=%1 KB
+104=%1 KB av %2 KB (%3%)
+
+; Status information
+110=Henter filinformasjon...
+111=Omdirigerer til %1
+112=Sender forespørsel...
+113=Resolving %1
+114=Oppkoblet mot %1
+115=Mottar...
+116=Kobler til %1
+; Error messages
+120=Feil ved oppkobling til Internett.\n\n%1
+121=Feil ved åpning av %1.\n\nTjeneren returnerte statuskode %2.
+122=Feil ved lesing av URL.\n\n%1
+123=Feil ved skriving til '%1'.\n\n%2
+124=Feil ved åpning av '%1'.\n\n%2
+125='%1' er ikke en gyldig url.
+126=Feil ved åpning av %1.\n\n%2
+127=Feil ved sending av forespørsel.\n\n%1
+128=Ikke støttet protokoll. Bare HTTP og FTP protokoller er støttet.
+129=Klarte ikke å koble til %1.\n\n%2
+130=Klarte ikke å lese statuskode.\n\n%1
+131=Feil ved forespørsel av fil.\n\n%1
+; Other
+144=Om...
+146=Nedlasting
+147=Setup laster nå ned flere filer til din datamaskin.
+
+; labels
+160=Fil:
+161=Hastighet:
+162=Status:
+163=Brukt tid:
+164=Gjenstående tid:
+165=Gjeldende fil:
+166=Total fremgang:
+167=Avbryt
+168=OK
+169=Brukernavn og passord
+170=Brukernavn:
+171=Passord:

+ 45 - 0
Installer/scripts/isxdl/polish.ini

@@ -0,0 +1,45 @@
+[strings]
+; General
+100=Pobieranie pliku
+101=Czy chcesz przerwać pobieranie?
+102=%1 (%2 z %3)
+103=%1 KB
+104=%1 KB z %2 KB (%3%)
+
+; Status information
+110=Pobieranie informacji o pliku...
+111=Przekierowywanie do %1
+112=Wysyłanie żądania...
+113=Rozwiązywanie %1
+114=Połączony z %1
+115=Pobieranie...
+116=Podłączanie do %1
+
+; Error messages
+120=Nie można podłączyć się do Internetu.\n\n%1
+121=Błąd otwierania %1.\n\nSerwer zwrócił kod błędu %2.
+122=Błąd czytania URL.\n\n%1
+123=Błąd zapisu pliku %1.\n\n%2
+124=Błąd otwarcia pliku %1.\n\n%2
+125='%1' nie jest prawidłowym URL.
+126=Błąd otwarcia %1.\n\n%2
+127=Błąd wysłania żądania.\n\n%1
+128=Nieznany protokół. Tylko protokoły HTTP i FTP są obsługiwane.
+129=Nie udało się podłączenie do %1.\n\n%2
+130=Nie udało się zapytać o kod stanu.\n\n%1
+131=Błąd żądania pliku.\n\n%1
+
+; Other
+144=O pobieraniu...
+146=Pobieranie
+147=W tej chwili Instalator pobiera dodatkowe pliki do Twojego komputera.
+
+; labels
+160=Plik:
+161=Prędkość:
+162=Stan:
+163=Upłynęło:
+164=Pozostały czas:
+165=Aktualny plik:
+166=Całkowity postęp:
+167=Anuluj

+ 45 - 0
Installer/scripts/isxdl/portugues.ini

@@ -0,0 +1,45 @@
+[strings]
+; General
+100=Donwload de ficheiro
+101=Deseja cancelar o donwload?
+102=%1 (%2 de %3)
+103=%1 KB
+104=%1 KB de %2 KB (%3%)
+
+; Status information
+110=A receber informação do ficheiro...
+111=A redirecionar para %1
+112=A enviar pedido...
+113=A resolver %1
+114=Ligado a %1
+115=A receber...
+116=A ligar a %1
+
+; Error messages
+120=Erro na ligação à internet.\n\n%1
+121=Erro na abertura de %1.\n\nO servidor retornou o código de erro %2.
+122=Erro a ler o URL.\n\n%1
+123=Erro na escrita do ficheiro %1.\n\n%2
+124=Erro na abertura do ficheiro %1.\n\n%2
+125='%1' é um URL inválido.
+126=Erro na abertura de %1.\n\n%2
+127=Erro no envio do pedido.\n\n%1
+128=Protocolo não suportado.
+129=Falha na ligação a %1.\n\n%2
+130=Falha na tentativa de retirar o código de status.\n\n%1
+131=Erro no pedido do ficheiro.\n\n%1
+
+; Other
+144=Acerca...
+146=Download
+147=A instalação está a efectuar o download de ficheiros adicionais necessários.
+
+; labels
+160=Ficheiro:
+161=Velocidade:
+162=Estado:
+163=Tempo usado:
+164=Tempo em falta:
+165=Ficheiro:
+166=Progresso:
+167=Cancelar

+ 46 - 0
Installer/scripts/isxdl/portuguese.ini

@@ -0,0 +1,46 @@
+; By António Pinto (AP SoftWare)
+[strings]
+; Geral
+100=Download
+101=Deseja cancelar o download?
+102=%1 (%2 de %3)
+103=%1 KB
+104=%1 KB de %2 KB (%3%)
+
+; Status information
+110=A receber informação do ficheiro...
+111=Redireccionando a %1
+112=A enviar petição...
+113=Resolvendo %1
+114=Ligado a %1
+115=A receber...
+116=A efectuar ligação a %1
+
+; Error messages
+120=Erro a ligar à Internet.\n\n%1
+121=Erro ao abrir %1.\n\nO servidor devolveu o código %2.
+122=Erro ao ler URL.\n\n%1
+123=Erro ao escrever o ficheiro %1.\n\n%2
+124=Erro ao abrir o ficheiro %1.\n\n%2
+125='%1' é uma URL inválida.
+126=Erro ao abrir %1.\n\n%2
+127=Erro ao enviar a petição.\n\n%1
+128=Erro de protocolo. Só os protocolos HTTP ou FTP são aceites.
+129=Erro ao ligar a %1.\n\n%2
+130=Erro ao processar o código.\n\n%1
+131=Erro ao procurar o ficheiro.\n\n%1
+
+; Other
+144=Acerca...
+146=Descarregar
+147=O assistente está a descarregar ficheiros para o seu computador.
+
+; labels
+160=Ficheiro:
+161=Velocidade:
+162=Estado:
+163=Tempo transcorrido:
+164=Tempo estimado:
+165=Ficheiro actual:
+166=Progressão geral:
+167=Cancelar

+ 49 - 0
Installer/scripts/isxdl/russian.ini

@@ -0,0 +1,49 @@
+[strings]
+; General
+100=Загрузка файла
+101=Вы действительно хотите прервать загрузку?
+102=%1 (%2 из %3)
+103=%1 KB
+104=%1 KB из %2 KB (%3%)
+
+; Status information
+110=Получение информации о файле...
+111=Переход на %1
+112=Отправка запроса...
+113=Подключение к %1
+114=Подключен к %1
+115=Получение...
+116=Соединение с %1
+
+; Error messages
+120=Ошибка подключения к интернету.\n\n%1
+121=Ошибка открытия %1.\n\nСервер вернул код ошибки %2.
+122=Ошибка чтения адреса.\n\n%1
+123=Ошибка записи файла %1.\n\n%2
+124=Ошибка открытия файла %1.\n\n%2
+125='%1' неправильный интернет адрес.
+126=Ошибка открытия %1.\n\n%2
+127=Ошибка при отправке запроса.\n\n%1
+128=Протокол не поддерживается. Программой поддерживаются только протоколы HTTP и FTP.
+129=Невозможно подключиться к %1.\n\n%2
+130=Невозможно получить код статуса.\n\n%1
+131=Ошибка при запросе файла.\n\n%1
+
+; Other
+144=О программе...
+146=Загрузка
+147=Сейчас происходит загрузка дополнительных файлов на ваш компьютер.
+
+; labels
+160=Файл:
+161=Скорость:
+162=Статус:
+163=Прошло времени:
+164=Осталось времени:
+165=Текущий файл:
+166=Всего закачено:
+167=Отмена
+168=OK
+169=Имя пользователя и пароль
+170=Имя пользователя:
+171=Пароль:

+ 46 - 0
Installer/scripts/isxdl/spanish.ini

@@ -0,0 +1,46 @@
+; By Lobo Lunar
+[strings]
+; General
+100=Descarga
+101=¿Deseas cancelar la descarga?
+102=%1 (%2 de %3)
+103=%1 KB
+104=%1 KB de %2 KB (%3%)
+
+; Status information
+110=Recibiendo información del archivo...
+111=Redireccionando a %1
+112=Enviando petición...
+113=Resolviendo %1
+114=Conectando a %1
+115=Descargando...
+116=Conectando a %1
+
+; Error messages
+120=Error al conectar a Internet.\n\n%1
+121=Error al abrir %1.\n\nEl servidor regresó %2.
+122=Error al leer URL.\n\n%1
+123=Error al escribir el archivo %1.\n\n%2
+124=Error al abrir archivo %1.\n\n%2
+125='%1' es URL inválido.
+126=Error al abrir %1.\n\n%2
+127=Error al mandar petición.\n\n%1
+128=Error de protocolo. Sólo HTTP o FTP son aceptados.
+129=Error al conectar a %1.\n\n%2
+130=Error al procesar el código.\n\n%1
+131=Error al buscar archivo.\n\n%1
+
+; Other
+144=Acerca...
+146=Descargar
+147=El asistente está descargando archivos.
+
+; labels
+160=Archivo:
+161=Velocidad:
+162=Estado:
+163=Tiempo transcurrido:
+164=Tiempo estimado:
+165=Archivo actual:
+166=Progreso general:
+167=Cancelar

+ 48 - 0
Installer/scripts/isxdl/swedish.ini

@@ -0,0 +1,48 @@
+[strings]
+; General
+100=Fil Nedladdning
+101=Vill du avbruta nedladdningen?
+102=%1 (%2 av %3)
+103=%1 KB
+104=%1 KB av %2 KB (%3%)
+
+; Status information
+110=Hämtar fil information...
+111=Omdirigerar till %1
+112=Sänder förfrågan...
+113=Delar upp %1
+114=Ansluten %1
+115=Tar emot...
+116=Ansluter till %1
+
+; Error messages
+120=Fel vid anslutning till Internet.\n\n%1
+121=Fel vid öppning av %1.\n\nServern returnerade felkod %2.
+122=Fel vid läsninga av URL.\n\n%1
+123=Fel vid skrivning av fil %1.\n\n%2
+124=Fel vid öppning av fil %1.\n\n%2
+125='%1' är en felaktig URL.
+126=Kan inte öppna %1.\n\n%2
+127=Fel vid sändning av förfrågan.\n\n%1
+128=Stöd saknas för protokollet. Endast HTTP och FTP protokollen understöds.
+129=Misslyckades att ansluta till %1.\n\n%2
+130=Misslyckades att kontrollera status kod.\n\n%1
+131=Fel vid förfrågan efter fil.\n\n%1
+
+; Other
+144=Om...
+146=Ladd ner
+147=Setup laddar nu ner tilläggsfiler till din dator
+; labels
+160=Fil:
+161=Hastighet:
+162=Status:
+163=Förfluten Time:
+164=Återstående Time:
+165=Nuvarande Fil:
+166=Totalt Förlopp:
+167=Avbryt
+168=OK
+169=Användarnamn och Lösenord
+170=Användarnamn:
+171=Lösenord:

+ 18 - 0
Installer/scripts/lang/chinese.iss

@@ -0,0 +1,18 @@
+[Languages]
+Name: "chs"; MessagesFile: "compiler:Default.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+chs.lcid=2052
+chs.depdownload_memo_title=下载依赖组建
+chs.depinstall_memo_title=安装依赖组建
+chs.depinstall_title=安装依赖组建
+chs.depinstall_description=安装程序正在安装所需的依赖组建,请稍后。
+chs.depinstall_status=正在安装 %1...
+chs.depinstall_missing=必须安装 %1 之后才能继续本安装程序。请先安装 %1,然后在重新运行本安装程序。
+chs.depinstall_error=安装依赖组建时出错。请重新启动计算机并再次运行安装程序,或手动安装下列依赖组建:%n
+
+chs.isxdl_langfile=chinese.ini
+
+[Files]
+Source: "scripts\isxdl\chinese.ini"; Flags: dontcopy noencryption

+ 18 - 0
Installer/scripts/lang/dutch.iss

@@ -0,0 +1,18 @@
+[Languages]
+Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+nl.lcid=1043
+nl.depdownload_memo_title=Download afhankelijkheden
+nl.depinstall_memo_title=Installeer afhankelijkheden
+nl.depinstall_title=Installeer afhankelijkheden
+nl.depinstall_description=Een moment geduld aub Setup installeert afhankelijkheden op uw computer.
+nl.depinstall_status=Installeren %1...
+nl.depinstall_missing=%1 moet worden geïnstalleerd vóór de installatie kan worden voortgezet. Installeer %1 en voer Setup opnieuw uit.
+nl.depinstall_error=Er is een fout opgetreden tijdens het installeren van de afhankelijkheden. Gelieve de computer opnieuw op en voer de installatie opnieuw uit of de volgende afhankelijkheden handmatig installeren:%n
+
+nl.isxdl_langfile=dutch.ini
+
+[Files]
+Source: "scripts\isxdl\dutch.ini"; Flags: dontcopy noencryption

+ 15 - 0
Installer/scripts/lang/english.iss

@@ -0,0 +1,15 @@
+[Languages]
+Name: "en"; MessagesFile: "compiler:Default.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+en.lcid=1033
+en.depdownload_memo_title=Download dependencies
+en.depinstall_memo_title=Install dependencies
+en.depinstall_title=Installing dependencies
+en.depinstall_description=Please wait while Setup installs dependencies on your computer.
+en.depinstall_status=Installing %1...
+en.depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
+en.depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
+
+en.isxdl_langfile=

+ 18 - 0
Installer/scripts/lang/french.iss

@@ -0,0 +1,18 @@
+[Languages]
+Name: "fr"; MessagesFile: "compiler:Languages\French.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+fr.lcid=1036
+fr.depdownload_memo_title=Télécharger les dépendances
+fr.depinstall_memo_title=Installez les dépendances
+fr.depinstall_title=Installation des dépendances
+fr.depinstall_description=Veuillez patienter pendant que les dépendances sont installées sur votre ordinateur.
+fr.depinstall_status=Installation de %1...
+fr.depinstall_missing=%1 doit être installé avant de pouvoir continuer. Veuillez installer %1 et exécutez à nouveau le programme d'installation.
+fr.depinstall_error=Une erreur est survenue lors de l'installation des dépendances. Veuillez redémarrer l'ordinateur, et exécutez à nouveau le programme d'installation, ou installez les dépendances suivantes manuellement :%n
+
+fr.isxdl_langfile=french3.ini
+
+[Files]
+Source: "scripts\isxdl\french3.ini"; Flags: dontcopy noencryption

+ 18 - 0
Installer/scripts/lang/german.iss

@@ -0,0 +1,18 @@
+[Languages]
+Name: "de"; MessagesFile: "compiler:Languages\German.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+de.lcid=1031
+de.depdownload_memo_title=Abhängigkeiten downloaden
+de.depinstall_memo_title=Abhängigkeiten installieren
+de.depinstall_title=Installiere Abhängigkeiten
+de.depinstall_description=Warten Sie bitte während Abhängigkeiten auf Ihrem Computer installiert wird.
+de.depinstall_status=Installiere %1...
+de.depinstall_missing=%1 muss installiert werden bevor das Setup fortfahren kann. Bitte installieren Sie %1 und starten Sie das Setup erneut.
+de.depinstall_error=Ein Fehler ist während der Installation der Abghängigkeiten aufgetreten. Bitte starten Sie den Computer neu und führen Sie das Setup erneut aus oder installieren Sie die folgenden Abhängigkeiten per Hand:%n
+
+de.isxdl_langfile=german.ini
+
+[Files]
+Source: "scripts\isxdl\german.ini"; Flags: dontcopy noencryption

+ 18 - 0
Installer/scripts/lang/italian.iss

@@ -0,0 +1,18 @@
+[Languages]
+Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+it.lcid=1040
+it.depdownload_memo_title=Dipendenze da scaricare
+it.depinstall_memo_title=Dipendenze da installare
+it.depinstall_title=Installazione delle dipendenze
+it.depinstall_description=Si prega di attendere mentre vengono installate le dipendenze necessarie sul computer.
+it.depinstall_status=Installazione %1...
+it.depinstall_missing=%1 deve essere installato per poter continuare. Si prega di installare %1 ed eseguire nuovamente il programma d'installazione.
+it.depinstall_error=Si è verificato un errore durante l'installazione delle dipendenze. Si prega di riavviare il computer ed eseguire nuovamente il programma d'installazione oppure di installare manualmente le seguenti applicazioni:%n
+
+it.isxdl_langfile=italian.ini
+
+[Files]
+Source: "scripts\isxdl\italian.ini"; Flags: dontcopy noencryption

+ 18 - 0
Installer/scripts/lang/japanese.iss

@@ -0,0 +1,18 @@
+[Languages]
+Name: "ja"; MessagesFile: "compiler:Languages\Japanese.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+ja.lcid=1041
+ja.depdownload_memo_title=ダウンロードする依存ファイル
+ja.depinstall_memo_title=インストールする依存ファイル
+ja.depinstall_title=依存ファイルのインストール
+ja.depinstall_description=セットアップが依存ファイルをインストールするまでお待ちください
+ja.depinstall_status=インストール中 %1...
+ja.depinstall_missing=セットアップを継続するために %1 をインストールする必要があります. %1 をインストールし、再度セットアップを実行してください.
+ja.depinstall_error=依存ファイルのインストール中にエラーが発生しました. コンピューターを再起動しセットアップを再度実行するか、依存ファイルを手動でインストールしてください:%n
+
+ja.isxdl_langfile=japanese.ini
+
+[Files]
+Source: "scripts\isxdl\japanese.ini"; Flags: dontcopy noencryption

+ 18 - 0
Installer/scripts/lang/polish.iss

@@ -0,0 +1,18 @@
+[Languages]
+Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+pl.lcid=1045
+pl.depdownload_memo_title=Pobierz zależności
+pl.depinstall_memo_title=Zainstaluj zależności
+pl.depinstall_title=Instalowanie zależności
+pl.depinstall_description=Instalator instaluje zależności na komputerze, proszę czekać.
+pl.depinstall_status=Instalowanie %1....
+pl.depinstall_missing=%1 musi być zainstalowany przed instalacją, aby mogła ona być kontynuowana. Zainstaluj %1 i ponownie uruchom program instalacyjny.
+pl.depinstall_error=Wystąpił błąd podczas instalowania zależności. Uruchom ponownie komputer, a następnie ponownie uruchom program instalacyjny lub ręcznie zainstaluj następujące programy:%n
+
+pl.isxdl_langfile=polish.ini
+
+[Files]
+Source: "scripts\isxdl\polish.ini"; Flags: dontcopy noencryption

+ 18 - 0
Installer/scripts/lang/russian.iss

@@ -0,0 +1,18 @@
+[Languages]
+Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
+
+[CustomMessages]
+// https://www.microsoft.com/globaldev/reference/lcid-all.mspx
+ru.lcid=1049
+ru.depdownload_memo_title=Загрузить зависимости
+ru.depinstall_memo_title=Установить зависимости
+ru.depinstall_title=Установка зависимостей
+ru.depinstall_description=Пожалуйста, подождите, пока зависимости будут установлены.
+ru.depinstall_status=Установка %1...
+ru.depinstall_missing=%1 должен быть установлен прежде чем установка может быть продолжена. Пожалуйста, установите %1 и повторите установку.
+ru.depinstall_error=В процессе установки зависимостей произошла ошибка. Пожалуйста, перезапустите компьютер и повторите установку, либо установите следующие зависимости вручную:%n
+
+ru.isxdl_langfile=russian.ini
+
+[Files]
+Source: "scripts\isxdl\russian.ini"; Flags: dontcopy noencryption

+ 4 - 0
Installer/scripts/products.iss

@@ -0,0 +1,4 @@
+#include "isxdl\isxdl.iss"
+
+[Code]
+#include "products.pas"

+ 324 - 0
Installer/scripts/products.pas

@@ -0,0 +1,324 @@
+{
+	--- TYPES AND VARIABLES ---
+}
+type
+	TProduct = record
+		File: String;
+		Title: String;
+		Parameters: String;
+		ForceSuccess: Boolean;
+		InstallClean: Boolean;
+		MustRebootAfter: Boolean;
+	end;
+
+	InstallResult = (InstallSuccessful, InstallRebootRequired, InstallError);
+
+var
+	installMemo, downloadMemo: String;
+	products: array of TProduct;
+	delayedReboot, isForcedX86: Boolean;
+	DependencyPage: TOutputProgressWizardPage;
+
+procedure AddProduct(filename, parameters, title, size, url: String; forceSuccess, installClean, mustRebootAfter: Boolean);
+{
+	Adds a product to the list of products to download.
+	Parameters:
+		filename: the file name under which to save the file
+		parameters: the parameters with which to run the file
+		title: the product title
+		size: the file size
+		url: the URL to download from
+		forceSuccess: whether to continue in case of setup failure
+		installClean: whether the product needs a reboot before installing
+		mustRebootAfter: whether the product needs a reboot after installing
+}
+var
+	path: String;
+	i: Integer;
+begin
+	path := ExpandConstant('{src}{\}') + CustomMessage('DependenciesDir') + '\' + filename;
+	if not FileExists(path) then begin
+		path := ExpandConstant('{tmp}{\}') + filename;
+
+		if not FileExists(path) then begin
+			isxdl_AddFile(url, path);
+
+			downloadMemo := downloadMemo + '%1' + title + ' (' + size + ')' + #13;
+		end else begin
+			installMemo := installMemo + '%1' + title + #13;
+		end;
+	end else begin
+		installMemo := installMemo + '%1' + title + #13;
+	end;
+
+	i := GetArrayLength(products);
+	SetArrayLength(products, i + 1);
+	products[i].File := path;
+	products[i].Title := title;
+	products[i].Parameters := parameters;
+	products[i].ForceSuccess := forceSuccess;
+	products[i].InstallClean := installClean;
+	products[i].MustRebootAfter := mustRebootAfter;
+end;
+
+function SmartExec(product: TProduct; var resultCode: Integer): Boolean;
+{
+	Executes a product and returns the exit code.
+	Parameters:
+		product: the product to install
+		resultCode: the exit code
+}
+begin
+	Result := ShellExec('', product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultCode);
+end;
+
+function PendingReboot: Boolean;
+{
+	Checks whether the machine has a pending reboot.
+}
+var
+	names: String;
+begin
+	if (RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'PendingFileRenameOperations', names)) then begin
+		Result := true;
+	end else if ((RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'SetupExecute', names)) and (names <> ''))  then begin
+		Result := true;
+	end else begin
+		Result := false;
+	end;
+end;
+
+function InstallProducts: InstallResult;
+{
+	Installs the downloaded products
+}
+var
+	resultCode, i, productCount, finishCount: Integer;
+begin
+	Result := InstallSuccessful;
+	productCount := GetArrayLength(products);
+
+	if productCount > 0 then begin
+		DependencyPage := CreateOutputProgressPage(CustomMessage('depinstall_title'), CustomMessage('depinstall_description'));
+		DependencyPage.Show;
+
+		for i := 0 to productCount - 1 do begin
+			if (products[i].InstallClean and (delayedReboot or PendingReboot())) then begin
+				Result := InstallRebootRequired;
+				break;
+			end;
+
+			DependencyPage.SetText(FmtMessage(CustomMessage('depinstall_status'), [products[i].Title]), '');
+			DependencyPage.SetProgress(i, productCount);
+
+			while true do begin
+				// set 0 as used code for shown error if SmartExec fails
+				resultCode := 0;
+				if SmartExec(products[i], resultCode) then begin
+					// setup executed; resultCode contains the exit code
+					if (products[i].MustRebootAfter) then begin
+						// delay reboot after install if we installed the last dependency anyways
+						if (i = productCount - 1) then begin
+							delayedReboot := true;
+						end else begin
+							Result := InstallRebootRequired;
+						end;
+						break;
+					end else if (resultCode = 0) or (products[i].ForceSuccess) then begin
+						finishCount := finishCount + 1;
+						break;
+					end else if (resultCode = 3010) then begin
+						// Windows Installer resultCode 3010: ERROR_SUCCESS_REBOOT_REQUIRED
+						delayedReboot := true;
+						finishCount := finishCount + 1;
+						break;
+					end;
+				end;
+
+				case MsgBox(FmtMessage(SetupMessage(msgErrorFunctionFailed), [products[i].Title, IntToStr(resultCode)]), mbError, MB_ABORTRETRYIGNORE) of
+					IDABORT: begin
+						Result := InstallError;
+						break;
+					end;
+					IDIGNORE: begin
+						break;
+					end;
+				end;
+			end;
+
+			if Result <> InstallSuccessful then begin
+				break;
+			end;
+		end;
+
+		// only leave not installed products for error message
+		for i := 0 to productCount - finishCount - 1 do begin
+			products[i] := products[i+finishCount];
+		end;
+		SetArrayLength(products, productCount - finishCount);
+
+		DependencyPage.Hide;
+	end;
+end;
+
+{
+	--------------------
+	INNO EVENT FUNCTIONS
+	--------------------
+}
+
+function PrepareToInstall(var NeedsRestart: Boolean): String;
+{
+	Before the "preparing to install" page.
+	See: https://www.jrsoftware.org/ishelp/index.php?topic=scriptevents
+}
+var
+	i: Integer;
+	s: String;
+begin
+	delayedReboot := false;
+
+	case InstallProducts() of
+		InstallError: begin
+			s := CustomMessage('depinstall_error');
+
+			for i := 0 to GetArrayLength(products) - 1 do begin
+				s := s + #13 + '	' + products[i].Title;
+			end;
+
+			Result := s;
+			end;
+		InstallRebootRequired: begin
+			Result := products[0].Title;
+			NeedsRestart := true;
+
+			// write into the registry that the installer needs to be executed again after restart
+			RegWriteStringValue(HKEY_CURRENT_USER, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', 'InstallBootstrap', ExpandConstant('{srcexe}'));
+			end;
+	end;
+end;
+
+function NeedRestart: Boolean;
+{
+	Checks whether a restart is needed at the end of install
+	See: https://www.jrsoftware.org/ishelp/index.php?topic=scriptevents
+}
+begin
+	Result := delayedReboot;
+end;
+
+function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
+{
+	Just before the "ready" page.
+	See: https://www.jrsoftware.org/ishelp/index.php?topic=scriptevents
+}
+var
+	s: String;
+begin
+	if downloadMemo <> '' then
+		s := s + CustomMessage('depdownload_memo_title') + ':' + NewLine + FmtMessage(downloadMemo, [Space]) + NewLine;
+	if installMemo <> '' then
+		s := s + CustomMessage('depinstall_memo_title') + ':' + NewLine + FmtMessage(installMemo, [Space]) + NewLine;
+
+	if MemoDirInfo <> '' then
+		s := s + MemoDirInfo + NewLine + NewLine;
+	if MemoGroupInfo <> '' then
+		s := s + MemoGroupInfo + NewLine + NewLine;
+	if MemoTasksInfo <> '' then
+		s := s + MemoTasksInfo;
+
+	Result := s
+end;
+
+function NextButtonClick(CurPageID: Integer): Boolean;
+{
+	At each "next" button click
+	See: https://www.jrsoftware.org/ishelp/index.php?topic=scriptevents
+}
+begin
+	Result := true;
+
+	if CurPageID = wpReady then begin
+		if downloadMemo <> '' then begin
+			// change isxdl language only if it is not english because isxdl default language is already english
+			if (ActiveLanguage() <> 'en') then begin
+				ExtractTemporaryFile(CustomMessage('isxdl_langfile'));
+				isxdl_SetOption('language', ExpandConstant('{tmp}{\}') + CustomMessage('isxdl_langfile'));
+			end;
+
+			if isxdl_DownloadFiles(StrToInt(ExpandConstant('{wizardhwnd}'))) = 0 then
+				Result := false;
+		end;
+	end;
+end;
+
+{
+	-----------------------------
+	ARCHITECTURE HELPER FUNCTIONS
+	-----------------------------
+}
+
+function IsX86: Boolean;
+{
+	Gets whether the computer is x86 (32 bits).
+}
+begin
+	Result := isForcedX86 or (ProcessorArchitecture = paX86) or (ProcessorArchitecture = paUnknown);
+end;
+
+function IsX64: Boolean;
+{
+	Gets whether the computer is x64 (64 bits).
+}
+begin
+	Result := (not isForcedX86) and Is64BitInstallMode and (ProcessorArchitecture = paX64);
+end;
+
+function IsIA64: Boolean;
+{
+	Gets whether the computer is IA64 (Itanium 64 bits).
+}
+begin
+	Result := (not isForcedX86) and Is64BitInstallMode and (ProcessorArchitecture = paIA64);
+end;
+
+function GetString(x86, x64, ia64: String): String;
+{
+	Gets a string depending on the computer architecture.
+	Parameters:
+		x86: the string if the computer is x86
+		x64: the string if the computer is x64
+		ia64: the string if the computer is IA64
+}
+begin
+	if IsX64() and (x64 <> '') then begin
+		Result := x64;
+	end else if IsIA64() and (ia64 <> '') then begin
+		Result := ia64;
+	end else begin
+		Result := x86;
+	end;
+end;
+
+function GetArchitectureString(): String;
+{
+	Gets the "standard" architecture suffix string.
+	Returns either _x64, _ia64 or nothing.
+}
+begin
+	if IsX64() then begin
+		Result := '_x64';
+	end else if IsIA64() then begin
+		Result := '_ia64';
+	end else begin
+		Result := '';
+	end;
+end;
+
+procedure SetForceX86(value: Boolean);
+{
+	Forces the setup to use X86 products
+}
+begin
+	isForcedX86 := value;
+end;

+ 92 - 0
Installer/scripts/products/dotnetfxversion.iss

@@ -0,0 +1,92 @@
+[Code]
+type
+	NetFXType = (NetFx10, NetFx11, NetFx20, NetFx30, NetFx35, NetFx40Client, NetFx40Full, NetFx4x);
+
+const
+	netfx11plus_reg = 'Software\Microsoft\NET Framework Setup\NDP\';
+
+function dotnetfxinstalled(version: NetFXType; lcid: String): Boolean;
+var
+	regVersion: Cardinal;
+	regVersionString: String;
+begin
+	if (lcid <> '') then
+		lcid := '\' + lcid;
+
+	case version of
+		NetFx10:
+			Result := RegQueryStringValue(HKLM, 'Software\Microsoft\.NETFramework\Policy\v1.0\3705', 'Install', regVersionString) and (regVersionString <> '');
+		NetFx11:
+			Result := RegQueryDWordValue(HKLM, netfx11plus_reg + 'v1.1.4322' + lcid, 'Install', regVersion) and (regVersion <> 0);
+		NetFx20:
+			Result := RegQueryDWordValue(HKLM, netfx11plus_reg + 'v2.0.50727' + lcid, 'Install', regVersion) and (regVersion <> 0);
+		NetFx30:
+			Result := RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.0\Setup' + lcid, 'InstallSuccess', regVersion) and (regVersion <> 0);
+		NetFx35:
+			Result := RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.5' + lcid, 'Install', regVersion) and (regVersion <> 0);
+		NetFx40Client:
+			Result := RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Client' + lcid, 'Install', regVersion) and (regVersion <> 0);
+		NetFx40Full:
+			Result := RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Install', regVersion) and (regVersion <> 0);
+		NetFx4x:
+			Result := RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Release', regVersion) and (regVersion >= 378389); // 4.5.0+
+	end;
+end;
+
+function dotnetfxspversion(version: NetFXType; lcid: String): Integer;
+var
+	regVersion: Cardinal;
+begin
+	if (lcid <> '') then
+		lcid := '\' + lcid;
+
+	case version of
+		NetFx10:
+			// not supported
+			regVersion := -1;
+		NetFx11:
+			if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v1.1.4322' + lcid, 'SP', regVersion)) then
+				regVersion := -1;
+		NetFx20:
+			if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v2.0.50727' + lcid, 'SP', regVersion)) then
+				regVersion := -1;
+		NetFx30:
+			if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.0' + lcid, 'SP', regVersion)) then
+				regVersion := -1;
+		NetFx35:
+			if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.5' + lcid, 'SP', regVersion)) then
+				regVersion := -1;
+		NetFx40Client:
+			if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Client' + lcid, 'Servicing', regVersion)) then
+				regVersion := -1;
+		NetFx40Full:
+			if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Servicing', regVersion)) then
+				regVersion := -1;
+		NetFx4x:
+			if (RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Release', regVersion)) then begin
+				if (regVersion >= 528040) then
+					regVersion := 80 // 4.8.0+ 
+				else if (regVersion >= 461808) then
+					regVersion := 72 // 4.7.2+
+				else if (regVersion >= 461308) then
+					regVersion := 71 // 4.7.1+
+				else if (regVersion >= 460798) then
+					regVersion := 70 // 4.7.0+
+				else if (regVersion >= 394802) then
+					regVersion := 62 // 4.6.2+
+				else if (regVersion >= 394254) then
+					regVersion := 61 // 4.6.1+
+				else if (regVersion >= 393295) then
+					regVersion := 60 // 4.6.0+
+				else if (regVersion >= 379893) then
+					regVersion := 52 // 4.5.2+
+				else if (regVersion >= 378675) then
+					regVersion := 51 // 4.5.1+
+				else if (regVersion >= 378389) then
+					regVersion := 50 // 4.5.0+
+				else
+					regVersion := -1;
+			end;
+	end;
+	Result := regVersion;
+end;

+ 27 - 0
Installer/scripts/products/netcore31.iss

@@ -0,0 +1,27 @@
+// requires Windows 10 Version 1607+, Windows 7 SP1+, Windows 8.1, Windows Server 2012 R2
+// https://dotnet.microsoft.com/download/dotnet-core/3.1
+
+[CustomMessages]
+netcore31_title=.NET Core Runtime 3.1.6 (x86)
+netcore31_title_x64=.NET Core Runtime 3.1.6 (x64)
+
+netcore31_size=23 MB
+netcore31_size_x64=26 MB
+
+[Code]
+const
+	netcore31_url = 'http://go.microsoft.com/fwlink/?linkid=2137641';
+	netcore31_url_x64 = 'http://go.microsoft.com/fwlink/?linkid=2137640';
+
+procedure netcore31();
+begin
+	if (not IsIA64()) then begin
+		if not netcoreinstalled(Core, '3.1.6') then
+			AddProduct('netcore31' + GetArchitectureString() + '.exe',
+				'/lcid ' + CustomMessage('lcid') + ' /passive /norestart',
+				CustomMessage('netcore31_title' + GetArchitectureString()),
+				CustomMessage('netcore31_size' + GetArchitectureString()),
+				GetString(netcore31_url, netcore31_url_x64, ''),
+				false, false, false);
+	end;
+end;

+ 27 - 0
Installer/scripts/products/netcore31desktop.iss

@@ -0,0 +1,27 @@
+// requires Windows 10 Version 1607+, Windows 7 SP1+, Windows 8.1, Windows Server 2012 R2
+// https://dotnet.microsoft.com/download/dotnet-core/3.1
+
+[CustomMessages]
+netcore31desktop_title=.NET Desktop Runtime 3.1.6 (x86)
+netcore31desktop_title_x64=.NET Desktop Runtime 3.1.6 (x64)
+
+netcore31desktop_size=23 MB
+netcore31desktop_size_x64=26 MB
+
+[Code]
+const
+	netcore31desktop_url = 'http://go.microsoft.com/fwlink/?linkid=2137844';
+	netcore31desktop_url_x64 = 'http://go.microsoft.com/fwlink/?linkid=2137941';
+
+procedure netcore31desktop();
+begin
+	if (not IsIA64()) then begin
+		if not netcoreinstalled(Desktop, '3.1.6') then
+			AddProduct('netcore31desktop' + GetArchitectureString() + '.exe',
+				'/lcid ' + CustomMessage('lcid') + ' /passive /norestart',
+				CustomMessage('netcore31desktop_title' + GetArchitectureString()),
+				CustomMessage('netcore31desktop_size' + GetArchitectureString()),
+				GetString(netcore31desktop_url, netcore31desktop_url_x64, ''),
+				false, false, false);
+	end;
+end;

+ 32 - 0
Installer/scripts/products/netcorecheck.iss

@@ -0,0 +1,32 @@
+// NetCoreCheck tool is necessary for detecting if a specific version of .NET Core/.NET 5.0 is installed: https://github.com/dotnet/runtime/issues/36479
+// source code: https://github.com/dotnet/deployment-tools/tree/master/src/clickonce/native/projects/NetCoreCheck
+// download netcorecheck.exe: https://go.microsoft.com/fwlink/?linkid=2135256
+// download netcorecheck_x64.exe: https://go.microsoft.com/fwlink/?linkid=2135504
+
+[Files]
+Source: "src\netcorecheck.exe"; Flags: dontcopy noencryption
+Source: "src\netcorecheck_x64.exe"; Flags: dontcopy noencryption
+
+[Code]
+type
+	NetCoreRuntimeType = (Asp, Core, Desktop);
+
+function netcoreinstalled(runtime: NetCoreRuntimeType; version: String): Boolean;
+var
+	netcoreRuntime: String;
+	resultCode: Integer;
+begin
+	case runtime of
+		Asp:
+			netcoreRuntime := 'Microsoft.AspNetCore.App';
+		Core:
+			netcoreRuntime := 'Microsoft.NETCore.App';
+		Desktop:
+			netcoreRuntime := 'Microsoft.WindowsDesktop.App';
+	end;
+
+	if not FileExists(ExpandConstant('{tmp}{\}') + 'netcorecheck' + GetArchitectureString() + '.exe') then
+		ExtractTemporaryFile('netcorecheck' + GetArchitectureString() + '.exe');
+
+	Result := Exec(ExpandConstant('{tmp}{\}') + 'netcorecheck' + GetArchitectureString() + '.exe', netcoreRuntime + ' ' + version, '', SW_HIDE, ewWaitUntilTerminated, resultCode) and (resultCode = 0);
+end;

+ 60 - 0
Installer/scripts/products/stringversion.iss

@@ -0,0 +1,60 @@
+[Code]
+function stringtoversion(var temp: String): Integer;
+var
+	part: String;
+	pos1: Integer;
+
+begin
+	if (Length(temp) = 0) then begin
+		Result := -1;
+		Exit;
+	end;
+
+	pos1 := Pos('.', temp);
+	if (pos1 = 0) then begin
+		Result := StrToInt(temp);
+		temp := '';
+	end else begin
+		part := Copy(temp, 1, pos1 - 1);
+		temp := Copy(temp, pos1 + 1, Length(temp));
+		Result := StrToInt(part);
+	end;
+end;
+
+function compareinnerversion(var x, y: String): Integer;
+var
+	num1, num2: Integer;
+
+begin
+	num1 := stringtoversion(x);
+	num2 := stringtoversion(y);
+	if (num1 = -1) and (num2 = -1) then begin
+		Result := 0;
+		Exit;
+	end;
+
+	if (num1 < 0) then begin
+		num1 := 0;
+	end;
+	if (num2 < 0) then begin
+		num2 := 0;
+	end;
+
+	if (num1 < num2) then begin
+		Result := -1;
+	end else if (num1 > num2) then begin
+		Result := 1;
+	end else begin
+		Result := compareinnerversion(x, y);
+	end;
+end;
+
+function compareversion(versionA, versionB: String): Integer;
+var
+  temp1, temp2: String;
+
+begin
+	temp1 := versionA;
+	temp2 := versionB;
+	Result := compareinnerversion(temp1, temp2);
+end;

+ 47 - 0
Installer/scripts/products/winversion.iss

@@ -0,0 +1,47 @@
+[Code]
+var
+	WindowsVersion: TWindowsVersion;
+
+procedure initwinversion();
+begin
+	GetWindowsVersionEx(WindowsVersion);
+end;
+
+function exactwinversion(MajorVersion, MinorVersion: Integer): Boolean;
+begin
+	Result := (WindowsVersion.Major = MajorVersion) and (WindowsVersion.Minor = MinorVersion);
+end;
+
+function minwinversion(MajorVersion, MinorVersion: Integer): Boolean;
+begin
+	Result := (WindowsVersion.Major > MajorVersion) or ((WindowsVersion.Major = MajorVersion) and (WindowsVersion.Minor >= MinorVersion));
+end;
+
+function maxwinversion(MajorVersion, MinorVersion: Integer): Boolean;
+begin
+	Result := (WindowsVersion.Major < MajorVersion) or ((WindowsVersion.Major = MajorVersion) and (WindowsVersion.Minor <= MinorVersion));
+end;
+
+function exactwinspversion(MajorVersion, MinorVersion, SpVersion: Integer): Boolean;
+begin
+	if exactwinversion(MajorVersion, MinorVersion) then
+		Result := WindowsVersion.ServicePackMajor = SpVersion
+	else
+		Result := true;
+end;
+
+function minwinspversion(MajorVersion, MinorVersion, SpVersion: Integer): Boolean;
+begin
+	if exactwinversion(MajorVersion, MinorVersion) then
+		Result := WindowsVersion.ServicePackMajor >= SpVersion
+	else
+		Result := true;
+end;
+
+function maxwinspversion(MajorVersion, MinorVersion, SpVersion: Integer): Boolean;
+begin
+	if exactwinversion(MajorVersion, MinorVersion) then
+		Result := WindowsVersion.ServicePackMajor <= SpVersion
+	else
+		Result := true;
+end;

BIN
Installer/src/netcorecheck.exe


BIN
Installer/src/netcorecheck_x64.exe


+ 1 - 0
PixiEditor.UpdateInstaller/PixiEditor.UpdateInstaller.csproj

@@ -4,6 +4,7 @@
     <OutputType>WinExe</OutputType>
     <OutputType>WinExe</OutputType>
     <TargetFramework>netcoreapp3.1</TargetFramework>
     <TargetFramework>netcoreapp3.1</TargetFramework>
     <UseWPF>true</UseWPF>
     <UseWPF>true</UseWPF>
+    <ApplicationManifest>app.manifest</ApplicationManifest>
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 5 - 4
PixiEditor.UpdateInstaller/ViewModelMain.cs

@@ -1,4 +1,5 @@
-using System;
+using PixiEditor.UpdateModule;
+using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
 using System.IO;
 using System.IO;
@@ -43,11 +44,11 @@ namespace PixiEditor.UpdateInstaller
 
 
         public void InstallUpdate()
         public void InstallUpdate()
         {
         {
-            string[] files = Directory.GetFiles(UpdateDirectory, "update-*.zip");
+            string[] files = Directory.GetFiles(UpdateDownloader.DownloadLocation, "update-*.zip");
 
 
             if (files.Length > 0)
             if (files.Length > 0)
             {
             {
-                Installer = new UpdateModule.UpdateInstaller(files[0]);
+                Installer = new UpdateModule.UpdateInstaller(files[0], UpdateDirectory);
                 Installer.ProgressChanged += Installer_ProgressChanged;
                 Installer.ProgressChanged += Installer_ProgressChanged;
                 Installer.Install();
                 Installer.Install();
             }
             }
@@ -57,7 +58,7 @@ namespace PixiEditor.UpdateInstaller
             }
             }
         }
         }
 
 
-        private void Installer_ProgressChanged(object sender, UpdateModule.UpdateProgressChangedEventArgs e)
+        private void Installer_ProgressChanged(object sender, UpdateProgressChangedEventArgs e)
         {
         {
             ProgressValue = e.Progress;
             ProgressValue = e.Progress;
         }
         }

+ 76 - 0
PixiEditor.UpdateInstaller/app.manifest

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+    <security>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <!-- UAC Manifest Options
+             If you want to change the Windows User Account Control level replace the 
+             requestedExecutionLevel node with one of the following.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            Specifying requestedExecutionLevel element will disable file and registry virtualization. 
+            Remove this element if your application requires this virtualization for backwards
+            compatibility.
+        -->
+        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+
+  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+    <application>
+      <!-- A list of the Windows versions that this application has been tested on
+           and is designed to work with. Uncomment the appropriate elements
+           and Windows will automatically select the most compatible environment. -->
+
+      <!-- Windows Vista -->
+      <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
+
+      <!-- Windows 7 -->
+      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
+
+      <!-- Windows 8 -->
+      <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
+
+      <!-- Windows 8.1 -->
+      <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
+
+      <!-- Windows 10 -->
+      <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
+
+    </application>
+  </compatibility>
+
+  <!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
+       DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need 
+       to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should 
+       also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
+  <!--
+  <application xmlns="urn:schemas-microsoft-com:asm.v3">
+    <windowsSettings>
+      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
+    </windowsSettings>
+  </application>
+  -->
+
+  <!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
+  <!--
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity
+          type="win32"
+          name="Microsoft.Windows.Common-Controls"
+          version="6.0.0.0"
+          processorArchitecture="*"
+          publicKeyToken="6595b64144ccf1df"
+          language="*"
+        />
+    </dependentAssembly>
+  </dependency>
+  -->
+
+</assembly>

+ 11 - 3
PixiEditor.UpdateModule/UpdateDownloader.cs

@@ -3,14 +3,13 @@ using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Net;
 using System.Net;
 using System.Net.Http;
 using System.Net.Http;
-using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
 namespace PixiEditor.UpdateModule
 namespace PixiEditor.UpdateModule
 {
 {
     public static class UpdateDownloader
     public static class UpdateDownloader
     {
     {
-        public static string DownloadLocation = AppDomain.CurrentDomain.BaseDirectory;
+        public static string DownloadLocation = Path.Join(Path.GetTempPath(), "PixiEditor");
         public static async Task DownloadReleaseZip(ReleaseInfo release)
         public static async Task DownloadReleaseZip(ReleaseInfo release)
         {
         {
             Asset matchingAsset = GetMatchingAsset(release);
             Asset matchingAsset = GetMatchingAsset(release);
@@ -23,15 +22,24 @@ namespace PixiEditor.UpdateModule
                 if (response.StatusCode == HttpStatusCode.OK)
                 if (response.StatusCode == HttpStatusCode.OK)
                 {
                 {
                     byte[] bytes = await response.Content.ReadAsByteArrayAsync();
                     byte[] bytes = await response.Content.ReadAsByteArrayAsync();
+                    CreateTempDirectory();
                     File.WriteAllBytes(Path.Join(DownloadLocation, $"update-{release.TagName}.zip"), bytes);
                     File.WriteAllBytes(Path.Join(DownloadLocation, $"update-{release.TagName}.zip"), bytes);
                 }
                 }
             }
             }
         }
         }
 
 
+        public static void CreateTempDirectory()
+        {
+            if (!Directory.Exists(DownloadLocation))
+            {
+                Directory.CreateDirectory(DownloadLocation);
+            }
+        }
+
         private static Asset GetMatchingAsset(ReleaseInfo release)
         private static Asset GetMatchingAsset(ReleaseInfo release)
         {
         {
             string arch = IntPtr.Size == 8 ? "x64" : "x86";
             string arch = IntPtr.Size == 8 ? "x64" : "x86";
-            return release.Assets.First(x => x.ContentType == "application/x-zip-compressed"
+            return release.Assets.First(x => x.ContentType.Contains("zip")
             && x.Name.Contains(arch));
             && x.Name.Contains(arch));
         }
         }
     }
     }

+ 9 - 5
PixiEditor.UpdateModule/UpdateInstaller.cs

@@ -8,6 +8,7 @@ namespace PixiEditor.UpdateModule
     public class UpdateInstaller
     public class UpdateInstaller
     {
     {
         public const string TargetDirectoryName = "UpdateFiles";
         public const string TargetDirectoryName = "UpdateFiles";
+        public static string UpdateFilesPath = Path.Join(UpdateDownloader.DownloadLocation, TargetDirectoryName);
 
 
         public event EventHandler<UpdateProgressChangedEventArgs> ProgressChanged;
         public event EventHandler<UpdateProgressChangedEventArgs> ProgressChanged;
         private float _progress = 0;
         private float _progress = 0;
@@ -21,22 +22,24 @@ namespace PixiEditor.UpdateModule
             }
             }
         }
         }
         public string ArchiveFileName { get; set; }
         public string ArchiveFileName { get; set; }
+        public string TargetDirectory { get; set; }
 
 
-        public UpdateInstaller(string archiveFileName)
+        public UpdateInstaller(string archiveFileName, string targetDirectory)
         {
         {
             ArchiveFileName = archiveFileName;
             ArchiveFileName = archiveFileName;
+            TargetDirectory = targetDirectory;
         }
         }
 
 
         public void Install()
         public void Install()
         {
         {
             var processes = Process.GetProcessesByName("PixiEditor");
             var processes = Process.GetProcessesByName("PixiEditor");
-            if(processes.Length > 0)
+            if (processes.Length > 0)
             {
             {
                 processes[0].WaitForExit();
                 processes[0].WaitForExit();
             }
             }
-            ZipFile.ExtractToDirectory(ArchiveFileName, TargetDirectoryName, true);
+            ZipFile.ExtractToDirectory(ArchiveFileName, UpdateFilesPath, true);
             Progress = 25; //25% for unzip
             Progress = 25; //25% for unzip
-            string dirWithFiles = Directory.GetDirectories(TargetDirectoryName)[0];
+            string dirWithFiles = Directory.GetDirectories(UpdateFilesPath)[0];
             string[] files = Directory.GetFiles(dirWithFiles);
             string[] files = Directory.GetFiles(dirWithFiles);
             CopyFilesToDestination(files);
             CopyFilesToDestination(files);
             DeleteArchive();
             DeleteArchive();
@@ -46,12 +49,13 @@ namespace PixiEditor.UpdateModule
         private void DeleteArchive()
         private void DeleteArchive()
         {
         {
             File.Delete(ArchiveFileName);
             File.Delete(ArchiveFileName);
+            Directory.Delete(UpdateFilesPath, true);
         }
         }
 
 
         private void CopyFilesToDestination(string[] files)
         private void CopyFilesToDestination(string[] files)
         {
         {
             float fileCopiedVal = 74f / files.Length; //74% is reserved for copying
             float fileCopiedVal = 74f / files.Length; //74% is reserved for copying
-            string destinationDir = Path.GetDirectoryName(ArchiveFileName);
+            string destinationDir = TargetDirectory;
             foreach (string file in files)
             foreach (string file in files)
             {
             {
                 string targetFileName = Path.GetFileName(file);
                 string targetFileName = Path.GetFileName(file);

+ 4 - 4
PixiEditor/Models/Controllers/BitmapManager.cs

@@ -12,7 +12,7 @@ using PixiEditor.Models.ImageManipulation;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools;
 using PixiEditor.Models.Tools;
-using PixiEditor.Models.Tools.ToolSettings;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 
 
 namespace PixiEditor.Models.Controllers
 namespace PixiEditor.Models.Controllers
 {
 {
@@ -46,12 +46,12 @@ namespace PixiEditor.Models.Controllers
 
 
         public int ToolSize
         public int ToolSize
         {
         {
-            get => SelectedTool.Toolbar.GetSetting("ToolSize") != null
-            ? (int)SelectedTool.Toolbar.GetSetting("ToolSize").Value
+            get => SelectedTool.Toolbar.GetSetting<SizeSetting>("ToolSize") != null
+            ? SelectedTool.Toolbar.GetSetting<SizeSetting>("ToolSize").Value
             : 1;
             : 1;
             set
             set
             {
             {
-                if (SelectedTool.Toolbar.GetSetting("ToolSize") is Setting toolSize)
+                if (SelectedTool.Toolbar.GetSetting<SizeSetting>("ToolSize") is var toolSize)
                 {
                 {
                     toolSize.Value = value;
                     toolSize.Value = value;
                     HighlightPixels(MousePositionConverter.CurrentCoordinates);
                     HighlightPixels(MousePositionConverter.CurrentCoordinates);

+ 25 - 0
PixiEditor/Models/Processes/ProcessHelper.cs

@@ -0,0 +1,25 @@
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace PixiEditor.Models.Processes
+{
+    public static class ProcessHelper
+    {
+        public static Process RunAsAdmin(string path)
+        {
+            Process proc = new Process();
+            try
+            {
+                proc.StartInfo.FileName = path;
+                proc.StartInfo.Verb = "runas";
+                proc.StartInfo.UseShellExecute = true;
+                proc.Start();
+            }
+            catch (Win32Exception ex)
+            {
+                throw ex;
+            }
+            return proc;
+        }
+    }
+}

+ 2 - 2
PixiEditor/Models/Tools/ToolSettings/Settings/BoolSetting.cs

@@ -5,7 +5,7 @@ using System.Windows.Data;
 
 
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 {
 {
-    public class BoolSetting : Setting
+    public class BoolSetting : Setting<bool>
     {
     {
         public BoolSetting(string name, string label = "") : base(name)
         public BoolSetting(string name, string label = "") : base(name)
         {
         {
@@ -25,7 +25,7 @@ namespace PixiEditor.Models.Tools.ToolSettings.Settings
         {
         {
             CheckBox checkBox = new CheckBox
             CheckBox checkBox = new CheckBox
             {
             {
-                IsChecked = (bool) Value,
+                IsChecked = Value,
                 VerticalAlignment = VerticalAlignment.Center
                 VerticalAlignment = VerticalAlignment.Center
             };
             };
 
 

+ 1 - 1
PixiEditor/Models/Tools/ToolSettings/Settings/ColorSetting.cs

@@ -4,7 +4,7 @@ using ColorPicker;
 
 
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 {
 {
-    public class ColorSetting : Setting
+    public class ColorSetting : Setting<Color>
     {
     {
         public ColorSetting(string name, string label = "") : base(name)
         public ColorSetting(string name, string label = "") : base(name)
         {
         {

+ 1 - 1
PixiEditor/Models/Tools/ToolSettings/Settings/DropdownSetting.cs

@@ -5,7 +5,7 @@ using System.Windows.Data;
 
 
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 {
 {
-    public class DropdownSetting : Setting
+    public class DropdownSetting : Setting<object>
     {
     {
         public string[] Values { get; set; }
         public string[] Values { get; set; }
 
 

+ 1 - 1
PixiEditor/Models/Tools/ToolSettings/Settings/FloatSetting.cs

@@ -3,7 +3,7 @@ using PixiEditor.Views;
 
 
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 {
 {
-    public class FloatSetting : Setting
+    public class FloatSetting : Setting<float>
     {
     {
         public float Min { get; set; }
         public float Min { get; set; }
         public float Max { get; set; }
         public float Max { get; set; }

+ 19 - 8
PixiEditor/Models/Tools/ToolSettings/Settings/Setting.cs

@@ -1,15 +1,18 @@
 using System.Windows.Controls;
 using System.Windows.Controls;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
 
 
-namespace PixiEditor.Models.Tools.ToolSettings
+namespace PixiEditor.Models.Tools.ToolSettings.Settings
 {
 {
-    public abstract class Setting : NotifyableObject
+    public abstract class Setting<T> : Setting
     {
     {
-        public string Name { get; protected set; }
-        public string Label { get; set; }
-        public bool HasLabel => !string.IsNullOrEmpty(Label);
+        private T value;
 
 
-        public object Value
+        protected Setting(string name)
+            : base(name)
+        {
+        }
+
+        public T Value
         {
         {
             get => value;
             get => value;
             set
             set
@@ -18,11 +21,19 @@ namespace PixiEditor.Models.Tools.ToolSettings
                 RaisePropertyChanged("Value");
                 RaisePropertyChanged("Value");
             }
             }
         }
         }
+    }
+
+    public abstract class Setting : NotifyableObject
+    {
+        public string Name { get; }
+
+        public string Label { get; set; }
+
+        public bool HasLabel => !string.IsNullOrEmpty(Label);
 
 
         public Control SettingControl { get; set; }
         public Control SettingControl { get; set; }
-        private object value;
 
 
-        public Setting(string name)
+        protected Setting(string name)
         {
         {
             Name = name;
             Name = name;
         }
         }

+ 2 - 2
PixiEditor/Models/Tools/ToolSettings/Settings/SizeSetting.cs

@@ -7,7 +7,7 @@ using PixiEditor.Helpers.Behaviours;
 
 
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 namespace PixiEditor.Models.Tools.ToolSettings.Settings
 {
 {
-    public class SizeSetting : Setting
+    public class SizeSetting : Setting<int>
     {
     {
         public SizeSetting(string name, string label = null) : base(name)
         public SizeSetting(string name, string label = null) : base(name)
         {
         {
@@ -28,7 +28,7 @@ namespace PixiEditor.Models.Tools.ToolSettings.Settings
 
 
             if (Application.Current != null)
             if (Application.Current != null)
             {
             {
-                tb.Style = (Style)Application.Current.TryFindResource("DarkTextBoxStyle"); ;
+                tb.Style = (Style)Application.Current.TryFindResource("DarkTextBoxStyle");
             }
             }
 
 
             Binding binding = new Binding("Value")
             Binding binding = new Binding("Value")

+ 30 - 8
PixiEditor/Models/Tools/ToolSettings/Toolbars/Toolbar.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Collections.ObjectModel;
 using System.Linq;
 using System.Linq;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 
 
 namespace PixiEditor.Models.Tools.ToolSettings.Toolbars
 namespace PixiEditor.Models.Tools.ToolSettings.Toolbars
 {
 {
@@ -20,16 +21,29 @@ namespace PixiEditor.Models.Tools.ToolSettings.Toolbars
             return Settings.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.CurrentCultureIgnoreCase));
             return Settings.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.CurrentCultureIgnoreCase));
         }
         }
 
 
+        /// <summary>
+        ///     Gets setting of given type T in toolbar by name.
+        /// </summary>
+        /// <param name="name">Setting name, non case sensitive</param>
+        /// <returns></returns>
+        public T GetSetting<T>(string name)
+            where T : Setting
+        {
+            Setting setting =  Settings.FirstOrDefault(currentSetting => string.Equals(currentSetting.Name, name, StringComparison.CurrentCultureIgnoreCase));
+
+            if (setting == null || !(setting is T convertedSetting))
+                return null;
+
+            return convertedSetting;
+        }
+
         /// <summary>
         /// <summary>
         ///     Saves current toolbar state, so other toolbars with common settings can load them.
         ///     Saves current toolbar state, so other toolbars with common settings can load them.
         /// </summary>
         /// </summary>
         public void SaveToolbarSettings()
         public void SaveToolbarSettings()
         {
         {
-            for (int i = 0; i < Settings.Count; i++)
-                if (SharedSettings.Any(x => x.Name == Settings[i].Name))
-                    SharedSettings.First(x => x.Name == Settings[i].Name).Value = Settings[i].Value;
-                else
-                    SharedSettings.Add(Settings[i]);
+            foreach (Setting setting in Settings)
+                AddSettingToCollection(SharedSettings, setting);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -37,9 +51,17 @@ namespace PixiEditor.Models.Tools.ToolSettings.Toolbars
         /// </summary>
         /// </summary>
         public void LoadSharedSettings()
         public void LoadSharedSettings()
         {
         {
-            for (int i = 0; i < SharedSettings.Count; i++)
-                if (Settings.Any(x => x.Name == SharedSettings[i].Name))
-                    Settings.First(x => x.Name == SharedSettings[i].Name).Value = SharedSettings[i].Value;
+            foreach (Setting sharedSetting in SharedSettings)
+                AddSettingToCollection(Settings, sharedSetting);
+        }
+
+        private static void AddSettingToCollection(ICollection<Setting> collection, Setting setting)
+        {
+            Setting storedSetting = collection.FirstOrDefault(currentSetting => currentSetting.Name == setting.Name);
+            if (storedSetting != null)
+                collection.Remove(storedSetting);
+
+            collection.Add(setting);
         }
         }
     }
     }
 }
 }

+ 4 - 4
PixiEditor/Models/Tools/Tools/BrightnessTool.cs

@@ -3,12 +3,12 @@ using System.Collections.Generic;
 using System.Windows.Controls;
 using System.Windows.Controls;
 using System.Windows.Input;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media;
-using System.Windows.Media.Imaging;
 using PixiEditor.Models.Colors;
 using PixiEditor.Models.Colors;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 
 
 namespace PixiEditor.Models.Tools.Tools
 namespace PixiEditor.Models.Tools.Tools
@@ -35,9 +35,9 @@ namespace PixiEditor.Models.Tools.Tools
 
 
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         {
         {
-            int toolSize = (int) Toolbar.GetSetting("ToolSize").Value;
-            float correctionFactor = (float) Toolbar.GetSetting("CorrectionFactor").Value;
-            Enum.TryParse<BrightnessMode>((Toolbar.GetSetting("Mode").Value as ComboBoxItem)?.Content as string, out var mode);
+            int toolSize = Toolbar.GetSetting<SizeSetting>("ToolSize").Value;
+            float correctionFactor = Toolbar.GetSetting<FloatSetting>("CorrectionFactor").Value;
+            Enum.TryParse((Toolbar.GetSetting<DropdownSetting>("Mode")?.Value as ComboBoxItem)?.Content as string, out BrightnessMode mode);
             Mode = mode;
             Mode = mode;
 
 
             LayerChange[] layersChanges = new LayerChange[1];
             LayerChange[] layersChanges = new LayerChange[1];

+ 4 - 5
PixiEditor/Models/Tools/Tools/CircleTool.cs

@@ -1,13 +1,12 @@
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Diagnostics;
 using System.Linq;
 using System.Linq;
-using System.Numerics;
 using System.Windows.Media;
 using System.Windows.Media;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 
 
 namespace PixiEditor.Models.Tools.Tools
 namespace PixiEditor.Models.Tools.Tools
 {
 {
@@ -22,13 +21,13 @@ namespace PixiEditor.Models.Tools.Tools
 
 
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         {
         {
-            int thickness = (int) Toolbar.GetSetting("ToolSize").Value;
+            int thickness = Toolbar.GetSetting<SizeSetting>("ToolSize").Value;
             DoubleCords fixedCoordinates = CalculateCoordinatesForShapeRotation(coordinates[^1], coordinates[0]);
             DoubleCords fixedCoordinates = CalculateCoordinatesForShapeRotation(coordinates[^1], coordinates[0]);
             IEnumerable<Coordinates> outline = CreateEllipse(fixedCoordinates.Coords1, fixedCoordinates.Coords2, thickness);
             IEnumerable<Coordinates> outline = CreateEllipse(fixedCoordinates.Coords1, fixedCoordinates.Coords2, thickness);
             BitmapPixelChanges pixels = BitmapPixelChanges.FromSingleColoredArray(outline, color);
             BitmapPixelChanges pixels = BitmapPixelChanges.FromSingleColoredArray(outline, color);
-            if ((bool) Toolbar.GetSetting("Fill").Value)
+            if (Toolbar.GetSetting<BoolSetting>("Fill").Value)
             {
             {
-                Color fillColor = (Color) Toolbar.GetSetting("FillColor").Value;
+                Color fillColor = Toolbar.GetSetting<ColorSetting>("FillColor").Value;
                 pixels.ChangedPixels.AddRangeNewOnly(
                 pixels.ChangedPixels.AddRangeNewOnly(
                     BitmapPixelChanges.FromSingleColoredArray(CalculateFillForEllipse(outline), fillColor)
                     BitmapPixelChanges.FromSingleColoredArray(CalculateFillForEllipse(outline), fillColor)
                         .ChangedPixels);
                         .ChangedPixels);

+ 2 - 2
PixiEditor/Models/Tools/Tools/EraserTool.cs

@@ -2,7 +2,7 @@
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
-using PixiEditor.Models.Tools.ToolSettings;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 
 
 namespace PixiEditor.Models.Tools.Tools
 namespace PixiEditor.Models.Tools.Tools
@@ -19,7 +19,7 @@ namespace PixiEditor.Models.Tools.Tools
 
 
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         {
         {
-            return Erase(layer, coordinates, (int) Toolbar.GetSetting("ToolSize").Value);
+            return Erase(layer, coordinates, Toolbar.GetSetting<SizeSetting>("ToolSize").Value);
         }
         }
 
 
         public LayerChange[] Erase(Layer layer, Coordinates[] coordinates, int toolSize)
         public LayerChange[] Erase(Layer layer, Coordinates[] coordinates, int toolSize)

+ 3 - 4
PixiEditor/Models/Tools/Tools/LineTool.cs

@@ -1,12 +1,11 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Windows.Media;
 using System.Windows.Media;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
-using PixiEditor.Models.Tools.ToolSettings;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 
 
 namespace PixiEditor.Models.Tools.Tools
 namespace PixiEditor.Models.Tools.Tools
@@ -26,7 +25,7 @@ namespace PixiEditor.Models.Tools.Tools
             var pixels =
             var pixels =
                 BitmapPixelChanges.FromSingleColoredArray(
                 BitmapPixelChanges.FromSingleColoredArray(
                     CreateLine(coordinates, 
                     CreateLine(coordinates, 
-                        (int) Toolbar.GetSetting("ToolSize").Value, CapType.Square, CapType.Square), color);
+                        Toolbar.GetSetting<SizeSetting>("ToolSize").Value, CapType.Square, CapType.Square), color);
             return Only(pixels, layer);
             return Only(pixels, layer);
         }
         }
 
 

+ 4 - 5
PixiEditor/Models/Tools/Tools/PenTool.cs

@@ -1,10 +1,9 @@
 using System.Windows.Input;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Enums;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
-using PixiEditor.Models.Tools.ToolSettings;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 
 
 namespace PixiEditor.Models.Tools.Tools
 namespace PixiEditor.Models.Tools.Tools
@@ -12,20 +11,20 @@ namespace PixiEditor.Models.Tools.Tools
     public class PenTool : BitmapOperationTool
     public class PenTool : BitmapOperationTool
     {
     {
         public override ToolType ToolType => ToolType.Pen;
         public override ToolType ToolType => ToolType.Pen;
-        private readonly int _toolSizeIndex;
+        private readonly SizeSetting _toolSizeSetting;
 
 
         public PenTool()
         public PenTool()
         {
         {
             Cursor = Cursors.Pen;
             Cursor = Cursors.Pen;
             Tooltip = "Standard brush (B)";
             Tooltip = "Standard brush (B)";
             Toolbar = new BasicToolbar();
             Toolbar = new BasicToolbar();
-            _toolSizeIndex = Toolbar.Settings.IndexOf(Toolbar.GetSetting("ToolSize"));
+            _toolSizeSetting = Toolbar.GetSetting<SizeSetting>("ToolSize");
         }
         }
 
 
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         {
         {
             Coordinates startingCords = coordinates.Length > 1 ? coordinates[1] : coordinates[0];
             Coordinates startingCords = coordinates.Length > 1 ? coordinates[1] : coordinates[0];
-            var pixels = Draw(startingCords, coordinates[0], color, (int) Toolbar.Settings[_toolSizeIndex].Value);
+            var pixels = Draw(startingCords, coordinates[0], color, _toolSizeSetting.Value);
             return Only(pixels, layer);
             return Only(pixels, layer);
         }
         }
 
 

+ 4 - 3
PixiEditor/Models/Tools/Tools/RectangleTool.cs

@@ -6,6 +6,7 @@ using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 
 
 namespace PixiEditor.Models.Tools.Tools
 namespace PixiEditor.Models.Tools.Tools
 {
 {
@@ -21,12 +22,12 @@ namespace PixiEditor.Models.Tools.Tools
 
 
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         public override LayerChange[] Use(Layer layer, Coordinates[] coordinates, Color color)
         {
         {
-            int thickness = (int) Toolbar.GetSetting("ToolSize").Value;
+            int thickness = Toolbar.GetSetting<SizeSetting>("ToolSize").Value;
             BitmapPixelChanges pixels =
             BitmapPixelChanges pixels =
                 BitmapPixelChanges.FromSingleColoredArray(CreateRectangle(coordinates, thickness), color);
                 BitmapPixelChanges.FromSingleColoredArray(CreateRectangle(coordinates, thickness), color);
-            if ((bool) Toolbar.GetSetting("Fill").Value)
+            if (Toolbar.GetSetting<BoolSetting>("Fill").Value)
             {
             {
-                Color fillColor = (Color) Toolbar.GetSetting("FillColor").Value;
+                Color fillColor = Toolbar.GetSetting<ColorSetting>("FillColor").Value;
                 pixels.ChangedPixels.AddRangeOverride(
                 pixels.ChangedPixels.AddRangeOverride(
                     BitmapPixelChanges.FromSingleColoredArray
                     BitmapPixelChanges.FromSingleColoredArray
                             (CalculateFillForRectangle(coordinates[^1], coordinates[0], thickness), fillColor)
                             (CalculateFillForRectangle(coordinates[^1], coordinates[0], thickness), fillColor)

+ 2 - 2
PixiEditor/Models/Tools/Tools/SelectTool.cs

@@ -6,8 +6,8 @@ using System.Windows.Input;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Enums;
-using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using PixiEditor.ViewModels;
 using PixiEditor.ViewModels;
 
 
@@ -27,7 +27,7 @@ namespace PixiEditor.Models.Tools.Tools
 
 
         public override void OnMouseDown(MouseEventArgs e)
         public override void OnMouseDown(MouseEventArgs e)
         {
         {
-            Enum.TryParse((Toolbar.GetSetting("Mode").Value as ComboBoxItem)?.Content as string, out SelectionType);
+            Enum.TryParse((Toolbar.GetSetting<DropdownSetting>("Mode")?.Value as ComboBoxItem)?.Content as string, out SelectionType);
 
 
             _oldSelection = null;
             _oldSelection = null;
             if (ViewModelMain.Current.ActiveSelection != null &&
             if (ViewModelMain.Current.ActiveSelection != null &&

+ 2 - 2
PixiEditor/Properties/AssemblyInfo.cs

@@ -50,5 +50,5 @@ using System.Windows;
 // by using the '*' as shown below:
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
 // [assembly: AssemblyVersion("1.0.*")]
 
 
-[assembly: AssemblyVersion("0.1.3.1")]
-[assembly: AssemblyFileVersion("0.1.3.1")]
+[assembly: AssemblyVersion("0.1.3.2")]
+[assembly: AssemblyFileVersion("0.1.3.2")]

+ 13 - 3
PixiEditor/ViewModels/ViewModelMain.cs

@@ -21,6 +21,7 @@ using PixiEditor.Models.Enums;
 using PixiEditor.Models.Events;
 using PixiEditor.Models.Events;
 using PixiEditor.Models.IO;
 using PixiEditor.Models.IO;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
+using PixiEditor.Models.Processes;
 using PixiEditor.Models.Tools;
 using PixiEditor.Models.Tools;
 using PixiEditor.Models.Tools.Tools;
 using PixiEditor.Models.Tools.Tools;
 using PixiEditor.UpdateModule;
 using PixiEditor.UpdateModule;
@@ -329,8 +330,16 @@ namespace PixiEditor.ViewModels
 
 
         private void RestartApplication(object parameter)
         private void RestartApplication(object parameter)
         {
         {
-            Process.Start(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "PixiEditor.UpdateInstaller.exe"));
-            Application.Current.Shutdown();
+            try
+            {
+                ProcessHelper.RunAsAdmin(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "PixiEditor.UpdateInstaller.exe"));
+                Application.Current.Shutdown();
+            }
+            catch (Win32Exception)
+            {
+                MessageBox.Show("Couldn't update without administrator rights.", "Insufficient permissions",
+                    MessageBoxButton.OK, MessageBoxImage.Error);
+            }
         }
         }
 
 
         public async Task<bool> CheckForUpdate()
         public async Task<bool> CheckForUpdate()
@@ -338,7 +347,8 @@ namespace PixiEditor.ViewModels
             return await Task.Run(async () =>
             return await Task.Run(async () =>
             {
             {
                 bool updateAvailable = await UpdateChecker.CheckUpdateAvailable();
                 bool updateAvailable = await UpdateChecker.CheckUpdateAvailable();
-                bool updateFileDoesNotExists = !File.Exists($"update-{UpdateChecker.LatestReleaseInfo.TagName}.zip");
+                bool updateFileDoesNotExists = !File.Exists(
+                    Path.Join(UpdateDownloader.DownloadLocation, $"update-{UpdateChecker.LatestReleaseInfo.TagName}.zip"));
                 if (updateAvailable && updateFileDoesNotExists)
                 if (updateAvailable && updateFileDoesNotExists)
                 {
                 {
                     VersionText = "Downloading update...";
                     VersionText = "Downloading update...";

+ 16 - 4
PixiEditor/Views/MainWindow.xaml.cs

@@ -1,9 +1,12 @@
 using System;
 using System;
+using System.ComponentModel;
 using System.Diagnostics;
 using System.Diagnostics;
 using System.IO;
 using System.IO;
 using System.Reflection;
 using System.Reflection;
 using System.Windows;
 using System.Windows;
 using System.Windows.Input;
 using System.Windows.Input;
+using PixiEditor.Models.Processes;
+using PixiEditor.UpdateModule;
 using PixiEditor.ViewModels;
 using PixiEditor.ViewModels;
 
 
 namespace PixiEditor
 namespace PixiEditor
@@ -69,12 +72,21 @@ namespace PixiEditor
         private void mainWindow_Initialized(object sender, EventArgs e)
         private void mainWindow_Initialized(object sender, EventArgs e)
         {
         {
             string dir = AppDomain.CurrentDomain.BaseDirectory;
             string dir = AppDomain.CurrentDomain.BaseDirectory;
-            bool updateFileExists = Directory.GetFiles(dir, "update-*.zip").Length > 0;
+            UpdateDownloader.CreateTempDirectory();
+            bool updateFileExists = Directory.GetFiles(UpdateDownloader.DownloadLocation, "update-*.zip").Length > 0;
             string updaterPath = Path.Join(dir, "PixiEditor.UpdateInstaller.exe");
             string updaterPath = Path.Join(dir, "PixiEditor.UpdateInstaller.exe");
             if (updateFileExists && File.Exists(updaterPath))
             if (updateFileExists && File.Exists(updaterPath))
-            {                
-                Process.Start(updaterPath);
-                Close();
+            {
+                try
+                {
+                    ProcessHelper.RunAsAdmin(updaterPath);
+                    Close();
+                }
+                catch(Win32Exception)
+                {
+                    MessageBox.Show("Couldn't update without administrator rights.", "Insufficient permissions", 
+                        MessageBoxButton.OK, MessageBoxImage.Error);
+                }
             }
             }
         }
         }
     }
     }

+ 41 - 8
PixiEditorTests/ModelsTests/ToolsTests/ToolbarTests/ToolbarBaseTests.cs

@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using PixiEditor.Models.Tools.ToolSettings;
+using PixiEditor.Models.Tools.ToolSettings.Settings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using Xunit;
 using Xunit;
 
 
@@ -10,7 +7,6 @@ namespace PixiEditorTests.ModelsTests.ToolsTests.ToolbarTests
     [Collection("Application collection")]
     [Collection("Application collection")]
     public class ToolbarBaseTests
     public class ToolbarBaseTests
     {
     {
-
         [StaFact]
         [StaFact]
         public void TestThatGetSettingReturnsCorrectSetting()
         public void TestThatGetSettingReturnsCorrectSetting()
         {
         {
@@ -23,22 +19,59 @@ namespace PixiEditorTests.ModelsTests.ToolsTests.ToolbarTests
             Assert.Equal(settingName,setting.Name);
             Assert.Equal(settingName,setting.Name);
         }
         }
 
 
+        [StaFact]
+        public void TestThatGenericGetSettingReturnsSettingWithCorrectType()
+        {
+            const string settingName = "test";
+            const bool settingValue = true;
+            Setting<bool> expected = new BoolSetting(settingName, settingValue);
+
+            BasicToolbar toolbar = new BasicToolbar();
+            toolbar.Settings.Add(expected);
+
+            BoolSetting actual = toolbar.GetSetting<BoolSetting>(settingName);
+
+            Assert.Equal(expected.Value, actual.Value);
+        }
+
+        [StaFact]
+        public void TestThatGenericGetSettingReturnsNullWhenSettingIsNotFound()
+        {
+            BasicToolbar toolbar = new BasicToolbar();
+
+            BoolSetting actual = toolbar.GetSetting<BoolSetting>("invalid");
+
+            Assert.Null(actual);
+        }
+
+        [StaFact]
+        public void TestThatGenericGetSettingReturnsNullWhenSettingHasWrongType()
+        {
+            const string settingName = "test";
+            BasicToolbar toolbar = new BasicToolbar();
+            toolbar.Settings.Add(new BoolSetting(settingName));
+
+            SizeSetting actual = toolbar.GetSetting<SizeSetting>(settingName);
+
+            Assert.Null(actual);
+        }
+
         [StaFact]
         [StaFact]
         public void TestThatSaveToolbarSettingsSavesSettingAndLoadsItIntoNewToolbar()
         public void TestThatSaveToolbarSettingsSavesSettingAndLoadsItIntoNewToolbar()
         {
         {
             BasicToolbar toolbar = new BasicToolbar();
             BasicToolbar toolbar = new BasicToolbar();
 
 
-            toolbar.Settings[0].Value = 5;
+            toolbar.GetSetting<SizeSetting>("ToolSize").Value = 5;
 
 
             toolbar.SaveToolbarSettings();
             toolbar.SaveToolbarSettings();
 
 
             BasicShapeToolbar shapeToolbar = new BasicShapeToolbar();
             BasicShapeToolbar shapeToolbar = new BasicShapeToolbar();
 
 
-            Assert.NotEqual(5, (int)shapeToolbar.GetSetting("ToolSize").Value);
+            Assert.NotEqual(5, shapeToolbar.GetSetting<SizeSetting>("ToolSize").Value);
 
 
             shapeToolbar.LoadSharedSettings();
             shapeToolbar.LoadSharedSettings();
 
 
-            Assert.Equal(5, (int)shapeToolbar.GetSetting("ToolSize").Value);
+            Assert.Equal(5, shapeToolbar.GetSetting<SizeSetting>("ToolSize").Value);
         }
         }
     }
     }
 }
 }

+ 1 - 31
windows-x64-release.yml

@@ -43,36 +43,6 @@ steps:
   inputs:
   inputs:
     filePath: 'assemblyVerReader.ps1'
     filePath: 'assemblyVerReader.ps1'
 
 
-- task: DotNetCoreCLI@2
-  displayName: "Build release PixiEditor Self-contained"
-  inputs:
-    command: 'publish'
-    publishWebProjects: false
-    projects: '**/PixiEditor.csproj'
-    arguments: '-o "Builds/PixiEditor-x64" --self-contained=true -r "win-x64" -c Release'
-    zipAfterPublish: false
-
-- task: CopyFiles@2
-  displayName: "Copy updater to PixiEditor target dir"
-  inputs:
-    SourceFolder: 'UpdateInstaller'
-    Contents: '**'
-    TargetFolder: 'Builds/PixiEditor-x64/PixiEditor/'
-    flattenFolders: true
-
-- task: PowerShell@2
-  displayName: "Compile installer"
-  inputs:
-    targetType: 'inline'
-    script: '& "$env:userprofile\.nuget\packages\tools.innosetup\6.0.5\tools\ISCC.exe" Installer\installer-setup-x64.iss'
-  
-- task: PublishPipelineArtifact@1
-  displayName: "Publish artifact"
-  inputs:
-    targetPath: 'Installer/Assets/PixiEditor-x64'
-    artifact: 'PixiEditor-setup-x64.exe'
-    publishLocation: 'pipeline'
-
 - task: DotNetCoreCLI@2
 - task: DotNetCoreCLI@2
   displayName: "Build release PixiEditor x64 light"
   displayName: "Build release PixiEditor x64 light"
   inputs:
   inputs:
@@ -115,5 +85,5 @@ steps:
   displayName: "Publish artifact"
   displayName: "Publish artifact"
   inputs:
   inputs:
     targetPath: 'Installer/Assets/PixiEditor-x64-light/'
     targetPath: 'Installer/Assets/PixiEditor-x64-light/'
-    artifact: 'PixiEditor-setup-x64-light.exe'
+    artifact: 'PixiEditor-setup-x64.exe'
     publishLocation: 'pipeline'
     publishLocation: 'pipeline'

+ 1 - 31
windows-x86-release.yml

@@ -42,36 +42,6 @@ steps:
     arguments: '-o "UpdateInstaller" -r "win-x86" --self-contained=false -p:PublishSingleFile=true -c Release'
     arguments: '-o "UpdateInstaller" -r "win-x86" --self-contained=false -p:PublishSingleFile=true -c Release'
     zipAfterPublish: false
     zipAfterPublish: false
 
 
-- task: DotNetCoreCLI@2
-  displayName: "Build release PixiEditor Self-contained"
-  inputs:
-    command: 'publish'
-    publishWebProjects: false
-    projects: '**/PixiEditor.csproj'
-    arguments: '-o "Builds/PixiEditor-x86" --self-contained=true -r "win-x86" -c Release'
-    zipAfterPublish: false
-
-- task: CopyFiles@2
-  displayName: "Copy updater to PixiEditor target dir"
-  inputs:
-    SourceFolder: 'UpdateInstaller'
-    Contents: '**'
-    TargetFolder: 'Builds/PixiEditor-x86/PixiEditor'
-    flattenFolders: true
-
-- task: PowerShell@2
-  displayName: "Compile installer"
-  inputs:
-    targetType: 'inline'
-    script: '& "$env:userprofile\.nuget\packages\tools.innosetup\6.0.5\tools\ISCC.exe" Installer\installer-setup-x86.iss'
-  
-- task: PublishPipelineArtifact@1
-  displayName: "Publish artifact"
-  inputs:
-    targetPath: 'Installer/Assets/PixiEditor-x86/'
-    artifact: 'PixiEditor-setup-x86.exe'
-    publishLocation: 'pipeline'
-
 - task: DotNetCoreCLI@2
 - task: DotNetCoreCLI@2
   displayName: "Build release PixiEditor x86 light"
   displayName: "Build release PixiEditor x86 light"
   inputs:
   inputs:
@@ -114,5 +84,5 @@ steps:
   displayName: "Publish artifact"
   displayName: "Publish artifact"
   inputs:
   inputs:
     targetPath: 'Installer/Assets/PixiEditor-x86-light/'
     targetPath: 'Installer/Assets/PixiEditor-x86-light/'
-    artifact: 'PixiEditor-setup-x86-light.exe'
+    artifact: 'PixiEditor-setup-x86.exe'
     publishLocation: 'pipeline'
     publishLocation: 'pipeline'