From 66ab8ce5d5cf170966fa897f432c3e886f63cc4f Mon Sep 17 00:00:00 2001 From: DoogeJ Date: Sun, 16 Oct 2016 18:23:10 +0200 Subject: [PATCH] Add installer --- .gitignore | 1 + Installer/innodependencyinstaller LICENSE.md | 210 ++++++++++++ Installer/innodependencyinstaller README.md | 3 + Installer/scripts/code.pas | 313 ++++++++++++++++++ Installer/scripts/isxdl/english.ini | 49 +++ Installer/scripts/isxdl/isxdl.dll | Bin 0 -> 124416 bytes Installer/scripts/isxdl/isxdl.iss | 14 + Installer/scripts/products.iss | 27 ++ Installer/scripts/products/dotnetfx46.iss | 28 ++ .../scripts/products/dotnetfxversion.iss | 94 ++++++ Installer/scripts/products/fileversion.iss | 25 ++ Installer/scripts/products/stringversion.iss | 62 ++++ Installer/scripts/products/winversion.iss | 49 +++ Installer/setup.iss | 82 +++++ README.md | 15 + 15 files changed, 972 insertions(+) create mode 100644 Installer/innodependencyinstaller LICENSE.md create mode 100644 Installer/innodependencyinstaller README.md create mode 100644 Installer/scripts/code.pas create mode 100644 Installer/scripts/isxdl/english.ini create mode 100644 Installer/scripts/isxdl/isxdl.dll create mode 100644 Installer/scripts/isxdl/isxdl.iss create mode 100644 Installer/scripts/products.iss create mode 100644 Installer/scripts/products/dotnetfx46.iss create mode 100644 Installer/scripts/products/dotnetfxversion.iss create mode 100644 Installer/scripts/products/fileversion.iss create mode 100644 Installer/scripts/products/stringversion.iss create mode 100644 Installer/scripts/products/winversion.iss create mode 100644 Installer/setup.iss diff --git a/.gitignore b/.gitignore index de7dc55..4842e6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vs SmartHDD/bin SmartHDD/obj +Installer/bin \ No newline at end of file diff --git a/Installer/innodependencyinstaller LICENSE.md b/Installer/innodependencyinstaller LICENSE.md new file mode 100644 index 0000000..77325dc --- /dev/null +++ b/Installer/innodependencyinstaller LICENSE.md @@ -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. diff --git a/Installer/innodependencyinstaller README.md b/Installer/innodependencyinstaller README.md new file mode 100644 index 0000000..bca518c --- /dev/null +++ b/Installer/innodependencyinstaller README.md @@ -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. \ No newline at end of file diff --git a/Installer/scripts/code.pas b/Installer/scripts/code.pas new file mode 100644 index 0000000..bf437e8 --- /dev/null +++ b/Installer/scripts/code.pas @@ -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; diff --git a/Installer/scripts/isxdl/english.ini b/Installer/scripts/isxdl/english.ini new file mode 100644 index 0000000..55b2878 --- /dev/null +++ b/Installer/scripts/isxdl/english.ini @@ -0,0 +1,49 @@ +[strings] +; General +100=File download +101=Do you want to cancel the download? +102=%1 (%2 of %3) +103=%1 KB +104=%1 KB of %2 KB (%3%) + +; Status information +110=Getting file information... +111=Redirecting to %1 +112=Sending request... +113=Resolving %1 +114=Connected to %1 +115=Receiving... +116=Connecting to %1 + +; Error messages +120=Error connecting to the internet.\n\n%1 +121=Error opening %1.\n\nThe server returned status code %2. +122=Error reading URL.\n\n%1 +123=Error writing file %1.\n\n%2 +124=Error opening file %1.\n\n%2 +125='%1' is an invalid URL. +126=Error opening %1.\n\n%2 +127=Error sending request.\n\n%1 +128=Unsupported protocol. Only HTTP and FTP protocols are supported. +129=Failed to connect to %1.\n\n%2 +130=Failed to query status code.\n\n%1 +131=Error requesting file.\n\n%1 + +; Other +144=About... +146=Download +147=Setup is now downloading additional files to your computer. + +; labels +160=File: +161=Speed: +162=Status: +163=Elapsed Time: +164=Remaining Time: +165=Current File: +166=Overall Progress: +167=Cancel +168=OK +169=User Name and Password +170=User Name: +171=Password: diff --git a/Installer/scripts/isxdl/isxdl.dll b/Installer/scripts/isxdl/isxdl.dll new file mode 100644 index 0000000000000000000000000000000000000000..d227bcad82b145e18a122348dab7227d3816bf90 GIT binary patch literal 124416 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 '') 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] diff --git a/Installer/scripts/products/fileversion.iss b/Installer/scripts/products/fileversion.iss new file mode 100644 index 0000000..b5570c5 --- /dev/null +++ b/Installer/scripts/products/fileversion.iss @@ -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] diff --git a/Installer/scripts/products/stringversion.iss b/Installer/scripts/products/stringversion.iss new file mode 100644 index 0000000..e7ee3d7 --- /dev/null +++ b/Installer/scripts/products/stringversion.iss @@ -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] diff --git a/Installer/scripts/products/winversion.iss b/Installer/scripts/products/winversion.iss new file mode 100644 index 0000000..c6d7e72 --- /dev/null +++ b/Installer/scripts/products/winversion.iss @@ -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] diff --git a/Installer/setup.iss b/Installer/setup.iss new file mode 100644 index 0000000..0fbd400 --- /dev/null +++ b/Installer/setup.iss @@ -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; \ No newline at end of file diff --git a/README.md b/README.md index 6ebd595..3f0298b 100644 --- a/README.md +++ b/README.md @@ -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 \ No newline at end of file