Add installer

This commit is contained in:
DoogeJ
2016-10-16 18:23:10 +02:00
parent 8a862faa17
commit 66ab8ce5d5
15 changed files with 972 additions and 0 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.vs
SmartHDD/bin
SmartHDD/obj
Installer/bin

View File

@@ -0,0 +1,210 @@
The Code Project Open License (CPOL) 1.02
Preamble
This License governs Your use of the Work. This License is intended to allow
developers to use the Source Code and Executable Files provided as part of the
Work in any application in any form.
The main points subject to the terms of the License are:
* Source Code and Executable Files can be used in commercial applications;
* Source Code and Executable Files can be redistributed; and
* Source Code can be modified to create derivative works.
* No claim of suitability, guarantee, or any warranty whatsoever is provided.
The software is provided "as-is".
* The Article accompanying the Work may not be distributed or republished
without the Author's consent
This License is entered between You, the individual or other entity reading or
otherwise making use of the Work licensed pursuant to this License and the
individual or other entity which offers the Work under the terms of this License
("Author").
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CODE PROJECT
OPEN LICENSE ("LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER
APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE
OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HEREIN, YOU ACCEPT AND AGREE TO
BE BOUND BY THE TERMS OF THIS LICENSE. THE AUTHOR GRANTS YOU THE RIGHTS CONTAINED
HEREIN IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. IF YOU
DO NOT AGREE TO ACCEPT AND BE BOUND BY THE TERMS OF THIS LICENSE, YOU CANNOT
MAKE ANY USE OF THE WORK.
1. Definitions.
1. "Articles" means, collectively, all articles written by Author which
describes how the Source Code and Executable Files for the Work may
be used by a user.
2. "Author" means the individual or entity that offers the Work under
the terms of this License.
3. "Derivative Work" means a work based upon the Work or upon the Work
and other pre-existing works.
4. "Executable Files" refer to the executables, binary files, configu-
ration and any required data files included in the Work.
5. "Publisher" means the provider of the website, magazine, CD-ROM,
DVD or other medium from or by which the Work is obtained by You.
6. "Source Code" refers to the collection of source code and configu-
ration files used to create the Executable Files.
7. "Standard Version" refers to such a Work if it has not been modified,
or has been modified in accordance with the consent of the Author,
such consent being in the full discretion of the Author.
8. "Work" refers to the collection of files distributed by the Publisher,
including the Source Code, Executable Files, binaries, data files,
documentation, whitepapers and the Articles.
9. "You" is you, an individual or entity wishing to use the Work and
exercise your rights under this License.
2. Fair Use/Fair Use Rights. Nothing in this License is intended to reduce,
limit, or restrict any rights arising from fair use, fair dealing, first
sale or other limitations on the exclusive rights of the copyright owner
under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License, the
Author hereby grants You a worldwide, royalty-free, non-exclusive, perpe-
tual (for the duration of the applicable copyright) license to exercise
the rights in the Work as stated below:
1. You may use the standard version of the Source Code or Executable
Files in Your own applications.
2. You may apply bug fixes, portability fixes and other modifications
obtained from the Public Domain or from the Author. A Work modified
in such a way shall still be considered the standard version and
will be subject to this License.
3. You may otherwise modify Your copy of this Work (excluding the
Articles) in any way to create a Derivative Work, provided that
You insert a prominent notice in each changed file stating how,
when and where You changed that file.
4. You may distribute the standard version of the Executable Files
and Source Code or Derivative Work in aggregate with other (pos-
sibly commercial) programs as part of a larger (possibly commercial)
software distribution.
5. The Articles discussing the Work published in any form by the
author may not be distributed or republished without the Author's
consent. The author retains copyright to any such Articles. You may
use the Executable Files and Source Code pursuant to this License
but you may not repost or republish or otherwise distribute or make
available the Articles, without the prior written consent of the
Author.
Any subroutines or modules supplied by You and linked into the Source
Code or Executable Files this Work shall not be considered part of this
Work and will not be subject to the terms of this License.
4. Patent License. Subject to the terms and conditions of this License,
each Author hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, import, and otherwise transfer
the Work.
5. Restrictions. The license granted in Section 3 above is expressly made
subject to and limited by the following restrictions:
1. You agree not to remove any of the original copyright, patent,
trademark, and attribution notices and associated disclaimers that
may appear in the Source Code or Executable Files.
2. You agree not to advertise or in any way imply that this Work is a
product of Your own.
3. The name of the Author may not be used to endorse or promote pro-
ducts derived from the Work without the prior written consent of
the Author.
4. You agree not to sell, lease, or rent any part of the Work. This
does not restrict you from including the Work or any part of the
Work inside a larger software distribution that itself is being
sold. The Work by itself, though, cannot be sold, leased or rented.
5. You may distribute the Executable Files and Source Code only under
the terms of this License, and You must include a copy of, or the
Uniform Resource Identifier for, this License with every copy of
the Executable Files or Source Code You distribute and ensure that
anyone receiving such Executable Files and Source Code agrees that
the terms of this License apply to such Executable Files and/or
Source Code. You may not offer or impose any terms on the Work that
alter or restrict the terms of this License or the recipients'
exercise of the rights granted hereunder. You may not sublicense
the Work. You must keep intact all notices that refer to this
License and to the disclaimer of warranties. You may not distribute
the Executable Files or Source Code with any technological measures
that control access or use of the Work in a manner inconsistent with
the terms of this License.
6. You agree not to use the Work for illegal, immoral or improper
purposes, or on pages containing illegal, immoral or improper
material. The Work is subject to applicable export laws. You agree
to comply with all such laws and regulations that may apply to the
Work after Your receipt of the Work.
6. Representations, Warranties and Disclaimer. THIS WORK IS PROVIDED "AS
IS", "WHERE IS" AND "AS AVAILABLE", WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES OR CONDITIONS OR GUARANTEES. YOU, THE USER, ASSUME ALL RISK
IN ITS USE, INCLUDING COPYRIGHT INFRINGEMENT, PATENT INFRINGEMENT, SUIT-
ABILITY, ETC. AUTHOR EXPRESSLY DISCLAIMS ALL EXPRESS, IMPLIED OR STATU-
TORY WARRANTIES OR CONDITIONS, INCLUDING WITHOUT LIMITATION, WARRANTIES
OR CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY OR FITNESS FOR A
PARTICULAR PURPOSE, OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT, OR THAT
THE WORK (OR ANY PORTION THEREOF) IS CORRECT, USEFUL, BUG-FREE OR FREE OF
VIRUSES. YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE
WORK OR DERIVATIVE WORKS.
7. Indemnity. You agree to defend, indemnify and hold harmless the Author
and the Publisher from and against any claims, suits, losses, damages,
liabilities, costs, and expenses (including reasonable legal or attorneys'
fees) resulting from or relating to any use of the Work by You.
8. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
LAW, IN NO EVENT WILL THE AUTHOR OR THE PUBLISHER BE LIABLE TO YOU ON
ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR
EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK OR
OTHERWISE, EVEN IF THE AUTHOR OR THE PUBLISHER HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
9. Termination.
1. This License and the rights granted hereunder will terminate auto-
matically upon any breach by You of any term of this License. Indi-
viduals or entities who have received Derivative Works from You
under this License, however, will not have their licenses terminated
provided such individuals or entities remain in full compliance
with those licenses. Sections 1, 2, 6, 7, 8, 9, 10 and 11 will
survive any termination of this License.
2. If You bring a copyright, trademark, patent or any other infringe-
ment claim against any contributor over infringements You claim are
made by the Work, your License from such contributor to the Work
ends automatically.
3. Subject to the above terms and conditions, this License is perpe-
tual (for the duration of the applicable copyright in the Work).
Notwithstanding the above, the Author reserves the right to release
the Work under different license terms or to stop distributing the
Work at any time; provided, however that any such election will not
serve to withdraw this License (or any other license that has been,
or is required to be, granted under the terms of this License), and
this License will continue in full force and effect unless termi-
nated as stated above.
10. Publisher. The parties hereby confirm that the Publisher shall not,
under any circumstances, be responsible for and shall not have any lia-
bility in respect of the subject matter of this License. The Publisher
makes no warranty whatsoever in connection with the Work and shall not
be liable to You or any party on any legal theory for any damages what-
soever, including without limitation any general, special, incidental or
consequential damages arising in connection to this license. The Pub-
lisher reserves the right to cease making the Work available to You at
any time without notice
11. Miscellaneous
1. This License shall be governed by the laws of the location of the
head office of the Author or if the Author is an individual, the
laws of location of the principal place of residence of the Author.
2. If any provision of this License is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability
of the remainder of the terms of this License, and without further
action by the parties to this License, such provision shall be
reformed to the minimum extent necessary to make such provision
valid and enforceable.
3. No term or provision of this License shall be deemed waived and no
breach consented to unless such waiver or consent shall be in
writing and signed by the party to be charged with such waiver or
consent.
4. This License constitutes the entire agreement between the parties
with respect to the Work licensed herein. There are no understan-
dings, agreements or representations with respect to the Work not
specified herein. The Author shall not be bound by any additional
provisions that may appear in any communication from You. This
License may not be modified without the mutual written agreement
of the Author and You.

View File

@@ -0,0 +1,3 @@
This installer uses 3rd party components from https://github.com/stfx/innodependencyinstaller to automatically download and install .NET frameworks.
See **'innodependencyinstaller LICENSE.md'** for the license of innodependencyinstaller.

313
Installer/scripts/code.pas Normal file
View File

@@ -0,0 +1,313 @@
{
--- TYPES AND VARIABLES ---
}
type
TProduct = record
File: String;
Title: String;
Parameters: String;
ForceSuccess : boolean;
InstallClean : boolean;
MustRebootAfter : boolean;
end;
InstallResult = (InstallSuccessful, InstallRebootRequired, InstallError);
var
installMemo, downloadMemo, downloadMessage: string;
products: array of TProduct;
delayedReboot, isForcedX86: boolean;
DependencyPage: TOutputProgressWizardPage;
procedure AddProduct(filename, parameters, title, size, url: string; forceSuccess, installClean, mustRebootAfter : boolean);
{
Adds a product to the list of products to download.
Parameters:
filename: the file name under which to save the file
parameters: the parameters with which to run the file
title: the product title
size: the file size
url: the URL to download from
forceSuccess: whether to continue in case of setup failure
installClean: whether the product needs a reboot before installing
mustRebootAfter: whether the product needs a reboot after installing
}
var
path: string;
i: Integer;
begin
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);
downloadMemo := downloadMemo + '%1' + title + #13;
downloadMessage := downloadMessage + ' ' + 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);
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;
end else if (resultCode = 3010) then begin
//Windows Installer resultCode 3010: ERROR_SUCCESS_REBOOT_REQUIRED
delayedReboot := true;
finishCount := finishCount + 1;
end else begin
Result := InstallError;
break;
end;
end else begin
Result := InstallError;
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 downloadMemo <> '' then
s := s + CustomMessage('depdownload_memo_title') + ':' + NewLine + FmtMessage(downloadMemo, [Space]) + NewLine;
if installMemo <> '' then
s := s + CustomMessage('depinstall_memo_title') + ':' + NewLine + FmtMessage(installMemo, [Space]) + NewLine;
s := s + MemoDirInfo + NewLine + NewLine + MemoGroupInfo
if MemoTasksInfo <> '' then
s := s + NewLine + NewLine + MemoTasksInfo;
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 downloadMemo <> '' then begin
//change isxdl language only if it is not english because isxdl default language is already english
if (ActiveLanguage() <> 'en') then begin
ExtractTemporaryFile(CustomMessage('isxdl_langfile'));
isxdl_SetOption('language', ExpandConstant('{tmp}{\}') + CustomMessage('isxdl_langfile'));
end;
//isxdl_SetOption('title', FmtMessage(SetupMessage(msgSetupWindowTitle), [CustomMessage('appname')]));
if SuppressibleMsgBox(FmtMessage(CustomMessage('depdownload_msg'), [downloadMessage]), mbConfirmation, MB_YESNO, IDYES) = IDNO then
Result := false
else if isxdl_DownloadFiles(StrToInt(ExpandConstant('{wizardhwnd}'))) = 0 then
Result := false;
end;
end;
end;
{
-----------------------------
ARCHITECTURE HELPER FUNCTIONS
-----------------------------
}
function IsX86: boolean;
{
Gets whether the computer is x86 (32 bits).
}
begin
Result := isForcedX86 or (ProcessorArchitecture = paX86) or (ProcessorArchitecture = paUnknown);
end;
function IsX64: boolean;
{
Gets whether the computer is x64 (64 bits).
}
begin
Result := (not isForcedX86) and Is64BitInstallMode and (ProcessorArchitecture = paX64);
end;
function IsIA64: boolean;
{
Gets whether the computer is IA64 (Itanium 64 bits).
}
begin
Result := (not isForcedX86) and Is64BitInstallMode and (ProcessorArchitecture = paIA64);
end;
function GetString(x86, x64, ia64: String): String;
{
Gets a string depending on the computer architecture.
Parameters:
x86: the string if the computer is x86
x64: the string if the computer is x64
ia64: the string if the computer is IA64
}
begin
if IsX64() and (x64 <> '') then begin
Result := x64;
end else if IsIA64() and (ia64 <> '') then begin
Result := ia64;
end else begin
Result := x86;
end;
end;
function GetArchitectureString(): String;
{
Gets the "standard" architecture suffix string.
Returns either _x64, _ia64 or nothing.
}
begin
if IsX64() then begin
Result := '_x64';
end else if IsIA64() then begin
Result := '_ia64';
end else begin
Result := '';
end;
end;
procedure SetForceX86(value: boolean);
{
Forces the setup to use X86 products
}
begin
isForcedX86 := value;
end;

View File

@@ -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:

Binary file not shown.

View File

@@ -0,0 +1,14 @@
[Files]
Source: "scripts\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]

View File

@@ -0,0 +1,27 @@
#include "isxdl\isxdl.iss"
[CustomMessages]
DependenciesDir=MyProgramDependencies
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=
[Code]
#include "code.pas"
[Setup]

View File

@@ -0,0 +1,28 @@
; requires Windows 10, Windows 7 Service Pack 1, Windows 8, Windows 8.1, Windows Server 2008 R2 SP1, Windows Server 2008 Service Pack 2, Windows Server 2012, Windows Server 2012 R2, Windows Vista Service Pack 2
; WARNING: express setup (downloads and installs the components depending on your OS) if you want to deploy it on cd or network download the full bootsrapper on website below
; https://www.microsoft.com/en-US/download/details.aspx?id=49982
[CustomMessages]
dotnetfx46_title=.NET Framework 4.6.1
dotnetfx46_size=1 MB - 65 MB
;http://www.microsoft.com/globaldev/reference/lcid-all.mspx
en.dotnetfx46_lcid=
[Code]
const
dotnetfx461_url = 'http://download.microsoft.com/download/3/5/9/35980F81-60F4-4DE3-88FC-8F962B97253B/NDP461-KB3102438-Web.exe';
procedure dotnetfx46(minVersion: integer);
begin
if (not netfxinstalled(NetFx4x, '') or (netfxspversion(NetFx4x, '') < minVersion)) then
AddProduct('dotnetfx46.exe',
CustomMessage('dotnetfx46_lcid') + ' /passive /norestart',
CustomMessage('dotnetfx46_title'),
CustomMessage('dotnetfx46_size'),
dotnetfx461_url,
false, false, false);
end;
[Setup]

View File

@@ -0,0 +1,94 @@
[Code]
type
NetFXType = (NetFx10, NetFx11, NetFx20, NetFx30, NetFx35, NetFx40Client, NetFx40Full, NetFx4x);
const
netfx11plus_reg = 'Software\Microsoft\NET Framework Setup\NDP\';
function netfxinstalled(version: NetFXType; lcid: string): boolean;
var
regVersion: cardinal;
regVersionString: string;
begin
if (lcid <> '') then
lcid := '\' + lcid;
if (version = NetFx10) then begin
RegQueryStringValue(HKLM, 'Software\Microsoft\.NETFramework\Policy\v1.0\3705', 'Install', regVersionString);
Result := regVersionString <> '';
end else begin
case version of
NetFx11:
RegQueryDWordValue(HKLM, netfx11plus_reg + 'v1.1.4322' + lcid, 'Install', regVersion);
NetFx20:
RegQueryDWordValue(HKLM, netfx11plus_reg + 'v2.0.50727' + lcid, 'Install', regVersion);
NetFx30:
RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.0\Setup' + lcid, 'InstallSuccess', regVersion);
NetFx35:
RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.5' + lcid, 'Install', regVersion);
NetFx40Client:
RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Client' + lcid, 'Install', regVersion);
NetFx40Full:
RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Install', regVersion);
NetFx4x:
begin
RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Release', regVersion);
Result := (regVersion >= 378389); // 4.5.0+
Exit;
end;
end;
Result := (regVersion <> 0);
end;
end;
function netfxspversion(version: NetFXType; lcid: string): integer;
var
regVersion: cardinal;
begin
if (lcid <> '') then
lcid := '\' + lcid;
case version of
NetFx10:
//not supported
regVersion := -1;
NetFx11:
if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v1.1.4322' + lcid, 'SP', regVersion)) then
regVersion := -1;
NetFx20:
if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v2.0.50727' + lcid, 'SP', regVersion)) then
regVersion := -1;
NetFx30:
if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.0' + lcid, 'SP', regVersion)) then
regVersion := -1;
NetFx35:
if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.5' + lcid, 'SP', regVersion)) then
regVersion := -1;
NetFx40Client:
if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Client' + lcid, 'Servicing', regVersion)) then
regVersion := -1;
NetFx40Full:
if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Servicing', regVersion)) then
regVersion := -1;
NetFx4x:
if (RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Release', regVersion)) then begin
if (regVersion >= 394747) then
regVersion := 62 // 4.6.2+
else if (regVersion >= 394254) then
regVersion := 61 // 4.6.1+
else if (regVersion >= 393295) then
regVersion := 60 // 4.6+
else if (regVersion >= 379893) then
regVersion := 52 // 4.5.2+
else if (regVersion >= 378675) then
regVersion := 51 // 4.5.1+
else if (regVersion >= 378389) then
regVersion := 50 // 4.5.0+
else
regVersion := -1;
end;
end;
Result := regVersion;
end;
[Setup]

View File

@@ -0,0 +1,25 @@
[Code]
function GetFullVersion(VersionMS, VersionLS: cardinal): string;
var
version: string;
begin
version := IntToStr(word(VersionMS shr 16));
version := version + '.' + IntToStr(word(VersionMS and not $ffff0000));
version := version + '.' + IntToStr(word(VersionLS shr 16));
version := version + '.' + IntToStr(word(VersionLS and not $ffff0000));
Result := version;
end;
function fileversion(file: string): string;
var
versionMS, versionLS: cardinal;
begin
if GetVersionNumbers(file, versionMS, versionLS) then
Result := GetFullVersion(versionMS, versionLS)
else
Result := '0';
end;
[Setup]

View File

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

View File

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

82
Installer/setup.iss Normal file
View File

@@ -0,0 +1,82 @@
#define use_dotnetfx46
#define MyAppName "SmartHDD"
#define MyAppVersion "1.0.0.0"
#define MyAppPublisher "DoogeJ"
#define MyAppURL "https://github.com/DoogeJ/SmartHDD"
#define MyAppExeName "SmartHDD.exe"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
AppId={{8F0F9A45-E913-479D-97DE-0E8017B7B687}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=bin
LicenseFile=..\LICENSE
OutputBaseFilename=Install_{#MyAppName}_{#MyAppVersion}
SetupIconFile=..\Visualpharm-Hardware-Hard-disk.ico
Compression=lzma
SolidCompression=yes
; we will need administrator privileges to copy to program files and / or install prerequirements
PrivilegesRequired=admin
;Downloading and installing dependencies will only work if the memo/ready page is enabled (default behaviour)
DisableReadyPage=no
DisableReadyMemo=no
[Languages]
Name: "en"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; OnlyBelowVersion: 0,6.1
[Files]
Source: "..\SmartHDD\bin\Release\SmartHDD.exe"; DestDir: "{app}"; Flags: ignoreversion
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent runascurrentuser
[CustomMessages]
win_sp_title=Windows %1 Service Pack %2
; shared code for installing the products
#include "scripts\products.iss"
; helper functions
#include "scripts\products\stringversion.iss"
#include "scripts\products\winversion.iss"
#include "scripts\products\fileversion.iss"
#include "scripts\products\dotnetfxversion.iss"
#ifdef use_dotnetfx46
#include "scripts\products\dotnetfx46.iss"
#endif
[Code]
function InitializeSetup(): boolean;
begin
// initialize windows version
initwinversion();
#ifdef use_dotnetfx46
dotnetfx46(50); // min allowed version is 4.5.0
#endif
Result := true;
end;

View File

@@ -31,3 +31,18 @@ It will most likely build fine on different configurations, but might require so
## Updating the version number
The version number is stored in two locations:
* In the projects assembly info file: **'SmartHDD\Properties\AssemblyInfo.cs'**
* In the installer setup.iss file (only used for the installer): **'Installer\setup.iss'**
## Building the installer
> Note: *This installer uses 3rd party components from [innodependencyinstaller](https://github.com/stfx/innodependencyinstaller) to automatically download and install the correct .NET framework if required. See* ***'Installer\innodependencyinstaller LICENSE.md'*** *for the license of innodependencyinstaller.*
SmartHDD uses the [Inno Setup Compiler](http://www.jrsoftware.org/isinfo.php) to generate an executable installer.
The installer project files are located in the **'Installer'**-folder.
The scripts are based on [Inno Setup 5.5.9](http://www.jrsoftware.org/isinfo.php) but will probably work with any recent version.
To build the installer:
* Make sure the project is compiled and there is a working executable named **'SmartHDD.exe'** in the **'SmartHDD\bin\Release'**-folder
* Open **'Installer\setup.iss'** in the [Inno Setup Compiler](http://www.jrsoftware.org/isinfo.php)
* Hit *Build* -> *Compile* (Ctrl+F9)
* Done, the installer should be in the **'Installer\bin'**-folder