diff --git a/DnsServerSystemTrayApp/App.config b/DnsServerSystemTrayApp/App.config
deleted file mode 100644
index 4bfa0056..00000000
--- a/DnsServerSystemTrayApp/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/DnsServerSystemTrayApp/DnsServerSystemTrayApp.csproj b/DnsServerSystemTrayApp/DnsServerSystemTrayApp.csproj
index 273993b9..af911783 100644
--- a/DnsServerSystemTrayApp/DnsServerSystemTrayApp.csproj
+++ b/DnsServerSystemTrayApp/DnsServerSystemTrayApp.csproj
@@ -1,48 +1,17 @@
-
-
-
+
+
- Debug
- AnyCPU
- {2F91BD07-2CEE-47FA-8486-457B54612B4C}
WinExe
+ net5.0-windows
+ true
+ true
DnsServerSystemTrayApp
DnsServerSystemTrayApp
- v4.8
- 512
- false
- true
-
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
+ Shreyas Zare
logo2.ico
+ 2.0.0.0
-
-
-
-
-
False
..\..\TechnitiumLibrary\bin\TechnitiumLibrary.IO.dll
@@ -52,45 +21,16 @@
-
-
- Form
-
-
- frmAbout.cs
-
-
- Form
-
-
- frmManageDnsProviders.cs
-
-
-
-
-
-
- frmAbout.cs
-
-
- frmManageDnsProviders.cs
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
- Designer
-
-
+
True
Resources.resx
True
-
SettingsSingleFileGenerator
Settings.Designer.cs
-
+
True
Settings.settings
True
@@ -99,5 +39,8 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/DnsServerSystemTrayApp/Properties/AssemblyInfo.cs b/DnsServerSystemTrayApp/Properties/AssemblyInfo.cs
deleted file mode 100644
index 6b1e9ec2..00000000
--- a/DnsServerSystemTrayApp/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Technitium DNS Server")]
-[assembly: AssemblyDescription("Technitium DNS Server")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Technitium")]
-[assembly: AssemblyProduct("Technitium DNS Server")]
-[assembly: AssemblyCopyright("Copyright © 2020")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("2f91bd07-2cee-47fa-8486-457b54612b4c")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.3.2.0")]
-[assembly: AssemblyFileVersion("1.3.2.0")]
diff --git a/DnsService/DnsService.cs b/DnsService/DnsService.cs
index 9879082b..8982f463 100644
--- a/DnsService/DnsService.cs
+++ b/DnsService/DnsService.cs
@@ -34,10 +34,25 @@ namespace DnsService
protected override void OnStart(string[] args)
{
- _service = new WebService(null, new Uri("https://go.technitium.com/?id=22"));
+ _service = new WebService(getConfigFolder(), new Uri("https://go.technitium.com/?id=22"));
_service.Start();
}
+ ///
+ /// If the service file path has the configuration files, use it, otherwise use the localapppath folder.
+ ///
+ /// The configuration path.
+ private string getConfigFolder()
+ {
+ string userConfigFolder = String.Concat(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"\Technitium\DNSServer");
+
+ if (System.IO.Directory.Exists(Environment.CurrentDirectory))
+ {
+ return Environment.CurrentDirectory;
+ }
+ return userConfigFolder;
+ }
+
protected override void OnStop()
{
_service.Dispose();
diff --git a/DnsService/DnsService.csproj b/DnsService/DnsService.csproj
index 1fec5bf9..10c6cb8a 100644
--- a/DnsService/DnsService.csproj
+++ b/DnsService/DnsService.csproj
@@ -1,83 +1,30 @@
-
-
-
+
+
- Debug
- AnyCPU
- {7873B2B8-01BA-48BC-B4B0-0857FFD873C9}
WinExe
+ net5.0-windows7.0
+ true
+
DnsService
DnsService
- v4.8
- 512
- false
-
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
-
-
- AnyCPU
- none
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
logo2.ico
+ 2.6.0.0
-
-
-
..\..\TechnitiumLibrary\bin\TechnitiumLibrary.Net.Firewall.dll
-
-
- Component
-
-
- ProjectInstaller.cs
-
-
- Component
-
-
- DnsService.cs
-
-
-
-
-
-
- ProjectInstaller.cs
-
-
- DnsService.cs
-
-
-
-
-
-
{4494b79b-588c-41f2-95ad-0897123af154}
DnsServerCore
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DnsService/ProjectInstaller.Designer.cs b/DnsService/ProjectInstaller.Designer.cs
deleted file mode 100644
index 2fe7732f..00000000
--- a/DnsService/ProjectInstaller.Designer.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-namespace DnsService
-{
- partial class ProjectInstaller
- {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Component Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
- {
- this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
- this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
- //
- // serviceProcessInstaller1
- //
- this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
- this.serviceProcessInstaller1.Password = null;
- this.serviceProcessInstaller1.Username = null;
- //
- // serviceInstaller1
- //
- this.serviceInstaller1.Description = "Technitium DNS Server";
- this.serviceInstaller1.DisplayName = "Technitium DNS Server";
- this.serviceInstaller1.ServiceName = "DnsService";
- this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
- //
- // ProjectInstaller
- //
- this.Installers.AddRange(new System.Configuration.Install.Installer[] {
- this.serviceProcessInstaller1,
- this.serviceInstaller1});
-
- }
-
- #endregion
-
- private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
- private System.ServiceProcess.ServiceInstaller serviceInstaller1;
- }
-}
\ No newline at end of file
diff --git a/DnsService/ProjectInstaller.cs b/DnsService/ProjectInstaller.cs
deleted file mode 100644
index fa6da0c8..00000000
--- a/DnsService/ProjectInstaller.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-Technitium Library
-Copyright (C) 2018 Shreyas Zare (shreyas@technitium.com)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-*/
-
-using System.Collections;
-using System.ComponentModel;
-using System.Configuration.Install;
-using System.ServiceProcess;
-
-namespace DnsService
-{
- [RunInstaller(true)]
- public partial class ProjectInstaller : Installer
- {
- public ProjectInstaller()
- {
- InitializeComponent();
- }
-
- protected override void OnBeforeInstall(IDictionary savedState)
- {
- try
- {
- foreach (ServiceController sc in ServiceController.GetServices())
- {
- if (sc.ServiceName == serviceInstaller1.ServiceName)
- {
- //found previously installed service
- //stop service
- if (sc.Status == ServiceControllerStatus.Running)
- sc.Stop();
-
- //uninstall service
- using (ServiceInstaller si = new ServiceInstaller())
- {
- si.Context = new InstallContext();
- si.ServiceName = serviceInstaller1.ServiceName;
- si.Uninstall(null);
- }
-
- break;
- }
- }
- }
- catch
- { }
- }
-
- protected override void OnAfterInstall(IDictionary savedState)
- {
- try
- {
- using (ServiceController sc = new ServiceController(serviceInstaller1.ServiceName))
- {
- sc.Start();
- }
- }
- catch
- { }
- }
-
- protected override void OnBeforeUninstall(IDictionary savedState)
- {
- try
- {
- using (ServiceController sc = new ServiceController(serviceInstaller1.ServiceName))
- {
- sc.Stop();
- }
- }
- catch
- { }
- }
- }
-}
diff --git a/DnsService/ProjectInstaller.resx b/DnsService/ProjectInstaller.resx
deleted file mode 100644
index 235f1b0b..00000000
--- a/DnsService/ProjectInstaller.resx
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- 17, 56
-
-
- 196, 17
-
-
- False
-
-
\ No newline at end of file
diff --git a/DnsService/Properties/AssemblyInfo.cs b/DnsService/Properties/AssemblyInfo.cs
deleted file mode 100644
index 2bd1169f..00000000
--- a/DnsService/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Technitium DNS Server")]
-[assembly: AssemblyDescription("Technitium DNS Server")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Technitium")]
-[assembly: AssemblyProduct("Technitium DNS Server")]
-[assembly: AssemblyCopyright("Copyright © 2021")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("7873b2b8-01ba-48bc-b4b0-0857ffd873c9")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("5.6.0.0")]
-[assembly: AssemblyFileVersion("5.6.0.0")]
diff --git a/DnsServiceSetup/Chocolatey/.skipAutoUninstall b/DnsServiceSetup/Chocolatey/.skipAutoUninstall
new file mode 100644
index 00000000..e69de29b
diff --git a/DnsServiceSetup/Chocolatey/VERIFICATION.txt b/DnsServiceSetup/Chocolatey/VERIFICATION.txt
new file mode 100644
index 00000000..994aea82
--- /dev/null
+++ b/DnsServiceSetup/Chocolatey/VERIFICATION.txt
@@ -0,0 +1 @@
+I am the package maintainer AND the software developer for Technitium DNS Server.
\ No newline at end of file
diff --git a/DnsServiceSetup/Chocolatey/build.ps1 b/DnsServiceSetup/Chocolatey/build.ps1
new file mode 100644
index 00000000..e35373d2
--- /dev/null
+++ b/DnsServiceSetup/Chocolatey/build.ps1
@@ -0,0 +1,70 @@
+$buildfolder = "build/"
+$installerfilename = "dnsserverinstall"
+Write-Host "DNS Server Chocolatey Package Builder"
+Write-Host "-------------------------------------"
+Write-Host "Create build folders..."
+New-Item -ItemType Directory -Path "${buildfolder}" -ErrorAction Ignore | Out-Null
+New-Item -ItemType Directory -Path "${buildfolder}/tools" -ErrorAction Ignore | Out-Null
+
+Write-Host "Building Setup..."
+iscc "/O./${buildfolder}/tools" "/F$installerfilename" ..\Windows\DnsServiceSetup.iss | Out-Null
+if ($LASTEXITCODE -ne 0) {
+ Write-Host "Error: Inno Setup Compile Failed!"
+ return
+} else {
+ Write-Host "Build Success!"
+}
+
+$installerfilename = "${installerfilename}.exe"
+$version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("./${buildfolder}/tools/${installerfilename}").ProductVersion
+Write-Host "Version: $version"
+if (!$version) {
+ Write-Host "Error: Could not get Product Version from Installer File"
+ return
+}
+Write-Host "Copying files..."
+
+$nuspecfilename = ""
+
+$files = Get-ChildItem -Path .
+foreach ($file in $files) {
+ if ($file.Name.StartsWith("build")) {
+ #Skip any build files starting with the word build (ie: build.ps1)
+ continue
+ }
+
+ if ($file.Name.EndsWith(".template")) {
+ Write-Host "Build $($file.Name)"
+ $outfilename = ($file.Name -replace ".{9}$")
+ $templater = Get-Content "$($file.Name)" -Raw
+
+ $templater = $templater -replace "%fileversion%", "$version"
+ $templater = $templater -replace "%installfile%", "$installerfilename"
+
+ $outpath = "${buildfolder}/"
+ if (!$outfilename.EndsWith(".nuspec")) {
+ $outpath = "${outpath}/tools/"
+ } else {
+ $nuspecfilename = $outfilename
+ }
+
+ $templater | Out-File "${outpath}/${outfilename}"
+ } else {
+ Write-Host "Copy $($file.Name)"
+
+ $outpath = "${buildfolder}/"
+ if (!$file.Name.EndsWith(".nuspec")) {
+ $outpath = "${outpath}/tools/"
+ } else {
+ $nuspecfilename = $file.Name
+ }
+
+ Copy-Item "$($file.Name)" "${outpath}/$($file.Name)"
+ }
+}
+
+Write-Host "Create Package..."
+cpack ${buildfolder}/${nuspecfilename} --out ../Release
+Write-Host "Remove Build Folder"
+Remove-Item -Path "${buildfolder}" -Recurse
+Write-Host "COMPLETE!"
\ No newline at end of file
diff --git a/DnsServiceSetup/Chocolatey/chocolateyInstall.ps1.template b/DnsServiceSetup/Chocolatey/chocolateyInstall.ps1.template
new file mode 100644
index 00000000..d80bdbb3
--- /dev/null
+++ b/DnsServiceSetup/Chocolatey/chocolateyInstall.ps1.template
@@ -0,0 +1,14 @@
+$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
+$file = "$toolsDir/%installfile%"
+
+$packageArgs = @{
+ packageName = $env:ChocolateyPackageName
+ fileType = 'EXE'
+
+ file = $file
+
+ silentArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /LOG=`"$($env:TEMP)\$($env:chocolateyPackageName).$($env:chocolateyPackageVersion).Install.log`" /skipnet=true"
+ validExitCodes= @(0)
+}
+
+Install-ChocolateyInstallPackage @packageArgs
\ No newline at end of file
diff --git a/DnsServiceSetup/Chocolatey/chocolateyUninstall.ps1 b/DnsServiceSetup/Chocolatey/chocolateyUninstall.ps1
new file mode 100644
index 00000000..959fd313
--- /dev/null
+++ b/DnsServiceSetup/Chocolatey/chocolateyUninstall.ps1
@@ -0,0 +1,31 @@
+$ErrorActionPreference = 'Stop';
+
+$packageName = 'technitiumdnsserver'
+$softwareName = 'Technitium DNS Server*'
+$installerType = 'EXE'
+
+$silentArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /LOG=`"$($env:TEMP)\$($env:chocolateyPackageName).$($env:chocolateyPackageVersion).Uninstall.log`""
+$validExitCodes = @(0)
+
+$uninstalled = $false
+[array]$key = Get-UninstallRegistryKey -SoftwareName $softwareName
+
+if ($key.Count -eq 1) {
+ $key | ForEach-Object {
+ $file = "$($_.UninstallString.Trim('"'))"
+
+ Uninstall-ChocolateyPackage `
+ -PackageName $packageName `
+ -FileType $installerType `
+ -SilentArgs "$silentArgs" `
+ -ValidExitCodes $validExitCodes `
+ -File "$file"
+ }
+} elseif ($key.Count -eq 0) {
+ Write-Warning "$packageName has already been uninstalled by other means."
+} elseif ($key.Count -gt 1) {
+ Write-Warning "$key.Count matches found!"
+ Write-Warning "To prevent accidental data loss, no programs will be uninstalled."
+ Write-Warning "Please alert package maintainer the following keys were matched:"
+ $key | ForEach-Object {Write-Warning "- $_.DisplayName"}
+}
\ No newline at end of file
diff --git a/DnsServiceSetup/Chocolatey/technitiumdnsserver.nuspec.template b/DnsServiceSetup/Chocolatey/technitiumdnsserver.nuspec.template
new file mode 100644
index 00000000..12791a10
--- /dev/null
+++ b/DnsServiceSetup/Chocolatey/technitiumdnsserver.nuspec.template
@@ -0,0 +1,50 @@
+
+
+
+ technitiumdnsserver
+ %fileversion%
+ Shreyas Zare
+ Technitium DNS Server
+ Shreyas Zare, Contributors
+ https://technitium.com/dns/
+ https://github.com/TechnitiumSoftware/DnsServer
+ https://github.com/TechnitiumSoftware/DnsServer/issues
+ Shreyas Zare
+ dns dhcp
+ https://technitium.com/img/logo25x25.png
+
+
+
+ Open Source DNS and DHCP Server.
+
+Technitium DNS Server is an open source tool that can be used for self hosting a local DNS server for privacy & security or, used for experimentation/testing by software developers on their computer. It works out-of-the-box with no or minimal configuration and provides a user friendly web console accessible using any web browser.
+
+Features:
+* Works on Windows, Linux, macOS and Raspberry Pi.
+* Installs in just a minute and works out-of-the-box with zero configuration.
+* Block Ads using one or more block list URLs.
+* Run [DNS-over-TLS](https://en.wikipedia.org/wiki/DNS_over_TLS) and [DNS-over-HTTPS](https://en.wikipedia.org/wiki/DNS_over_HTTPS) DNS service on your network.
+* Use public DNS resolvers like Cloudflare, Google & Quad9 with DNS-over-TLS and DNS-over-HTTPS protocols as forwarders.
+* Advance caching with features like serve stale, prefetching and auto prefetching.
+* Supports working as an authoritative as well as a recursive DNS server.
+* CNAME cloaking feature to block domain names that resolve to CNAME which are blocked.
+* QNAME minimization support in recursive resolver [draft-ietf-dnsop-rfc7816bis-04](https://tools.ietf.org/html/draft-ietf-dnsop-rfc7816bis-04).
+* QNAME randomization support for UDP transport protocol [draft-vixie-dnsext-dns0x20-00](https://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00).
+* ANAME propriety record support to allow using CNAME like feature at zone root.
+* Primary, Secondary, Stub and Conditional Forwarder zone support.
+* Host domain names on your own DNS server.
+* Wildcard sub domain support.
+* Enable/disable zones and records to allow testing with ease.
+* Built-in DNS Client with option to import responses to local zone.
+* Supports out-of-order DNS request processing for DNS-over-TCP and DNS-over-TLS protocols.
+* Built-in DHCP Server that can work for multiple networks.
+* IPv6 support in DNS server core.
+* HTTP & SOCKS5 proxy support which can be configured to route DNS over Tor Network or use Cloudflare's hidden DNS resolver.
+* Web console portal for easy configuration using any web browser.
+* Built-in system logging and query logging.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/DnsServiceSetup.iss b/DnsServiceSetup/Windows/DnsServiceSetup.iss
new file mode 100644
index 00000000..8f523c8d
--- /dev/null
+++ b/DnsServiceSetup/Windows/DnsServiceSetup.iss
@@ -0,0 +1,70 @@
+#define PRODUCT_NAME "DNS Server"
+#define APPID "{{9B86AC7F-53B3-4E31-B245-D4602D16F5C8}"
+#define PRODUCT_VERSION "5.6"
+#define COMPANY "Technitium"
+#define TITLE "Technitium DNS Server"
+#define APP_URL "https://technitium.com/dns/"
+
+#define FILES_LOCATION "..\..\DnsService\bin\Release\net5.0-windows7.0"
+#define TRAYAPP_LOCATION "..\..\DnsServerSystemTrayApp\obj\Release"
+#define TRAYAPP_FILENAME "DnsServerSystemTrayApp.exe"
+
+#define SERVICE_NAME "DnsService"
+#define SERVICE_FILE "DnsService.exe"
+#define SERVICE_DISPLAY_NAME "Technitium DNS Server"
+#define SERVICE_DESCRIPTION "Technitium DNS Server"
+#define CONFIG_FOLDER_COMPANY "{localappdata}\Technitium"
+#define CONFIG_FOLDER_FULL CONFIG_FOLDER_COMPANY + "\DNS Server"
+
+#define LEGACY_INSTALLER_APPID "{9B86AC7F-53B3-4E31-B245-D4602D16F5C8}"
+#define LEGACY_INSTALLER_CONFIG_PATH "{commonpf32}\Technitium\DNS Server\config"
+
+[Setup]
+PrivilegesRequired=admin
+AppName={#TITLE}
+AppVersion={#PRODUCT_VERSION}
+AppId={#APPID}
+DefaultDirName={commonpf32}\{#COMPANY}\{#PRODUCT_NAME}
+DefaultGroupName={#COMPANY}
+DisableProgramGroupPage=yes
+AppCopyright=Copyright (c) 2021 {#COMPANY}
+AppPublisher={#COMPANY}
+AppSupportURL={#APP_URL}
+AppPublisherURL={#APP_URL}
+
+OutputDir=..\Release
+OutputBaseFilename=DnsServiceSetup
+CloseApplications=no
+Compression=lzma2/max
+SetupIconFile=logo.ico
+WizardSmallImageFile=logo.bmp
+
+[Files]
+Source: "{#TRAYAPP_LOCATION}\{#TRAYAPP_FILENAME}"; DestDir: "{app}";
+Source: "{#FILES_LOCATION}\*.*"; Excludes: "*.pdb,*.runtimeconfig.dev.json"; DestDir: "{app}"; Flags: recursesubdirs;
+
+[Tasks]
+Name: "desktopicon"; Description: "Create an icon on the &desktop";
+
+[CustomMessages]
+RemoveConfig=Do you want to remove the configuration files?%n%nClick No to keep your settings.
+RemoveConfigFail=Some configuration files could not be automatically removed.
+ServiceInstallFailure=The DNS Service could not be installed. %1
+ServiceManagerUnavailable=The Service Manager is not available!
+DependenciesDir=.
+
+[Icons]
+Name: "{userprograms}\Technitium DNS Server"; Comment: "DNS Server Tray App"; Filename: "{app}\DnsServerSystemTrayApp.exe"; WorkingDir: "{app}\"; Flags: createonlyiffileexists
+Name: "{userdesktop}\Technitium DNS Server"; Filename: "{app}\DnsServerSystemTrayApp.exe"; WorkingDir: "{app}\"; Flags: createonlyiffileexists; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\DnsServerSystemTrayApp.exe"; Description: "Run the Tray App"; Flags: postinstall nowait;
+
+;Include the dependency code
+#include "depend\lang\english.iss"
+#include "depend\products.iss"
+#include "depend\products\dotnet5.iss"
+
+[Code]
+//Include the setup code
+#include "DnsServiceSetup.pas"
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/DnsServiceSetup.pas b/DnsServiceSetup/Windows/DnsServiceSetup.pas
new file mode 100644
index 00000000..9e7ce1e8
--- /dev/null
+++ b/DnsServiceSetup/Windows/DnsServiceSetup.pas
@@ -0,0 +1,229 @@
+//Include the sc functionality
+#include "service.pas"
+#include "helper.pas"
+#include "legacy.pas"
+
+{
+ Skips the tasks page if it is an upgrade install
+}
+function ShouldSkipPage(PageID: Integer): Boolean;
+begin
+ Result := (PageID = wpSelectTasks) and IsUpgrade;
+end;
+
+function InitializeSetup(): boolean;
+begin
+ //Specify the dependencies to install here
+ dotnet_5_desktop();
+ if IsLegacyInstallerInstalled or IsLegacyConfigAvailable then begin
+ AdditionalMemo := AdditionalMemo + #13#10 + #13#10 + 'Previous Version:';
+ end;
+ if IsLegacyInstallerInstalled then begin
+ AdditionalMemo := AdditionalMemo + #13#10 + ' Remove Legacy Installer';
+ end;
+ if IsLegacyConfigAvailable then begin
+ AdditionalMemo := AdditionalMemo + #13#10 + ' Migrate Configuration';
+ end;
+ Result := true;
+end;
+
+{
+ Kills the tray app
+}
+procedure KillTrayApp;
+begin
+ TaskKill('{#TRAYAPP_FILENAME}');
+end;
+
+{
+ Stops the service
+}
+procedure DoStopService();
+var
+ stopCounter: Integer;
+ serviceStopped: Boolean;
+begin
+ stopCounter := 0;
+ if IsServiceInstalled('{#SERVICE_NAME}') then begin
+ Log('Service: Already installed');
+ if IsServiceRunning('{#SERVICE_NAME}') then begin
+ Log('Service: Already running, stopping service...');
+ StopService('{#SERVICE_NAME}');
+
+ while IsServiceRunning('{#SERVICE_NAME}') do
+ begin
+ if stopCounter > 2 then begin
+ Log('Service: Waited too long to stop, killing task...');
+ TaskKill('{#SERVICE_FILE}');
+ Log('Service: Task killed');
+ break;
+ end else begin
+ Log('Service: Waiting for stop');
+ Sleep(2000);
+ stopCounter := stopCounter + 1
+ end;
+ end;
+ if stopCounter < 3 then Log('Service: Stopped');
+ end;
+ end;
+end;
+
+{
+ Removes the service from the computer
+}
+procedure DoRemoveService();
+var
+ stopCounter: Integer;
+begin
+ stopCounter := 0;
+ if IsServiceInstalled('{#SERVICE_NAME}') then begin
+ Log('Service: Already installed, begin remove...');
+ if IsServiceRunning('{#SERVICE_NAME}') then begin
+ Log('Service: Already running, stopping...');
+ StopService('{#SERVICE_NAME}');
+ while IsServiceRunning('{#SERVICE_NAME}') do
+ begin
+ if stopCounter > 2 then begin
+ Log('Service: Waited too long to stop, killing task...');
+ TaskKill('{#SERVICE_FILE}');
+ Log('Service: Task killed');
+ break;
+ end else begin
+ Log('Service: Waiting for stop');
+ Sleep(2000);
+ stopCounter := stopCounter + 1
+ end;
+ end;
+ end;
+
+ stopCounter := 0;
+ Log('Service: Removing...');
+ RemoveService('{#SERVICE_NAME}');
+ while IsServiceInstalled('{#SERVICE_NAME}') do
+ begin
+ if stopCounter > 2 then begin
+ Log('Service: Waited too long to remove, continuing');
+ break;
+ end else begin
+ Log('Service: Waiting for removal');
+ Sleep(2000);
+ stopCounter := stopCounter + 1
+ end;
+ end;
+ if stopCounter < 3 then Log('Service: Removed');
+ end;
+end;
+
+{
+ Installs the service onto the computer
+}
+procedure DoInstallService();
+var
+ InstallSuccess: Boolean;
+ StartServiceSuccess: Boolean;
+ MsgResult: Integer;
+ stopCounter: Integer;
+begin
+ stopCounter := 0;
+ if IsServiceInstalled('{#SERVICE_NAME}') then begin
+ Log('Service: Already installed, skip install service');
+ end else begin
+ Log('Service: Begin Install');
+ InstallSuccess := InstallService(ExpandConstant('{app}\DnsService.exe'), '{#SERVICE_NAME}', '{#SERVICE_DISPLAY_NAME}', '{#SERVICE_DESCRIPTION}', SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START);
+ if not InstallSuccess then
+ begin
+ Log('Service: Install Fail ' + ServiceErrorToMessage(GetLastError()));
+ SuppressibleMsgBox(ExpandConstant('{cm:ServiceInstallFailure,' + ServiceErrorToMessage(GetLastError()) + '}'), mbCriticalError, MB_OK, IDOK);
+ end else begin
+ Log('Service: Install Success, Starting...');
+ StartService('{#SERVICE_NAME}');
+
+ while IsServiceRunning('{#SERVICE_NAME}') <> true do
+ begin
+ if stopCounter > 3 then begin
+ Log('Service: Waited too long to start, continue');
+ break;
+ end else begin
+ Log('Service: still starting')
+ Sleep(2000);
+ stopCounter := stopCounter + 1
+ end;
+ end;
+ if stopCounter < 4 then Log('Service: Started');
+ end;
+ end;
+end;
+
+{
+ Removes the generated configuration
+}
+procedure RemoveConfiguration();
+var
+ DeleteSuccess: Boolean;
+begin
+ Log('Delete configuration folder');
+ DeleteSuccess := DelTree(ExpandConstant('{#CONFIG_FOLDER_FULL}'), True, True, True);
+ if not DeleteSuccess then
+ begin
+ Log('Not all configuration files were deleted succesfully in ' + ExpandConstant('{#CONFIG_FOLDER_FULL}'));
+ SuppressibleMsgBox(ExpandConstant('{cm:RemoveConfigFail}'), mbError, MB_OK, IDOK);
+ end;
+end;
+
+{
+ Prompts to remove the configuration
+ On unattended installs, will keep config unless /removeconfig=true is supplied
+}
+procedure PromptRemoveConfiguration();
+begin
+ case ExpandConstant('{param:removeconfig|prompt}') of
+ 'prompt':
+ if SuppressibleMsgBox(ExpandConstant('{cm:RemoveConfig}'), mbConfirmation, MB_YESNO or MB_DEFBUTTON2, IDNO) = IDYES then
+ begin
+ RemoveConfiguration();
+ end;
+ 'true':
+ RemoveConfiguration();
+ end;
+end;
+
+procedure CurStepChanged(CurStep: TSetupStep);
+begin
+ if CurStep = ssInstall then begin //Step happens just before installing files
+ WizardForm.StatusLabel.Caption := 'Stopping Tray App...';
+ KillTrayApp(); //Stop the tray app if running
+
+ if IsLegacyInstallerInstalled or IsLegacyConfigAvailable then begin
+ WizardForm.StatusLabel.Caption := 'Stopping Service...';
+ DoStopService(); //Stop the service if running
+
+ WizardForm.StatusLabel.Caption := 'Removing Legacy Installer...';
+ UninstallLegacyInstaller(); //Uninstall Legacy Installer if Installed already
+
+ WizardForm.StatusLabel.Caption := 'Migrating Configuration...';
+ MigrateConfiguration(); //Shift configuration into correct path
+ end else begin
+ WizardForm.StatusLabel.Caption := 'Uninstalling Service...';
+ DoRemoveService(); //Stop and remove the service if installed
+ end;
+ end;
+ if CurStep = ssPostInstall then begin //Step happens just after installing files
+ WizardForm.StatusLabel.Caption := 'Installing Service...';
+ DoInstallService(); //Install service after all files installed, if not a portable install
+ end;
+end;
+
+procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
+begin
+ if CurUninstallStep = usUninstall then //Step happens before processing uninstall log
+ begin
+ UninstallProgressForm.StatusLabel.Caption := 'Stopping Tray App...';
+ KillTrayApp(); //Stop the tray app if running
+ UninstallProgressForm.StatusLabel.Caption := 'Uninstalling Service...';
+ DoRemoveService(); //Stop and remove the service
+ end;
+ if CurUninstallStep = usPostUninstall then //Step happens after processing uninstall log
+ begin
+ PromptRemoveConfiguration(); //Ask to remove any left over configuration files
+ end;
+end;
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/build.ps1 b/DnsServiceSetup/Windows/build.ps1
new file mode 100644
index 00000000..4282c706
--- /dev/null
+++ b/DnsServiceSetup/Windows/build.ps1
@@ -0,0 +1 @@
+iscc DnsServiceSetup.iss
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/depend/isxdl/chinese.ini b/DnsServiceSetup/Windows/depend/isxdl/chinese.ini
new file mode 100644
index 00000000..6bbb632d
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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=:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/czech.ini b/DnsServiceSetup/Windows/depend/isxdl/czech.ini
new file mode 100644
index 00000000..11ef1c51
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/isxdl/czech.ini
@@ -0,0 +1,53 @@
+[strings]
+
+; Translation (c) 2005 Martin Kozk (martin.kozak@openoffice.cz)
+
+; General
+100=Staen souboru
+101=Pejete si peruit stahovn?
+102=%1 (%2 z %3)
+103=%1 KB
+104=%1 KB z %2 KB (%3%)
+
+; Status information
+110=Zskvn informac o souboru...
+111=Pesmrovn na %1
+112=Odesln poadavku...
+113=Zpracovn %1
+114=Spojen s %1 navzno
+115=Pijmn...
+116=Pipojovn k %1
+
+; Error messages
+120=Chyba pi pipojovn k sti Internet.\n\n%1
+121=Chyba pi otevrn %1.\n\nServer nastavil nvratov kd %2.
+122=Chyba pi ten URL.\n\n%1
+123=Chyba pi zpisu do souboru %1.\n\n%2
+124=Chyba pi otevrn souboru %1.\n\n%2
+125='%1' nen platn URL.
+126=Chyba pi otevrn %1.\n\n%2
+127=Chyba pi zasln poadavku.\n\n%1
+128=Nepodporovan protokol. Podporovny jsou pouze protokoly HTTP a FTP.
+129=Pokus o pipojen k %1 selhalo.\n\n%2
+130=Pokus o zskn nvratovho kdu serveru selhal.\n\n%1
+131=Chyba pi zadvn poadavku na soubor.\n\n%1
+
+; Other
+144=O knihovn...
+146=Staen komponent
+147=Prvodce instalac stahuje pdavn komponenty do vaeho potae.
+
+; labels
+160=Soubor:
+161=Penosov rychlost:
+162=Stav:
+163=Uplynul as:
+164=Zbvajc as:
+165=Zpracovvan soubor:
+166=Celkov prbh:
+167=Zruit
+168=OK
+169=Uivatelsk jmno a heslo
+170=Uivatelsk jmno:
+171=Heslo:
+
diff --git a/DnsServiceSetup/Windows/depend/isxdl/dutch.ini b/DnsServiceSetup/Windows/depend/isxdl/dutch.ini
new file mode 100644
index 00000000..6fe8ca75
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/english.ini b/DnsServiceSetup/Windows/depend/isxdl/english.ini
new file mode 100644
index 00000000..55b2878b
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/french.ini b/DnsServiceSetup/Windows/depend/isxdl/french.ini
new file mode 100644
index 00000000..f5527bbc
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/isxdl/french.ini
@@ -0,0 +1,45 @@
+[strings]
+; General
+100=Tlchargement des fichiers
+101=Souhaitez-vous annuler le tlchargement ?
+102=%1 (%2 / %3)
+103=%1 Ko
+104=%1 Ko / %2 Ko (%3%)
+
+; Etat du tlchargement
+110=Accs au fichier...
+111=Redirection vers %1
+112=Envoi de la requte...
+113=Recherche %1
+114=Connect %1
+115=Rception...
+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 crer 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'accder 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 rcuprer le code d'tat.\n\n%1
+131=Impossible de rcuprer le fichier.\n\n%1
+
+; Autre
+144=A propos...
+146=Tlchargement
+147=Certains fichiers requis vont tre tlchargs.
+
+; Labels
+160=Fichier :
+161=Vitesse :
+162=Etat :
+163=Temps coul :
+164=Temps restant :
+165=Fichier courant :
+166=Tous les fichiers :
+167=Annuler
diff --git a/DnsServiceSetup/Windows/depend/isxdl/french2.ini b/DnsServiceSetup/Windows/depend/isxdl/french2.ini
new file mode 100644
index 00000000..a774639a
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/isxdl/french2.ini
@@ -0,0 +1,45 @@
+[strings]
+; General
+100=Tlchargement de fichier
+101=Voulez vous annuler le tlchargement ?
+102=%1 (%2 de %3)
+103=%1 Ko
+104=%1 Ko de %2 Ko (%3%)
+
+; Status information
+110=Rception des informations du fichier...
+111=Redirection vers %1
+112=envoie de la demande...
+113=Rsolution %1
+114=Connect a %1
+115=Rception...
+116=Connexion %1
+
+; Error messages
+120=Erreur de connexion Internet.\n\n%1
+121=Erreur d'ouverture%1.\n\nLe Serveur rpondu 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 douverture %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 accepts.
+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=Tlchargement
+147=LiveUpdate tlcharge maintenant des fichiers complmentaires 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
diff --git a/DnsServiceSetup/Windows/depend/isxdl/french3.ini b/DnsServiceSetup/Windows/depend/isxdl/french3.ini
new file mode 100644
index 00000000..5d767709
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/isxdl/french3.ini
@@ -0,0 +1,46 @@
+; By Fabien ILLIDE (fabienillide@users.sourceforge.net)
+[strings]
+; General
+100=Tlchargement de fichier
+101=Voulez-vous annuler le tlchargement ?
+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 requte...
+113=Rsolution de %1
+114=Connect %1
+115=Rception...
+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 requte.\n\n%1
+128=Protocole non support. Seuls les protocoles HTTP et FTP sont supports.
+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=Tlcharger
+147=L'installateur tlcharge 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
diff --git a/DnsServiceSetup/Windows/depend/isxdl/german.ini b/DnsServiceSetup/Windows/depend/isxdl/german.ini
new file mode 100644
index 00000000..b2204362
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/isxdl/german.ini
@@ -0,0 +1,49 @@
+[strings]
+; General
+100=Datei herunterladen
+101=Mchten 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=Auflsen 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 ungltige URL.
+126=Fehler beim ffnen von %1.\n\n%2
+127=Fehler beim Senden der Anforderung.\n\n%1
+128=Protokoll wird nicht untersttzt. Nur HTTP und FTP werden untersttzt.
+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 ldt nun zustzliche 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:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/isxdl.dll b/DnsServiceSetup/Windows/depend/isxdl/isxdl.dll
new file mode 100644
index 00000000..d227bcad
Binary files /dev/null and b/DnsServiceSetup/Windows/depend/isxdl/isxdl.dll differ
diff --git a/DnsServiceSetup/Windows/depend/isxdl/isxdl.iss b/DnsServiceSetup/Windows/depend/isxdl/isxdl.iss
new file mode 100644
index 00000000..81e2a861
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/isxdl/isxdl.iss
@@ -0,0 +1,14 @@
+[Files]
+Source: "depend\isxdl\isxdl.dll"; Flags: dontcopy
+
+[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';
+
+[Setup]
diff --git a/DnsServiceSetup/Windows/depend/isxdl/italian.ini b/DnsServiceSetup/Windows/depend/isxdl/italian.ini
new file mode 100644
index 00000000..9c290c6d
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/japanese.ini b/DnsServiceSetup/Windows/depend/isxdl/japanese.ini
new file mode 100644
index 00000000..6638d1f3
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/isxdl/japanese.ini
@@ -0,0 +1,49 @@
+[strings]
+; General
+100=t@C_E[h
+101=_E[hLZ܂H
+102=%1 (%2 of %3)
+103=%1 KB
+104=%1 KB of %2 KB (%3%)
+
+; Status information
+110=t@C擾...
+111=_CNg %1
+112=NGXgM...
+113= %1
+114=ڑ %1
+115=M...
+116=ڑ %1
+
+; Error messages
+120=C^[lbgڑG[.\n\n%1
+121=JnG[ %1.\n\nT[o[̃Xe[^XR[h %2.
+122=URLǂݎG[.\n\n%1
+123=t@C݃G[ %1.\n\n%2
+124=t@CI[vG[ %1.\n\n%2
+125='%1' ͕sURLł.
+126=I[vG[ %1.\n\n%2
+127=NGXgMG[.\n\n%1
+128=T|[gĂȂvgRł. HTTPFTPvgRT|[gĂ܂.
+129=ڑɎs܂ %1.\n\n%2
+130=Xe[^XR[h̖₢킹s.\n\n%1
+131=t@CNGXgG[.\n\n%1
+
+; Other
+144=About...
+146=_E[h
+147=ZbgAbv̓Rs[^[ɒlj̃t@C_E[hĂ܂.
+
+; labels
+160=t@C:
+161=x:
+162=:
+163=oߎ:
+164=c莞:
+165=݂̃t@C:
+166=Ŝ̐i:
+167=LZ
+168=OK
+169=[U[ƃpX[h
+170=[U[:
+171=pX[h:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/korean.ini b/DnsServiceSetup/Windows/depend/isxdl/korean.ini
new file mode 100644
index 00000000..ba8e6cb6
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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=н:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/norwegian.ini b/DnsServiceSetup/Windows/depend/isxdl/norwegian.ini
new file mode 100644
index 00000000..49562d08
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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 foresprsel...
+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 foresprsel.\n\n%1
+128=Ikke stttet protokoll. Bare HTTP og FTP protokoller er stttet.
+129=Klarte ikke koble til %1.\n\n%2
+130=Klarte ikke lese statuskode.\n\n%1
+131=Feil ved foresprsel 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=Gjenstende tid:
+165=Gjeldende fil:
+166=Total fremgang:
+167=Avbryt
+168=OK
+169=Brukernavn og passord
+170=Brukernavn:
+171=Passord:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/polish.ini b/DnsServiceSetup/Windows/depend/isxdl/polish.ini
new file mode 100644
index 00000000..cd76effd
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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=Wysyanie dania...
+113=Rozwizywanie %1
+114=Poczony z %1
+115=Pobieranie...
+116=Podczanie do %1
+
+; Error messages
+120=Nie mona podczy si do Internetu.\n\n%1
+121=Bd otwierania %1.\n\nSerwer zwrci kod bdu %2.
+122=Bd czytania URL.\n\n%1
+123=Bd zapisu pliku %1.\n\n%2
+124=Bd otwarcia pliku %1.\n\n%2
+125='%1' nie jest prawidowym URL.
+126=Bd otwarcia %1.\n\n%2
+127=Bd wysania dania.\n\n%1
+128=Nieznany protok. Tylko protokoy HTTP i FTP s obsugiwane.
+129=Nie udao si podczenie do %1.\n\n%2
+130=Nie udao si zapyta o kod stanu.\n\n%1
+131=Bd 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=Prdko:
+162=Stan:
+163=Upyno:
+164=Pozostay czas:
+165=Aktualny plik:
+166=Cakowity postp:
+167=Anuluj
diff --git a/DnsServiceSetup/Windows/depend/isxdl/portugues.ini b/DnsServiceSetup/Windows/depend/isxdl/portugues.ini
new file mode 100644
index 00000000..26ac9aaf
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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 informao 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 ligao internet.\n\n%1
+121=Erro na abertura de %1.\n\nO servidor retornou o cdigo 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 invlido.
+126=Erro na abertura de %1.\n\n%2
+127=Erro no envio do pedido.\n\n%1
+128=Protocolo no suportado.
+129=Falha na ligao a %1.\n\n%2
+130=Falha na tentativa de retirar o cdigo de status.\n\n%1
+131=Erro no pedido do ficheiro.\n\n%1
+
+; Other
+144=Acerca...
+146=Download
+147=A instalao est a efectuar o download de ficheiros adicionais necessrios.
+
+; labels
+160=Ficheiro:
+161=Velocidade:
+162=Estado:
+163=Tempo usado:
+164=Tempo em falta:
+165=Ficheiro:
+166=Progresso:
+167=Cancelar
diff --git a/DnsServiceSetup/Windows/depend/isxdl/portuguese.ini b/DnsServiceSetup/Windows/depend/isxdl/portuguese.ini
new file mode 100644
index 00000000..fcab0c47
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/isxdl/portuguese.ini
@@ -0,0 +1,46 @@
+; By Antnio 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 informao do ficheiro...
+111=Redireccionando a %1
+112=A enviar petio...
+113=Resolvendo %1
+114=Ligado a %1
+115=A receber...
+116=A efectuar ligao a %1
+
+; Error messages
+120=Erro a ligar Internet.\n\n%1
+121=Erro ao abrir %1.\n\nO servidor devolveu o cdigo %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 invlida.
+126=Erro ao abrir %1.\n\n%2
+127=Erro ao enviar a petio.\n\n%1
+128=Erro de protocolo. S os protocolos HTTP ou FTP so aceites.
+129=Erro ao ligar a %1.\n\n%2
+130=Erro ao processar o cdigo.\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=Progresso geral:
+167=Cancelar
diff --git a/DnsServiceSetup/Windows/depend/isxdl/russian.ini b/DnsServiceSetup/Windows/depend/isxdl/russian.ini
new file mode 100644
index 00000000..dcc9cae8
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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=:
diff --git a/DnsServiceSetup/Windows/depend/isxdl/spanish.ini b/DnsServiceSetup/Windows/depend/isxdl/spanish.ini
new file mode 100644
index 00000000..6993d764
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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 informacin del archivo...
+111=Redireccionando a %1
+112=Enviando peticin...
+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 invlido.
+126=Error al abrir %1.\n\n%2
+127=Error al mandar peticin.\n\n%1
+128=Error de protocolo. Slo HTTP o FTP son aceptados.
+129=Error al conectar a %1.\n\n%2
+130=Error al procesar el cdigo.\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
diff --git a/DnsServiceSetup/Windows/depend/isxdl/swedish.ini b/DnsServiceSetup/Windows/depend/isxdl/swedish.ini
new file mode 100644
index 00000000..4d988e3b
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/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=Hmtar fil information...
+111=Omdirigerar till %1
+112=Snder frfrgan...
+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 lsninga 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 sndning av frfrgan.\n\n%1
+128=Std saknas fr protokollet. Endast HTTP och FTP protokollen understds.
+129=Misslyckades att ansluta till %1.\n\n%2
+130=Misslyckades att kontrollera status kod.\n\n%1
+131=Fel vid frfrgan efter fil.\n\n%1
+
+; Other
+144=Om...
+146=Ladd ner
+147=Setup laddar nu ner tillggsfiler till din dator
+; labels
+160=Fil:
+161=Hastighet:
+162=Status:
+163=Frfluten Time:
+164=terstende Time:
+165=Nuvarande Fil:
+166=Totalt Frlopp:
+167=Avbryt
+168=OK
+169=Anvndarnamn och Lsenord
+170=Anvndarnamn:
+171=Lsenord:
diff --git a/DnsServiceSetup/Windows/depend/lang/chinese.iss b/DnsServiceSetup/Windows/depend/lang/chinese.iss
new file mode 100644
index 00000000..1c71ae80
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/chinese.iss
@@ -0,0 +1,19 @@
+[Languages]
+Name: "chs"; MessagesFile: "compiler:Default.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+chs.lcid=2052
+chs.depdownload_msg=安装程序需要下列依赖组建才能继续运行:%n%n%1%n要现在下载并安装吗?
+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
diff --git a/DnsServiceSetup/Windows/depend/lang/dutch.iss b/DnsServiceSetup/Windows/depend/lang/dutch.iss
new file mode 100644
index 00000000..aa9af03c
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/dutch.iss
@@ -0,0 +1,19 @@
+[Languages]
+Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+nl.lcid=1043
+nl.depdownload_msg=De volgende toepassingen zijn nodig vr de installatie kunt doorgaan:%n%n%1%nDownload en installeer nu?
+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 genstalleerd vr 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
diff --git a/DnsServiceSetup/Windows/depend/lang/english.iss b/DnsServiceSetup/Windows/depend/lang/english.iss
new file mode 100644
index 00000000..3287ee88
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/english.iss
@@ -0,0 +1,18 @@
+[Languages]
+Name: "en"; MessagesFile: "compiler:Default.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+en.lcid=1033
+en.depdownload_msg=The following applications are required before setup can continue:%n%n%1%nDownload and install now?
+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=
+
+[Files]
diff --git a/DnsServiceSetup/Windows/depend/lang/french.iss b/DnsServiceSetup/Windows/depend/lang/french.iss
new file mode 100644
index 00000000..8283953b
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/french.iss
@@ -0,0 +1,19 @@
+[Languages]
+Name: "fr"; MessagesFile: "compiler:Languages\French.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+fr.lcid=1036
+fr.depdownload_msg=Les applications suivantes sont ncessaires avant que l'installation puisse continuer :%n%n%1%nTlcharger et installer maintenant ?
+fr.depdownload_memo_title=Tlcharger les dpendances
+fr.depinstall_memo_title=Installez les dpendances
+fr.depinstall_title=Installation des dpendances
+fr.depinstall_description=Veuillez patienter pendant que les dpendances sont installes sur votre ordinateur.
+fr.depinstall_status=Installation de %1...
+fr.depinstall_missing=%1 doit tre install avant de pouvoir continuer. Veuillez installer %1 et excutez nouveau le programme d'installation.
+fr.depinstall_error=Une erreur est survenue lors de l'installation des dpendances. Veuillez redmarrer l'ordinateur, et excutez nouveau le programme d'installation, ou installez les dpendances suivantes manuellement :%n
+
+fr.isxdl_langfile=french3.ini
+
+[Files]
+Source: "scripts\isxdl\french3.ini"; Flags: dontcopy
diff --git a/DnsServiceSetup/Windows/depend/lang/german.iss b/DnsServiceSetup/Windows/depend/lang/german.iss
new file mode 100644
index 00000000..fb2d1c79
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/german.iss
@@ -0,0 +1,19 @@
+[Languages]
+Name: "de"; MessagesFile: "compiler:Languages\German.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+de.lcid=1031
+de.depdownload_msg=Die folgenden Programme werden bentigt bevor das Setup fortfahren kann:%n%n%1%nJetzt downloaden und installieren?
+de.depdownload_memo_title=Abhngigkeiten downloaden
+de.depinstall_memo_title=Abhngigkeiten installieren
+de.depinstall_title=Installiere Abhngigkeiten
+de.depinstall_description=Warten Sie bitte whrend Abhngigkeiten 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 whrend der Installation der Abghngigkeiten aufgetreten. Bitte starten Sie den Computer neu und fhren Sie das Setup erneut aus oder installieren Sie die folgenden Abhngigkeiten per Hand:%n
+
+de.isxdl_langfile=german.ini
+
+[Files]
+Source: "scripts\isxdl\german.ini"; Flags: dontcopy
diff --git a/DnsServiceSetup/Windows/depend/lang/italian.iss b/DnsServiceSetup/Windows/depend/lang/italian.iss
new file mode 100644
index 00000000..67efc61c
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/italian.iss
@@ -0,0 +1,19 @@
+[Languages]
+Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+it.lcid=1040
+it.depdownload_msg=Le seguenti applicazioni sono necessarie per procedere con l'installazione:%n%n%1%nSi desidera scaricarle ed installarle adesso?
+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
diff --git a/DnsServiceSetup/Windows/depend/lang/japanese.iss b/DnsServiceSetup/Windows/depend/lang/japanese.iss
new file mode 100644
index 00000000..7ff31819
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/japanese.iss
@@ -0,0 +1,19 @@
+[Languages]
+Name: "ja"; MessagesFile: "compiler:Languages\Japanese.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+ja.lcid=1041
+ja.depdownload_msg=処理を継続する前に次のアプリケーションが必要です:%n%n%1%nダウンロード後インストールしてよろしいですか?
+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
diff --git a/DnsServiceSetup/Windows/depend/lang/polish.iss b/DnsServiceSetup/Windows/depend/lang/polish.iss
new file mode 100644
index 00000000..cecaf113
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/polish.iss
@@ -0,0 +1,19 @@
+[Languages]
+Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+pl.lcid=1045
+pl.depdownload_msg=Poniższe aplikacje są wymagane przed instalacją aby móc kontynuować:%n%n%1%nCzy pobrać je i zainstalować teraz?
+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
diff --git a/DnsServiceSetup/Windows/depend/lang/russian.iss b/DnsServiceSetup/Windows/depend/lang/russian.iss
new file mode 100644
index 00000000..a9965131
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/lang/russian.iss
@@ -0,0 +1,19 @@
+[Languages]
+Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
+
+[CustomMessages]
+;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+ru.lcid=1049
+ru.depdownload_msg=Для продолжения установки требуются следующие приложения:%n%n%1%nСкачать и установить их сейчас?
+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
diff --git a/DnsServiceSetup/Windows/depend/products.iss b/DnsServiceSetup/Windows/depend/products.iss
new file mode 100644
index 00000000..2b6a633f
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/products.iss
@@ -0,0 +1,6 @@
+#include "isxdl\isxdl.iss"
+
+[Code]
+#include "products.pas"
+
+[Setup]
diff --git a/DnsServiceSetup/Windows/depend/products.pas b/DnsServiceSetup/Windows/depend/products.pas
new file mode 100644
index 00000000..b040bfc9
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/products.pas
@@ -0,0 +1,341 @@
+{
+ --- 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, downloadMessage: string;
+ products: array of TProduct;
+ delayedReboot, isForcedX86: boolean;
+ DependencyPage: TOutputProgressWizardPage;
+ AdditionalMemo: string;
+
+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
+ installMemo := installMemo + '%1' + title + #13;
+
+ 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);
+
+ downloadMessage := downloadMessage + '%1' + title + ' (' + size + ')' + #13;
+ end;
+ 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
+ if (LowerCase(Copy(product.File, Length(product.File) - 2, 3)) = 'exe') then begin
+ Result := Exec(product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
+ end else begin
+ Result := ShellExec('', product.File, product.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, resultcode);
+ end;
+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: http://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: http://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: http://www.jrsoftware.org/ishelp/index.php?topic=scriptevents
+}
+var
+ s: string;
+begin
+ if downloadMessage <> '' then
+ s := s + CustomMessage('depdownload_memo_title') + ':' + NewLine + FmtMessage(downloadMessage, [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;
+
+ s := s + AdditionalMemo;
+
+ Result := s
+end;
+
+function NextButtonClick(CurPageID: Integer): boolean;
+{
+ At each "next" button click
+ See: http://www.jrsoftware.org/ishelp/index.php?topic=scriptevents
+}
+begin
+ Result := true;
+
+ if CurPageID = wpReady then begin
+ if downloadMessage <> '' 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;
+ //isxdl_SetOption('title', FmtMessage(SetupMessage(msgSetupWindowTitle), [CustomMessage('appname')]));
+
+ //if SuppressibleMsgBox(FmtMessage(CustomMessage('depdownload_msg'), [FmtMessage(downloadMessage, [''])]), mbConfirmation, MB_YESNO, IDYES) = IDNO then
+ // Result := false
+ //else if
+ 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 GetString(x86, x64: String; w64: boolean): 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 <> '')) or (w64 and IsWin64 and (x64 <> '')) then begin
+ Result := x64;
+ end else begin
+ Result := x86;
+ end;
+end;
+
+function GetArchitectureString(w64: boolean): String;
+{
+ Gets the "standard" architecture suffix string.
+ Returns either _x64, _ia64 or nothing.
+}
+begin
+ if IsX64() or (w64 and IsWin64) then begin
+ Result := 'x64';
+ end else begin
+ Result := 'x86';
+ end;
+end;
+
+procedure SetForceX86(value: boolean);
+{
+ Forces the setup to use X86 products
+}
+begin
+ isForcedX86 := value;
+end;
+
+function StrSplit(Text: String; Separator: String): TArrayOfString;
+var
+ i, p: Integer;
+ Dest: TArrayOfString;
+begin
+ i := 0;
+ repeat
+ SetArrayLength(Dest, i+1);
+ p := Pos(Separator,Text);
+ if p > 0 then begin
+ Dest[i] := Copy(Text, 1, p-1);
+ Text := Copy(Text, p + Length(Separator), Length(Text));
+ i := i + 1;
+ end else begin
+ Dest[i] := Text;
+ Text := '';
+ end;
+ until Length(Text)=0;
+ Result := Dest
+end;
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/depend/products/dotnet5.iss b/DnsServiceSetup/Windows/depend/products/dotnet5.iss
new file mode 100644
index 00000000..adee3b22
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/products/dotnet5.iss
@@ -0,0 +1,49 @@
+[CustomMessages]
+dotnet_502_desktop_title=.NET 5.0.2 32-Bit Desktop Runtime
+dotnet_502_desktop_title_x64=.NET 5.0.2 64-Bit Desktop Runtime
+dotnet_502_desktop_size=47.1 MB
+dotnet_502_desktop_size_x64=52.5 MB
+dotnet_502_desktop_url=http://download.visualstudio.microsoft.com/download/pr/adeb8933-7480-4015-abf6-ca31137ad7cd/1123096ebfa5ee3f36d77500b622e4d8/windowsdesktop-runtime-5.0.2-win-x86.exe
+dotnet_502_desktop_url_x64=http://download.visualstudio.microsoft.com/download/pr/deffc9d5-ef77-4697-ac6e-33a58ccdc409/8386e478b5823a765dc1361155360877/windowsdesktop-runtime-5.0.2-win-x64.exe
+
+dotnet_502_runtime_title=.NET 5.0.2 32-Bit Runtime
+dotnet_502_runtime_title_x64=.NET 5.0.2 64-Bit Runtime
+dotnet_502_runtime_size=22.8 MB
+dotnet_502_runtime_size_x64=25.3 MB
+dotnet_502_runtime_url=http://download.visualstudio.microsoft.com/download/pr/46f8a025-ea67-4288-8e6a-709cfebc9b4b/69045dd85bcbfdd50441a87dedc13bd0/dotnet-runtime-5.0.2-win-x86.exe
+dotnet_502_runtime_url_x64=http://download.visualstudio.microsoft.com/download/pr/8526b5e6-e6e7-4d0b-902b-1f4ad5dd1462/7de15b8c6ab0387402d5958e99a62ed9/dotnet-runtime-5.0.2-win-x64.exe
+
+
+dotnet_501_desktop_title=.NET 5.0.1 32-Bit Desktop Runtime
+dotnet_501_desktop_title_x64=.NET 5.0.1 64-Bit Desktop Runtime
+dotnet_501_desktop_size=47.1 MB
+dotnet_501_desktop_size_x64=52.5 MB
+dotnet_501_desktop_url=http://download.visualstudio.microsoft.com/download/pr/55bb1094-db40-411d-8a37-21186e9495ef/1a045e29541b7516527728b973f0fdef/windowsdesktop-runtime-5.0.1-win-x86.exe
+dotnet_501_desktop_url_x64=http://download.visualstudio.microsoft.com/download/pr/c6a74d6b-576c-4ab0-bf55-d46d45610730/f70d2252c9f452c2eb679b8041846466/windowsdesktop-runtime-5.0.1-win-x64.exe
+
+dotnet_501_runtime_title=.NET 5.0.1 32-Bit Runtime
+dotnet_501_runtime_title_x64=.NET 5.0.1 64-Bit Runtime
+dotnet_501_runtime_size=22.7 MB
+dotnet_501_runtime_size_x64=25.3 MB
+dotnet_501_runtime_url=http://download.visualstudio.microsoft.com/download/pr/f4fb5042-8134-4434-8835-499eb2f18b38/6a0d857f6f1833f5c54fbbe5ead028a7/dotnet-runtime-5.0.1-win-x86.exe
+dotnet_501_runtime_url_x64=http://download.visualstudio.microsoft.com/download/pr/93095e51-be33-4b28-99c8-5ae0ebba753d/501f77f4b95d2e9c3481246a3eff9956/dotnet-runtime-5.0.1-win-x64.exe
+
+
+dotnet_500_desktop_title=.NET 5.0.0 32-Bit Desktop Runtime
+dotnet_500_desktop_title_x64=.NET 5.0.0 64-Bit Desktop Runtime
+dotnet_500_desktop_size=47.1 MB
+dotnet_500_desktop_size_x64=52.6 MB
+dotnet_500_desktop_url=http://download.visualstudio.microsoft.com/download/pr/b2780d75-e54a-448a-95fc-da9721b2b4c2/62310a9e9f0ba7b18741944cbae9f592/windowsdesktop-runtime-5.0.0-win-x86.exe
+dotnet_500_desktop_url_x64=http://download.visualstudio.microsoft.com/download/pr/1b3a8899-127a-4465-a3c2-7ce5e4feb07b/1e153ad470768baa40ed3f57e6e7a9d8/windowsdesktop-runtime-5.0.0-win-x64.exe
+
+dotnet_500_runtime_title=.NET 5.0.0 32-Bit Runtime
+dotnet_500_runtime_title_x64=.NET 5.0.0 64-Bit Runtime
+dotnet_500_runtime_size=22.7 MB
+dotnet_500_runtime_size_x64=25.3 MB
+dotnet_500_runtime_url=http://download.visualstudio.microsoft.com/download/pr/a7e15da3-7a15-43c2-a481-cf50bf305214/c69b951e8b47101e90b1289c387bb01a/dotnet-runtime-5.0.0-win-x86.exe
+dotnet_500_runtime_url_x64=http://download.visualstudio.microsoft.com/download/pr/36a9dc4e-1745-4f17-8a9c-f547a12e3764/ae25e38f20a4854d5e015a88659a22f9/dotnet-runtime-5.0.0-win-x64.exe
+
+[Code]
+#include "dotnet5.pas"
+
+[Setup]
diff --git a/DnsServiceSetup/Windows/depend/products/dotnet5.pas b/DnsServiceSetup/Windows/depend/products/dotnet5.pas
new file mode 100644
index 00000000..d9705d50
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/products/dotnet5.pas
@@ -0,0 +1,213 @@
+const
+ NoInstallNet = '{param:skipnet|false}'; //if this parameter is supplied on the command line then skip installing .NET dependencies
+
+{ .NET 5.0.2 }
+function DotNet_502_Desktop_Installed: Boolean;
+var
+ ResultCode: Integer;
+begin
+ Result := false;
+ Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.WindowsDesktop.App 5.0.2"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ if ResultCode = 0 then
+ begin
+ Result := true;
+ end;
+end;
+
+function DotNet_502_Runtime_Installed: Boolean;
+var
+ ResultCode: Integer;
+begin
+ Result := false;
+ Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.NETCore.App 5.0.2"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ if ResultCode = 0 then
+ begin
+ Result := true;
+ end;
+end;
+
+procedure dotnet_502_desktop;
+begin
+ if ExpandConstant(NoInstallNet) = 'false' then
+ begin
+ if not DotNet_502_Desktop_Installed() then
+ AddProduct('windowsdesktop-runtime-5.0.2-win' + GetArchitectureString(true) + '.exe',
+ '/install /quiet /norestart',
+ GetString(CustomMessage('dotnet_502_desktop_title'), CustomMessage('dotnet_502_desktop_title_x64'), true),
+ GetString(CustomMessage('dotnet_502_desktop_size'), CustomMessage('dotnet_502_desktop_size_x64'), true),
+ GetString(CustomMessage('dotnet_502_desktop_url'), CustomMessage('dotnet_502_desktop_url_x64'), true),
+ false, false, false);
+ end;
+end;
+
+procedure dotnet_502_runtime;
+begin
+ if ExpandConstant(NoInstallNet) = 'false' then
+ begin
+ if not DotNet_502_Runtime_Installed() then
+ AddProduct('dotnet-runtime-5.0.2-win' + GetArchitectureString(true) + '.exe',
+ '/install /quiet /norestart',
+ GetString(CustomMessage('dotnet_502_runtime_title'), CustomMessage('dotnet_502_runtime_title_x64'), true),
+ GetString(CustomMessage('dotnet_502_runtime_size'), CustomMessage('dotnet_502_runtime_size_x64'), true),
+ GetString(CustomMessage('dotnet_502_runtime_url'), CustomMessage('dotnet_502_runtime_url_x64'), true),
+ false, false, false);
+ end;
+end;
+
+{ .NET 5.0.1 }
+
+function DotNet_501_Desktop_Installed: Boolean;
+var
+ ResultCode: Integer;
+begin
+ Result := false;
+ Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.WindowsDesktop.App 5.0.1"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ if ResultCode = 0 then
+ begin
+ Result := true;
+ end;
+end;
+
+function DotNet_501_Runtime_Installed: Boolean;
+var
+ ResultCode: Integer;
+begin
+ Result := false;
+ Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.NETCore.App 5.0.1"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ if ResultCode = 0 then
+ begin
+ Result := true;
+ end;
+end;
+
+procedure dotnet_501_desktop;
+begin
+ if ExpandConstant(NoInstallNet) = 'false' then
+ begin
+ if not DotNet_501_Desktop_Installed() then
+ AddProduct('windowsdesktop-runtime-5.0.1-win' + GetArchitectureString(true) + '.exe',
+ '/install /quiet /norestart',
+ GetString(CustomMessage('dotnet_501_desktop_title'), CustomMessage('dotnet_501_desktop_title_x64'), true),
+ GetString(CustomMessage('dotnet_501_desktop_size'), CustomMessage('dotnet_501_desktop_size_x64'), true),
+ GetString(CustomMessage('dotnet_501_desktop_url'), CustomMessage('dotnet_501_desktop_url_x64'), true),
+ false, false, false);
+ end;
+end;
+
+procedure dotnet_501_runtime;
+begin
+ if ExpandConstant(NoInstallNet) = 'false' then
+ begin
+ if not DotNet_501_Runtime_Installed() then
+ AddProduct('dotnet-runtime-5.0.1-win' + GetArchitectureString(true) + '.exe',
+ '/install /quiet /norestart',
+ GetString(CustomMessage('dotnet_501_runtime_title'), CustomMessage('dotnet_501_runtime_title_x64'), true),
+ GetString(CustomMessage('dotnet_501_runtime_size'), CustomMessage('dotnet_501_runtime_size_x64'), true),
+ GetString(CustomMessage('dotnet_501_runtime_url'), CustomMessage('dotnet_501_runtime_url_x64'), true),
+ false, false, false);
+ end;
+end;
+
+{ .NET 5.0.0 }
+
+function DotNet_500_Desktop_Installed: Boolean;
+var
+ ResultCode: Integer;
+begin
+ Result := false;
+ Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.WindowsDesktop.App 5.0.0"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ if ResultCode = 0 then
+ begin
+ Result := true;
+ end;
+end;
+
+function DotNet_500_Runtime_Installed: Boolean;
+var
+ ResultCode: Integer;
+begin
+ Result := false;
+ Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.NETCore.App 5.0.0"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ if ResultCode = 0 then
+ begin
+ Result := true;
+ end;
+end;
+
+procedure dotnet_500_desktop;
+begin
+ if ExpandConstant(NoInstallNet) = 'false' then
+ begin
+ if not DotNet_500_Desktop_Installed() then
+ AddProduct('windowsdesktop-runtime-5.0.0-win' + GetArchitectureString(true) + '.exe',
+ '/install /quiet /norestart',
+ GetString(CustomMessage('dotnet_500_desktop_title'), CustomMessage('dotnet_500_desktop_title_x64'), true),
+ GetString(CustomMessage('dotnet_500_desktop_size'), CustomMessage('dotnet_500_desktop_size_x64'), true),
+ GetString(CustomMessage('dotnet_500_desktop_url'), CustomMessage('dotnet_500_desktop_url_x64'), true),
+ false, false, false);
+ end;
+end;
+
+procedure dotnet_500_runtime;
+begin
+ if ExpandConstant(NoInstallNet) = 'false' then
+ begin
+ if not DotNet_500_Runtime_Installed() then
+ AddProduct('dotnet-runtime-5.0.0-win' + GetArchitectureString(true) + '.exe',
+ '/install /quiet /norestart',
+ GetString(CustomMessage('dotnet_500_runtime_title'), CustomMessage('dotnet_500_runtime_title_x64'), true),
+ GetString(CustomMessage('dotnet_500_runtime_size'), CustomMessage('dotnet_500_runtime_size_x64'), true),
+ GetString(CustomMessage('dotnet_500_runtime_url'), CustomMessage('dotnet_500_runtime_url_x64'), true),
+ false, false, false);
+ end;
+end;
+
+{
+any .NET 5
+
+Checks for any version of .NET 5 and if none exists, installs latest
+}
+
+function DotNet_5_Desktop_Installed: Boolean;
+var
+ ResultCode: Integer;
+begin
+ Result := false;
+ Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.WindowsDesktop.App 5"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ // Only check for the 5 version number
+ if ResultCode = 0 then
+ begin
+ Result := true;
+ end;
+end;
+
+function DotNet_5_Runtime_Installed: Boolean;
+var
+ ResultCode: Integer;
+begin
+ Result := false;
+ Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.NETCore.App 5"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ // Only check for the 5 version number
+ if ResultCode = 0 then
+ begin
+ Result := true;
+ end;
+end;
+
+procedure dotnet_5_desktop;
+begin
+ if not DotNet_5_Desktop_Installed() then
+ begin
+ dotnet_502_desktop();
+ { if no .NET 5 version installed then install the one above }
+ end;
+end;
+
+procedure dotnet_5_runtime;
+begin
+ if not DotNet_5_Runtime_Installed() then
+ begin
+ dotnet_502_runtime();
+ { if no .NET 5 version installed then install the one above }
+ end;
+end;
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/depend/products/dotnetfw4.iss b/DnsServiceSetup/Windows/depend/products/dotnetfw4.iss
new file mode 100644
index 00000000..4b0a1e6d
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/products/dotnetfw4.iss
@@ -0,0 +1,9 @@
+[CustomMessages]
+dotnet_fw48_title=.NET Framework 4.8 Runtime
+dotnet_fw48_size=111 MB
+dotnet_fw48_url=http://download.visualstudio.microsoft.com/download/pr/014120d7-d689-4305-befd-3cb711108212/0fd66638cde16859462a6243a4629a50/ndp48-x86-x64-allos-enu.exe
+
+[Code]
+#include "dotnetfw4.pas"
+
+[Setup]
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/depend/products/dotnetfw4.pas b/DnsServiceSetup/Windows/depend/products/dotnetfw4.pas
new file mode 100644
index 00000000..abdc962a
--- /dev/null
+++ b/DnsServiceSetup/Windows/depend/products/dotnetfw4.pas
@@ -0,0 +1,40 @@
+const
+ NoInstallNet = '{param:skipnet|false}'; //if this parameter is supplied on the command line then skip installing .NET dependencies
+
+{ .NET Framework 4.8 }
+
+function DotNet_Framework_48_Installed: Boolean;
+var
+ KeyResult: String;
+ VersionParts: TArrayOfString;
+ RegVersion, MinVer: Int64;
+ VerDiff: Integer;
+begin
+ Result := false;
+
+ RegQueryStringValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Version', KeyResult);
+ VersionParts := StrSplit(KeyResult, '.');
+ RegVersion := PackVersionComponents(StrToInt(VersionParts[0]), StrToInt(VersionParts[1]), StrToInt(VersionParts[2]), 0);
+ MinVer := PackVersionComponents(4, 8, 0, 0);
+
+ VerDiff := ComparePackedVersion(RegVersion, MinVer);
+
+ if VerDiff > -1 then
+ begin
+ Result := true;
+ end;
+end;
+
+procedure dotnet_framework_48();
+begin
+ if ExpandConstant(NoInstallNet) = 'false' then
+ begin
+ if not DotNet_Framework_48_Installed() then
+ AddProduct('ndp48-x86-x64-allos-enu.exe',
+ '/install /quiet /norestart',
+ CustomMessage('dotnet_fw48_title'),
+ CustomMessage('dotnet_fw48_size'),
+ CustomMessage('dotnet_fw48_url'),
+ false, false, false);
+ end;
+end;
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/helper.pas b/DnsServiceSetup/Windows/helper.pas
new file mode 100644
index 00000000..8978e286
--- /dev/null
+++ b/DnsServiceSetup/Windows/helper.pas
@@ -0,0 +1,91 @@
+{
+ Helper functions
+}
+
+{
+ Checks to see if the installer is an 'upgrade'
+}
+function IsUpgrade: Boolean;
+var
+ Value: string;
+ UninstallKey: string;
+begin
+ UninstallKey := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' +
+ ExpandConstant('{#SetupSetting("AppId")}') + '_is1';
+ Result := (RegQueryStringValue(HKLM, UninstallKey, 'UninstallString', Value) or
+ RegQueryStringValue(HKCU, UninstallKey, 'UninstallString', Value)) and (Value <> '');
+end;
+
+{
+ Kills a running program by its filename
+}
+procedure TaskKill(fileName: String);
+var
+ ResultCode: Integer;
+begin
+ Exec(ExpandConstant('taskkill.exe'), '/f /im ' + '"' + fileName + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+end;
+
+
+{
+ Executes the MSI Uninstall by GUID functionality
+}
+function MsiExecUnins(appId: String): Integer;
+var
+ ResultCode: Integer;
+begin
+ ShellExec('', 'msiexec.exe', '/x ' + appId + ' /qn', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
+ Result := ResultCode;
+end;
+
+{
+ Copies and entire folder
+}
+procedure DirectoryCopy(SourcePath, DestPath: string);
+var
+ FindRec: TFindRec;
+ SourceFilePath: string;
+ DestFilePath: string;
+begin
+ if FindFirst(SourcePath + '\*', FindRec) then
+ begin
+ try
+ repeat
+ if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
+ begin
+ SourceFilePath := SourcePath + '\' + FindRec.Name;
+ DestFilePath := DestPath + '\' + FindRec.Name;
+ if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
+ begin
+ if FileCopy(SourceFilePath, DestFilePath, False) then
+ begin
+ Log(Format('Copied %s to %s', [SourceFilePath, DestFilePath]));
+ end
+ else
+ begin
+ Log(Format('Failed to copy %s to %s', [SourceFilePath, DestFilePath]));
+ end;
+ end
+ else
+ begin
+ if DirExists(DestFilePath) or CreateDir(DestFilePath) then
+ begin
+ Log(Format('Created %s', [DestFilePath]));
+ DirectoryCopy(SourceFilePath, DestFilePath);
+ end
+ else
+ begin
+ Log(Format('Failed to create %s', [DestFilePath]));
+ end;
+ end;
+ end;
+ until not FindNext(FindRec);
+ finally
+ FindClose(FindRec);
+ end;
+ end
+ else
+ begin
+ Log(Format('Failed to list %s', [SourcePath]));
+ end;
+end;
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/legacy.pas b/DnsServiceSetup/Windows/legacy.pas
new file mode 100644
index 00000000..84dc3905
--- /dev/null
+++ b/DnsServiceSetup/Windows/legacy.pas
@@ -0,0 +1,73 @@
+{
+ Legacy Installer Functionality
+}
+
+{
+ Checks if the MSI Installer is installed
+}
+function IsLegacyInstallerInstalled: Boolean;
+var
+ Value: string;
+ UninstallKey: string;
+begin
+ UninstallKey := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#LEGACY_INSTALLER_APPID}';
+ Result := (RegQueryStringValue(HKLM, UninstallKey, 'UninstallString', Value) or
+ RegQueryStringValue(HKCU, UninstallKey, 'UninstallString', Value)) and (Value <> '');
+end;
+
+{
+ Checks if Configuration exists in the old location.
+}
+function IsLegacyConfigAvailable: Boolean;
+var
+ Value: string;
+begin
+ Result := DirExists(ExpandConstant('{#LEGACY_INSTALLER_CONFIG_PATH}'));
+end;
+
+{
+ Uninstalls Legacy Installer
+}
+procedure UninstallLegacyInstaller;
+var
+ ResultCode: Integer;
+begin
+ if IsLegacyInstallerInstalled then begin
+ Log('Uninstall MSI installer item');
+ ResultCode := MsiExecUnins('{#LEGACY_INSTALLER_APPID}');
+ Log('Result code ' + IntToStr(ResultCode));
+ end;
+end;
+
+{
+ Migrates the Configuration to the new location
+}
+procedure MigrateConfiguration();
+var
+ ConfigDirExists : Boolean;
+begin
+
+ if IsLegacyConfigAvailable then begin
+ Log('Begin Configuration Migration');
+
+ ConfigDirExists := DirExists(ExpandConstant('{#CONFIG_FOLDER_COMPANY}'));
+
+ if not ConfigDirExists then begin
+ Log('Create config folder company');
+ CreateDir(ExpandConstant('{#CONFIG_FOLDER_COMPANY}'));
+ end;
+
+ ConfigDirExists := DirExists(ExpandConstant('{#CONFIG_FOLDER_FULL}'));
+
+ if not ConfigDirExists then begin
+ Log('Create config folder program');
+ CreateDir(ExpandConstant('{#CONFIG_FOLDER_FULL}'));
+ end;
+
+ DirectoryCopy(ExpandConstant('{#LEGACY_INSTALLER_CONFIG_PATH}'), ExpandConstant('{#CONFIG_FOLDER_FULL}'));
+
+ DelTree(ExpandConstant('{#LEGACY_INSTALLER_CONFIG_PATH}'), true, true, true);
+
+ Log('Complete Configuration Migration');
+ end;
+end;
\ No newline at end of file
diff --git a/DnsServiceSetup/Windows/logo.bmp b/DnsServiceSetup/Windows/logo.bmp
new file mode 100644
index 00000000..8659111e
Binary files /dev/null and b/DnsServiceSetup/Windows/logo.bmp differ
diff --git a/DnsServiceSetup/Windows/logo.ico b/DnsServiceSetup/Windows/logo.ico
new file mode 100644
index 00000000..67432fd8
Binary files /dev/null and b/DnsServiceSetup/Windows/logo.ico differ
diff --git a/DnsServiceSetup/Windows/service.pas b/DnsServiceSetup/Windows/service.pas
new file mode 100644
index 00000000..754a2858
--- /dev/null
+++ b/DnsServiceSetup/Windows/service.pas
@@ -0,0 +1,224 @@
+type
+ SERVICE_STATUS = record
+ dwServiceType : cardinal;
+ dwCurrentState : cardinal;
+ dwControlsAccepted : cardinal;
+ dwWin32ExitCode : cardinal;
+ dwServiceSpecificExitCode : cardinal;
+ dwCheckPoint : cardinal;
+ dwWaitHint : cardinal;
+ end;
+ HANDLE = cardinal;
+
+const
+ SERVICE_QUERY_CONFIG = $1;
+ SERVICE_CHANGE_CONFIG = $2;
+ SERVICE_QUERY_STATUS = $4;
+ SERVICE_START = $10;
+ SERVICE_STOP = $20;
+ SERVICE_ALL_ACCESS = $f01ff;
+ SC_MANAGER_ALL_ACCESS = $f003f;
+ SERVICE_WIN32_OWN_PROCESS = $10;
+ SERVICE_WIN32_SHARE_PROCESS = $20;
+ SERVICE_WIN32 = $30;
+ SERVICE_INTERACTIVE_PROCESS = $100;
+ SERVICE_BOOT_START = $0;
+ SERVICE_SYSTEM_START = $1;
+ SERVICE_AUTO_START = $2;
+ SERVICE_DEMAND_START = $3;
+ SERVICE_DISABLED = $4;
+ SERVICE_DELETE = $10000;
+ SERVICE_CONTROL_STOP = $1;
+ SERVICE_CONTROL_PAUSE = $2;
+ SERVICE_CONTROL_CONTINUE = $3;
+ SERVICE_CONTROL_INTERROGATE = $4;
+ SERVICE_STOPPED = $1;
+ SERVICE_START_PENDING = $2;
+ SERVICE_STOP_PENDING = $3;
+ SERVICE_RUNNING = $4;
+ SERVICE_CONTINUE_PENDING = $5;
+ SERVICE_PAUSE_PENDING = $6;
+ SERVICE_PAUSED = $7;
+
+
+ ERROR_ACCESS_DENIED = 5;
+ ERROR_CIRCULAR_DEPENDENCY = 1059;
+ ERROR_DUPLICATE_SERVICE_NAME = 1078;
+ ERROR_INVALID_HANDLE = 6;
+ ERROR_INVALID_NAME = 123;
+ ERROR_INVALID_PARAMETER = 87;
+ ERROR_INVALID_SERVICE_ACCOUNT = 1057;
+ ERROR_SERVICE_EXISTS = 1073;
+ ERROR_SERVICE_MARKED_FOR_DELETE = 1072;
+
+// #######################################################################################
+// nt based service utilities
+// #######################################################################################
+function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE;
+external 'OpenSCManagerW@advapi32.dll stdcall';
+
+function OpenService(hSCManager :HANDLE;lpServiceName: string; dwDesiredAccess :cardinal): HANDLE;
+external 'OpenServiceW@advapi32.dll stdcall';
+
+function CloseServiceHandle(hSCObject :HANDLE): boolean;
+external 'CloseServiceHandle@advapi32.dll stdcall';
+
+function CreateService(hSCManager :HANDLE;lpServiceName, lpDisplayName: string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl: cardinal;lpBinaryPathName,lpLoadOrderGroup: String; lpdwTagId : cardinal;lpDependencies,lpServiceStartName,lpPassword :string): cardinal;
+external 'CreateServiceW@advapi32.dll stdcall';
+
+function DeleteService(hService :HANDLE): boolean;
+external 'DeleteService@advapi32.dll stdcall';
+
+function StartNTService(hService :HANDLE;dwNumServiceArgs : cardinal;lpServiceArgVectors : cardinal) : boolean;
+external 'StartServiceW@advapi32.dll stdcall';
+
+function ControlService(hService :HANDLE; dwControl :cardinal;var ServiceStatus :SERVICE_STATUS) : boolean;
+external 'ControlService@advapi32.dll stdcall';
+
+function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean;
+external 'QueryServiceStatus@advapi32.dll stdcall';
+
+function QueryServiceStatusEx(hService :HANDLE;ServiceStatus :SERVICE_STATUS) : boolean;
+external 'QueryServiceStatus@advapi32.dll stdcall';
+
+function GetLastError(): dword;
+external 'GetLastError@kernel32.dll stdcall';
+
+function OpenServiceManager(): HANDLE;
+begin
+ if UsingWinNT() = true then begin
+ Result := OpenSCManager('', 'ServicesActive', SC_MANAGER_ALL_ACCESS);
+ if Result = 0 then
+ MsgBox(ExpandConstant('{cm:ServiceManagerUnavailable}'), mbError, MB_OK);
+ end
+ else begin
+ MsgBox('only nt based systems support services', mbError, MB_OK);
+ Result := 0;
+ end
+end;
+
+function IsServiceInstalled(ServiceName: string): boolean;
+var
+ hSCM : HANDLE;
+ hService: HANDLE;
+begin
+ hSCM := OpenServiceManager();
+ Result := false;
+ if hSCM <> 0 then begin
+ hService := OpenService(hSCM, ServiceName, SERVICE_QUERY_CONFIG);
+ if hService <> 0 then begin
+ Result := true;
+ CloseServiceHandle(hService);
+ end;
+ CloseServiceHandle(hSCM);
+ end
+end;
+
+function InstallService(FileName, ServiceName, DisplayName, Description: string; ServiceType, StartType: cardinal): boolean;
+var
+ hSCM : HANDLE;
+ hService: HANDLE;
+begin
+ hSCM := OpenServiceManager();
+ Result := false;
+ if hSCM <> 0 then begin
+ hService := CreateService(hSCM, ServiceName, DisplayName, SERVICE_ALL_ACCESS, ServiceType, StartType, 0, FileName,'', 0, '', '', '');
+ if hService <> 0 then begin
+ Result := true;
+ // Win2K & WinXP supports aditional description text for services
+ if Description <> '' then
+ RegWriteStringValue(HKLM,'System\CurrentControlSet\Services\' + ServiceName, 'Description', Description);
+ CloseServiceHandle(hService);
+ end;
+ CloseServiceHandle(hSCM);
+ end;
+end;
+
+function RemoveService(ServiceName: string): boolean;
+var
+ hSCM : HANDLE;
+ hService: HANDLE;
+begin
+ hSCM := OpenServiceManager();
+ Result := false;
+ if hSCM <> 0 then begin
+ hService := OpenService(hSCM, ServiceName, SERVICE_DELETE);
+ if hService <> 0 then begin
+ Result := DeleteService(hService);
+ CloseServiceHandle(hService);
+ end;
+ CloseServiceHandle(hSCM);
+ end;
+end;
+
+function StartService(ServiceName: string): boolean;
+var
+ hSCM : HANDLE;
+ hService: HANDLE;
+begin
+ hSCM := OpenServiceManager();
+ Result := false;
+ if hSCM <> 0 then begin
+ hService := OpenService(hSCM, ServiceName, SERVICE_START);
+ if hService <> 0 then begin
+ Result := StartNTService(hService, 0, 0);
+ CloseServiceHandle(hService);
+ end;
+ CloseServiceHandle(hSCM);
+ end;
+end;
+
+function StopService(ServiceName: string): boolean;
+var
+ hSCM : HANDLE;
+ hService: HANDLE;
+ Status : SERVICE_STATUS;
+begin
+ hSCM := OpenServiceManager();
+ Result := false;
+ if hSCM <> 0 then begin
+ hService := OpenService(hSCM, ServiceName, SERVICE_STOP);
+ if hService <> 0 then begin
+ Result := ControlService(hService, SERVICE_CONTROL_STOP, Status);
+ CloseServiceHandle(hService);
+ end;
+ CloseServiceHandle(hSCM);
+ end;
+end;
+
+function IsServiceRunning(ServiceName: string): boolean;
+var
+ hSCM : HANDLE;
+ hService: HANDLE;
+ Status : SERVICE_STATUS;
+begin
+ hSCM := OpenServiceManager();
+ Result := false;
+ if hSCM <> 0 then begin
+ hService := OpenService(hSCM, ServiceName, SERVICE_QUERY_STATUS);
+ if hService <> 0 then begin
+ if QueryServiceStatus(hService, Status) then begin
+ Result :=(Status.dwCurrentState = SERVICE_RUNNING);
+ end;
+ CloseServiceHandle(hService);
+ end;
+ CloseServiceHandle(hSCM);
+ end
+end;
+
+function ServiceErrorToMessage(Error: word): string;
+begin
+ case Error of
+ ERROR_ACCESS_DENIED: Result := 'Access Denied';
+ ERROR_CIRCULAR_DEPENDENCY: Result := 'Circular Dependency';
+ ERROR_DUPLICATE_SERVICE_NAME: Result := 'Duplicate Service Name';
+ ERROR_INVALID_HANDLE: Result := 'Invalid Handle';
+ ERROR_INVALID_NAME: Result := 'Invalid Name';
+ ERROR_INVALID_PARAMETER: Result := 'Invalid Parameter';
+ ERROR_INVALID_SERVICE_ACCOUNT: Result := 'Invalid Service Account';
+ ERROR_SERVICE_EXISTS: Result := 'Service Exists';
+ ERROR_SERVICE_MARKED_FOR_DELETE: Result := 'Service Marked For Deletion';
+ else
+ Result := 'Unknown error: ' + IntToStr(Error);
+ end;
+end;
\ No newline at end of file