]> git.proxmox.com Git - mirror_smartmontools-debian.git/blobdiff - os_win32/installer.nsi
import smartmontools 7.0
[mirror_smartmontools-debian.git] / os_win32 / installer.nsi
index 16d21432f106b6f7170151f16945f7f25d3a2609..f9e281a55e33c7b7148d07e5e152121f3787c1d5 100644 (file)
@@ -1,20 +1,20 @@
 ;
-; installer.nsi - NSIS install script for smartmontools
+; os_win32/installer.nsi - smartmontools install NSIS script
 ;
-; Copyright (C) 2006-8 Christian Franke <smartmontools-support@lists.sourceforge.net>
+; Home page of code is: http://www.smartmontools.org
 ;
-; Project home page is: http://smartmontools.sourceforge.net
+; Copyright (C) 2006-17 Christian Franke
 ;
-; Download and install NSIS from: http://nsis.sourceforge.net/Download
-; Process with makensis to create installer (tested with NSIS 2.29)
+; SPDX-License-Identifier: GPL-2.0-or-later
 ;
-; $Id: installer.nsi,v 1.4 2008/03/04 22:09:48 ballen4705 Exp $
+; $Id: installer.nsi 4760 2018-08-19 18:45:53Z chrfranke $
 ;
 
 
 ;--------------------------------------------------------------------
 ; Command line arguments:
-; makensis /DINPDIR=<input-dir> /DOUTFILE=<output-file> installer.nsi
+; makensis -DINPDIR=<input-dir> -DINPDIR64=<input-dir-64-bit> \
+;   -DOUTFILE=<output-file> -DVERSTR=<version-string> installer.nsi
 
 !ifndef INPDIR
   !define INPDIR "."
 Name "smartmontools"
 OutFile "${OUTFILE}"
 
+RequestExecutionLevel admin
+
 SetCompressor /solid lzma
 
 XPStyle on
 InstallColors /windows
 
-InstallDir "$PROGRAMFILES\smartmontools"
-InstallDirRegKey HKLM "Software\smartmontools" "Install_Dir"
-Var UBCDDIR
+; Set in .onInit
+;InstallDir "$PROGRAMFILES\smartmontools"
+;InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "InstallLocation"
+
+!ifdef VERSION
+  VIProductVersion "${VERSION}"
+  VIAddVersionKey /LANG=1033-English "CompanyName" "www.smartmontools.org"
+  VIAddVersionKey /LANG=1033-English "FileDescription" "SMART Monitoring Tools"
+  VIAddVersionKey /LANG=1033-English "FileVersion" "${VERSION}"
+ !ifdef YY
+  VIAddVersionKey /LANG=1033-English "LegalCopyright" "(C) 2002-20${YY}, Bruce Allen, Christian Franke, www.smartmontools.org"
+ !endif
+  VIAddVersionKey /LANG=1033-English "OriginalFilename" "${OUTFILE}"
+  VIAddVersionKey /LANG=1033-English "ProductName" "smartmontools"
+  VIAddVersionKey /LANG=1033-English "ProductVersion" "${VERSION}"
+!endif
+
+Var EDITOR
+
+!ifdef INPDIR64
+  Var X64
+  Var INSTDIR32
+  Var INSTDIR64
+!endif
 
 LicenseData "${INPDIR}\doc\COPYING.txt"
 
+!include "FileFunc.nsh"
+!include "LogicLib.nsh"
+!include "Sections.nsh"
+
+
 ;--------------------------------------------------------------------
 ; Pages
 
 Page license
 Page components
-Page directory SkipProgPath "" ""
-PageEx directory
-  PageCallbacks SkipUBCDPath "" ""
-  DirText "Setup will install the UBCD4Win plugin in the following folder."
-  DirVar $UBCDDIR
-PageExEnd
+!ifdef INPDIR64
+  Page directory CheckX64
+!else
+  Page directory
+!endif
 Page instfiles
 
 UninstPage uninstConfirm
@@ -60,49 +87,108 @@ UninstPage instfiles
 InstType "Full"
 InstType "Extract files only"
 InstType "Drive menu"
-InstType "UBCD4Win plugin"
+!ifdef INPDIR64
+InstType "Full (x64)"
+InstType "Extract files only (x64)"
+InstType "Drive menu (x64)"
+!endif
 
 
 ;--------------------------------------------------------------------
 ; Sections
 
+!ifdef INPDIR64
+  Section "64-bit version" X64_SECTION
+    SectionIn 4 5 6
+    ; Handled in Function CheckX64
+  SectionEnd
+
+  !define FULL_TYPES "1 4"
+  !define EXTRACT_TYPES  "2 5"
+  !define DRIVEMENU_TYPE     "3 6"
+!else
+  !define FULL_TYPES "1"
+  !define EXTRACT_TYPES  "2"
+  !define DRIVEMENU_TYPE     "3"
+!endif
+
 SectionGroup "!Program files"
 
+  !macro FileExe path option
+    !ifdef INPDIR64
+      ; Use dummy SetOutPath to control archive location of executables
+      ${If} $X64 != ""
+        Goto +2
+          SetOutPath "$INSTDIR\bin64"
+        File ${option} '${INPDIR64}\${path}'
+      ${Else}
+        Goto +2
+          SetOutPath "$INSTDIR\bin"
+        File ${option} '${INPDIR}\${path}'
+      ${EndIf}
+    !else
+      File ${option} '${INPDIR}\${path}'
+    !endif
+  !macroend
+
   Section "smartctl" SMARTCTL_SECTION
 
-    SectionIn 1 2
+    SectionIn ${FULL_TYPES} ${EXTRACT_TYPES}
 
     SetOutPath "$INSTDIR\bin"
-    File "${INPDIR}\bin\smartctl.exe"
+    !insertmacro FileExe "bin\smartctl.exe" ""
 
   SectionEnd
 
   Section "smartd" SMARTD_SECTION
 
-    SectionIn 1 2
+    SectionIn ${FULL_TYPES} ${EXTRACT_TYPES}
 
     SetOutPath "$INSTDIR\bin"
 
     ; Stop service ?
     StrCpy $1 ""
-    IfFileExists "$INSTDIR\bin\smartd.exe" 0 nosrv
+    ${If} ${FileExists} "$INSTDIR\bin\smartd.exe"
       ReadRegStr $0 HKLM "System\CurrentControlSet\Services\smartd" "ImagePath"
-      StrCmp $0 "" nosrv
+      ${If} $0 != ""
         ExecWait "net stop smartd" $1
-  nosrv:
-    File "${INPDIR}\bin\smartd.exe"
+      ${EndIf}
+    ${EndIf}
+    !insertmacro FileExe "bin\smartd.exe" ""
 
     IfFileExists "$INSTDIR\bin\smartd.conf" 0 +2
-      MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Replace existing configuration file$\n$INSTDIR\bin\smartd.conf ?" IDYES 0 IDNO +2
+      MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Replace existing configuration file$\n$INSTDIR\bin\smartd.conf ?" /SD IDNO IDYES 0 IDNO +2
         File "${INPDIR}\doc\smartd.conf"
 
-    IfFileExists "$WINDIR\system32\cmd.exe" 0 +2
-      File /nonfatal "${INPDIR}\bin\syslogevt.exe"
+    File "${INPDIR}\bin\smartd_mailer.ps1"
+    File "${INPDIR}\bin\smartd_mailer.conf.sample.ps1"
+    File "${INPDIR}\bin\smartd_warning.cmd"
+    !insertmacro FileExe "bin\wtssendmsg.exe" ""
 
     ; Restart service ?
-    StrCmp $1 "0" 0 +3
-      MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Restart smartd service ?" IDYES 0 IDNO +2
+    ${If} $1 == "0"
+      MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Restart smartd service ?" /SD IDNO IDYES 0 IDNO +2
         ExecWait "net start smartd"
+    ${EndIf}
+
+  SectionEnd
+
+  Section "smartctl-nc (GSmartControl)" SMARTCTL_NC_SECTION
+
+    SectionIn ${FULL_TYPES} ${EXTRACT_TYPES}
+
+    SetOutPath "$INSTDIR\bin"
+    !insertmacro FileExe "bin\smartctl-nc.exe" ""
+
+  SectionEnd
+
+  Section "drivedb.h (Drive Database)" DRIVEDB_SECTION
+
+    SectionIn ${FULL_TYPES} ${EXTRACT_TYPES}
+
+    SetOutPath "$INSTDIR\bin"
+    File "${INPDIR}\bin\drivedb.h"
+    File "${INPDIR}\bin\update-smart-drivedb.exe"
 
   SectionEnd
 
@@ -110,45 +196,62 @@ SectionGroupEnd
 
 Section "!Documentation" DOC_SECTION
 
-  SectionIn 1 2
+  SectionIn ${FULL_TYPES} ${EXTRACT_TYPES}
 
   SetOutPath "$INSTDIR\doc"
   File "${INPDIR}\doc\AUTHORS.txt"
-  File "${INPDIR}\doc\CHANGELOG.txt"
+  File "${INPDIR}\doc\ChangeLog.txt"
+  File "${INPDIR}\doc\ChangeLog-5.0-6.0.txt"
   File "${INPDIR}\doc\COPYING.txt"
   File "${INPDIR}\doc\INSTALL.txt"
   File "${INPDIR}\doc\NEWS.txt"
   File "${INPDIR}\doc\README.txt"
   File "${INPDIR}\doc\TODO.txt"
-  File "${INPDIR}\doc\WARNINGS.txt"
+!ifdef INPDIR64
+  ${If} $X64 != ""
+    File "${INPDIR64}\doc\checksums64.txt"
+  ${Else}
+    File "${INPDIR}\doc\checksums32.txt"
+  ${EndIf}
+!else
+  File "${INPDIR}\doc\checksums??.txt"
+!endif
   File "${INPDIR}\doc\smartctl.8.html"
-  File "${INPDIR}\doc\smartctl.8.txt"
+  File "${INPDIR}\doc\smartctl.8.pdf"
+  Delete "$INSTDIR\doc\smartctl.8.txt" ; TODO: Remove after smartmontools 6.6
   File "${INPDIR}\doc\smartd.8.html"
-  File "${INPDIR}\doc\smartd.8.txt"
+  File "${INPDIR}\doc\smartd.8.pdf"
+  Delete "$INSTDIR\doc\smartd.8.txt" ; TODO: Remove after smartmontools 6.6
   File "${INPDIR}\doc\smartd.conf"
   File "${INPDIR}\doc\smartd.conf.5.html"
-  File "${INPDIR}\doc\smartd.conf.5.txt"
+  File "${INPDIR}\doc\smartd.conf.5.pdf"
+  Delete "$INSTDIR\doc\smartd.conf.5.txt" ; TODO: Remove after smartmontools 6.6
 
 SectionEnd
 
 Section "Uninstaller" UNINST_SECTION
 
-  SectionIn 1
-  AddSize 35
+  SectionIn ${FULL_TYPES}
+  AddSize 40
 
   CreateDirectory "$INSTDIR"
 
-  ; Save installation location
-  WriteRegStr HKLM "Software\smartmontools" "Install_Dir" "$INSTDIR"
+  ; Remove old "Install_Dir" registry entry (smartmontools < r3911/6.3)
+  ; No longer needed for GSmartControl
+  DeleteRegKey HKLM "Software\smartmontools" ; TODO: Remove after smartmontools 6.7
 
   ; Write uninstall keys and program
   WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayName" "smartmontools"
-  ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher" "smartmontools"
+!ifdef VERSTR
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayVersion" "${VERSTR}"
+!endif
+  ; Important: GSmartControl (>= 1.0.0) reads "InstallLocation" to detect location of bin\smartctl-nc.exe
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "InstallLocation" "$INSTDIR"
   WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"'
-  ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "http://smartmontools.sourceforge.net/"
-  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "HelpLink"     "http://smartmontools.sourceforge.net/"
-  ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://sourceforge.net/project/showfiles.php?group_id=64297"
-  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://smartmontools-win32.dyndns.org/"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher"     "smartmontools.org"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout"  "https://www.smartmontools.org/"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "HelpLink"      "https://www.smartmontools.org/wiki/Help"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "https://builds.smartmontools.org/"
   WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoModify" 1
   WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoRepair" 1
   WriteUninstaller "uninst-smartmontools.exe"
@@ -157,110 +260,116 @@ SectionEnd
 
 Section "Start Menu Shortcuts" MENU_SECTION
 
-  SectionIn 1
+  SectionIn ${FULL_TYPES}
+
+  SetShellVarContext all
 
   CreateDirectory "$SMPROGRAMS\smartmontools"
 
+  !macro CreateAdminShortCut link target args
+    CreateShortCut '${link}' '${target}' '${args}'
+    push '${link}'
+    Call ShellLinkSetRunAs
+  !macroend
+
+  ; runcmdu
+  ${If}   ${FileExists} "$INSTDIR\bin\smartctl.exe"
+  ${OrIf} ${FileExists} "$INSTDIR\bin\smartd.exe"
+    SetOutPath "$INSTDIR\bin"
+    !insertmacro FileExe "bin\runcmdu.exe" ""
+  ${EndIf}
+
   ; smartctl
-  IfFileExists "$INSTDIR\bin\smartctl.exe" 0 noctl
+  ${If} ${FileExists} "$INSTDIR\bin\smartctl.exe"
     SetOutPath "$INSTDIR\bin"
-    DetailPrint "Create file: $INSTDIR\bin\smartctl-run.bat"
-    Push "$INSTDIR\bin\smartctl-run.bat"
-    Call CreateSmartctlBat
-    IfFileExists "$WINDIR\system32\cmd.exe" 0 +2
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartctl (CMD).lnk" "cmd.exe" "/k smartctl-run.bat"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl (Admin CMD).lnk" "$WINDIR\system32\cmd.exe" '/k PATH=$INSTDIR\bin;%PATH%&cd /d "$INSTDIR\bin"'
     CreateDirectory "$SMPROGRAMS\smartmontools\smartctl Examples"
     FileOpen $0 "$SMPROGRAMS\smartmontools\smartctl Examples\!Read this first!.txt" "w"
     FileWrite $0 "All the example commands in this directory$\r$\napply to the first drive (sda).$\r$\n"
     FileClose $0
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\All info (-a).lnk"                    "$INSTDIR\bin\smartctl-run.bat" "-a sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Identify drive (-i).lnk"              "$INSTDIR\bin\smartctl-run.bat" "-i sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART attributes (-A).lnk"            "$INSTDIR\bin\smartctl-run.bat" "-A sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART capabilities (-c).lnk"          "$INSTDIR\bin\smartctl-run.bat" "-c sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART health status (-H).lnk"         "$INSTDIR\bin\smartctl-run.bat" "-H sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART error log (-l error).lnk"       "$INSTDIR\bin\smartctl-run.bat" "-l error sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART selftest log (-l selftest).lnk" "$INSTDIR\bin\smartctl-run.bat" "-l selftest sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start long selftest (-t long).lnk"    "$INSTDIR\bin\smartctl-run.bat" "-t long sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start offline test (-t offline).lnk"  "$INSTDIR\bin\smartctl-run.bat" "-t offline sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start short selftest (-t short).lnk"  "$INSTDIR\bin\smartctl-run.bat" "-t short sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Stop(Abort) selftest (-X).lnk"        "$INSTDIR\bin\smartctl-run.bat" "-X sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Turn SMART off (-s off).lnk"          "$INSTDIR\bin\smartctl-run.bat" "-s off sda"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Turn SMART on (-s on).lnk"            "$INSTDIR\bin\smartctl-run.bat" "-s on sda"  
-  noctl:
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\All info (-x).lnk"                    "$INSTDIR\bin\runcmdu.exe" "smartctl -x sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Identify drive (-i).lnk"              "$INSTDIR\bin\runcmdu.exe" "smartctl -i sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART attributes (-A -f brief).lnk"   "$INSTDIR\bin\runcmdu.exe" "smartctl -A -f brief sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART capabilities (-c).lnk"          "$INSTDIR\bin\runcmdu.exe" "smartctl -c sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART health status (-H).lnk"         "$INSTDIR\bin\runcmdu.exe" "smartctl -H sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART error log (-l error).lnk"       "$INSTDIR\bin\runcmdu.exe" "smartctl -l error sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART selftest log (-l selftest).lnk" "$INSTDIR\bin\runcmdu.exe" "smartctl -l selftest sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start long selftest (-t long).lnk"    "$INSTDIR\bin\runcmdu.exe" "smartctl -t long sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start offline test (-t offline).lnk"  "$INSTDIR\bin\runcmdu.exe" "smartctl -t offline sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start short selftest (-t short).lnk"  "$INSTDIR\bin\runcmdu.exe" "smartctl -t short sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Stop(Abort) selftest (-X).lnk"        "$INSTDIR\bin\runcmdu.exe" "smartctl -X sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Turn SMART off (-s off).lnk"          "$INSTDIR\bin\runcmdu.exe" "smartctl -s off sda"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Turn SMART on (-s on).lnk"            "$INSTDIR\bin\runcmdu.exe" "smartctl -s on sda"
+  ${EndIf}
 
   ; smartd
-  IfFileExists "$INSTDIR\bin\smartd.exe" 0 nod
+  ${If} ${FileExists} "$INSTDIR\bin\smartd.exe"
     SetOutPath "$INSTDIR\bin"
-    DetailPrint "Create file: $INSTDIR\bin\smartd-run.bat"
-    FileOpen $0 "$INSTDIR\bin\smartd-run.bat" "w"
-    FileWrite $0 "@echo off$\r$\necho smartd %1 %2 %3 %4 %5$\r$\nsmartd %1 %2 %3 %4 %5$\r$\npause$\r$\n"
-    FileClose $0
     CreateDirectory "$SMPROGRAMS\smartmontools\smartd Examples"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon start, smartd.log.lnk" "$INSTDIR\bin\smartd-run.bat" "-l local0"
-    IfFileExists "$WINDIR\system32\cmd.exe" 0 +2
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon start, eventlog.lnk" "$INSTDIR\bin\smartd-run.bat" ""
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon stop.lnk" "$INSTDIR\bin\smartd-run.bat" "stop"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Do all tests once (-q onecheck).lnk" "$INSTDIR\bin\smartd-run.bat" "-q onecheck"
-    CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Debug mode (-d).lnk" "$INSTDIR\bin\smartd-run.bat" "-d"
-    IfFileExists "$WINDIR\notepad.exe" 0 nopad
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Edit smartd.conf.lnk" "$WINDIR\notepad.exe" "$INSTDIR\bin\smartd.conf"
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\View smartd.log.lnk" "$WINDIR\notepad.exe" "$INSTDIR\bin\smartd.log"
-    nopad:
-
-    ; smartd service (not on 9x/ME)
-    IfFileExists "$WINDIR\system32\cmd.exe" 0 nosvc
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, eventlog, 30min.lnk" "$INSTDIR\bin\smartd-run.bat" "install"
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, smartd.log, 10min.lnk" "$INSTDIR\bin\smartd-run.bat" "install -l local0 -i 600"
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, smartd.log, 30min.lnk" "$INSTDIR\bin\smartd-run.bat" "install -l local0"
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service remove.lnk" "$INSTDIR\bin\smartd-run.bat" "remove"
-      DetailPrint "Create file: $INSTDIR\bin\net-run.bat"
-      FileOpen $0 "$INSTDIR\bin\net-run.bat" "w"
-      FileWrite $0 "@echo off$\r$\necho net %1 %2 %3 %4 %5$\r$\nnet %1 %2 %3 %4 %5$\r$\npause$\r$\n"
-      FileClose $0
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service start.lnk" "$INSTDIR\bin\net-run.bat" "start smartd"
-      CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service stop.lnk" "$INSTDIR\bin\net-run.bat" "stop smartd"
-    nosvc:
-  nod:
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon start, smartd.log.lnk"           "$INSTDIR\bin\runcmdu.exe" "smartd -l local0"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon start, eventlog.lnk"             "$INSTDIR\bin\runcmdu.exe" "smartd"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon stop.lnk"                        "$INSTDIR\bin\runcmdu.exe" "smartd stop"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Do all tests once (-q onecheck).lnk"    "$INSTDIR\bin\runcmdu.exe" "smartd -q onecheck"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Debug mode (-d).lnk"                    "$INSTDIR\bin\runcmdu.exe" "smartd -d"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.conf (edit).lnk" "$EDITOR" '"$INSTDIR\bin\smartd.conf"'
+    CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.conf (view).lnk"                   "$EDITOR" '"$INSTDIR\bin\smartd.conf"'
+    CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.log (view).lnk"                    "$EDITOR" '"$INSTDIR\bin\smartd.log"'
+    CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd_mailer.conf.sample.ps1 (view).lnk" "$EDITOR" '"$INSTDIR\bin\smartd_mailer.conf.sample.ps1"'
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd_mailer.conf.ps1 (create, edit).lnk" "$EDITOR" '"$INSTDIR\bin\smartd_mailer.conf.ps1"'
+
+    ; smartd service
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, eventlog, 30min.lnk"   "$INSTDIR\bin\runcmdu.exe" "smartd install"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, smartd.log, 10min.lnk" "$INSTDIR\bin\runcmdu.exe" "smartd install -l local0 -i 600"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, smartd.log, 30min.lnk" "$INSTDIR\bin\runcmdu.exe" "smartd install -l local0"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service remove.lnk"                     "$INSTDIR\bin\runcmdu.exe" "smartd remove"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service start.lnk"                      "$INSTDIR\bin\runcmdu.exe" "net start smartd"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service stop.lnk"                       "$INSTDIR\bin\runcmdu.exe" "net stop smartd"
+  ${EndIf}
 
   ; Documentation
-  IfFileExists "$INSTDIR\doc\README.TXT" 0 nodoc
+  ${If} ${FileExists} "$INSTDIR\doc\README.TXT"
     SetOutPath "$INSTDIR\doc"
     CreateDirectory "$SMPROGRAMS\smartmontools\Documentation"
     CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (html).lnk"    "$INSTDIR\doc\smartctl.8.html"
     CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (html).lnk"      "$INSTDIR\doc\smartd.8.html"
     CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (html).lnk" "$INSTDIR\doc\smartd.conf.5.html"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (txt).lnk"     "$INSTDIR\doc\smartctl.8.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (txt).lnk"       "$INSTDIR\doc\smartd.8.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (txt).lnk"  "$INSTDIR\doc\smartd.conf.5.txt"
-    IfFileExists "$WINDIR\notepad.exe" 0 +2
-      CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf sample.lnk" "$WINDIR\notepad.exe" "$INSTDIR\doc\smartd.conf"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\AUTHORS.lnk"   "$INSTDIR\doc\AUTHORS.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\CHANGELOG.lnk" "$INSTDIR\doc\CHANGELOG.txt"
+    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (pdf).lnk"     "$INSTDIR\doc\smartctl.8.pdf"
+    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (pdf).lnk"       "$INSTDIR\doc\smartd.8.pdf"
+    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (pdf).lnk"  "$INSTDIR\doc\smartd.conf.5.pdf"
+    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf sample.lnk" "$EDITOR" '"$INSTDIR\doc\smartd.conf"'
+    ${If} ${FileExists} "$INSTDIR\bin\drivedb.h"
+      CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\drivedb.h (view).lnk" "$EDITOR" '"$INSTDIR\bin\drivedb.h"'
+      !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\Documentation\drivedb-add.h (create, edit).lnk" "$EDITOR" '"$INSTDIR\bin\drivedb-add.h"'
+    ${EndIf}
+    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\ChangeLog.lnk" "$INSTDIR\doc\ChangeLog.txt"
     CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\COPYING.lnk"   "$INSTDIR\doc\COPYING.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\INSTALL.lnk"   "$INSTDIR\doc\INSTALL.txt"
     CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\NEWS.lnk"      "$INSTDIR\doc\NEWS.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\README.lnk"    "$INSTDIR\doc\README.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\TODO.lnk"      "$INSTDIR\doc\TODO.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\WARNINGS.lnk"  "$INSTDIR\doc\WARNINGS.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\Windows version download page.lnk" "http://smartmontools-win32.dyndns.org/smartmontools/"
-  nodoc:
+  ${EndIf}
 
   ; Homepage
-  CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "http://smartmontools.sourceforge.net/"
+  CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "https://www.smartmontools.org/"
+  CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Daily Builds.lnk" "https://builds.smartmontools.org/"
+
+  ; drivedb.h update
+  ${If} ${FileExists} "$INSTDIR\bin\update-smart-drivedb.exe"
+    SetOutPath "$INSTDIR\bin"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\drivedb.h update.lnk" "$INSTDIR\bin\update-smart-drivedb.exe" ""
+  ${EndIf}
 
   ; Uninstall
-  IfFileExists "$INSTDIR\uninst-smartmontools.exe" 0 +2
-    CreateShortCut "$SMPROGRAMS\smartmontools\Uninstall smartmontools.lnk" "$INSTDIR\uninst-smartmontools.exe"
+  ${If} ${FileExists} "$INSTDIR\uninst-smartmontools.exe"
+    SetOutPath "$INSTDIR"
+    !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\Uninstall smartmontools.lnk" "$INSTDIR\uninst-smartmontools.exe" ""
+  ${EndIf}
 
 SectionEnd
 
 Section "Add install dir to PATH" PATH_SECTION
 
-  SectionIn 1
+  SectionIn ${FULL_TYPES}
 
-  IfFileExists "$WINDIR\system32\cmd.exe" 0 +3
-    Push "$INSTDIR\bin"
-    Call AddToPath
+  Push "$INSTDIR\bin"
+  Call AddToPath
  
 SectionEnd
 
@@ -276,131 +385,113 @@ SectionGroup "Add smartctl to drive menu"
   DeleteRegKey HKCR "Drive\shell\smartctl5"
 !macroend
 
-  Section "Remove existing entries first"
-    SectionIn 3
+  Section "Remove existing entries first" DRIVE_REMOVE_SECTION
+    SectionIn ${DRIVEMENU_TYPE}
     !insertmacro DriveMenuRemove
   SectionEnd
 
 !macro DriveSection id name args
   Section 'smartctl ${args} ...' DRIVE_${id}_SECTION
-    SectionIn 3
+    SectionIn ${DRIVEMENU_TYPE}
+    Call CheckRunCmdA
     DetailPrint 'Add drive menu entry "${name}": smartctl ${args} ...'
     WriteRegStr HKCR "Drive\shell\smartctl${id}" "" "${name}"
-    WriteRegStr HKCR "Drive\shell\smartctl${id}\command" "" '"$INSTDIR\bin\smartctl-run.bat" ${args} %L'
+    WriteRegStr HKCR "Drive\shell\smartctl${id}\command" "" '"$INSTDIR\bin\runcmda.exe" "$INSTDIR\bin\smartctl.exe" ${args} %L'
   SectionEnd
 !macroend
 
-  !insertmacro DriveSection 0 "SMART all info"       "-a"
+  !insertmacro DriveSection 0 "SMART all info"       "-x"
   !insertmacro DriveSection 1 "SMART status"         "-Hc"
-  !insertmacro DriveSection 2 "SMART attributes"     "-A"
+  !insertmacro DriveSection 2 "SMART attributes"     "-A -f brief"
   !insertmacro DriveSection 3 "SMART short selftest" "-t short"
   !insertmacro DriveSection 4 "SMART long selftest"  "-t long"
   !insertmacro DriveSection 5 "SMART continue selective selftest"  '-t "selective,cont"'
 
 SectionGroupEnd
 
-Section "UBCD4Win Plugin" UBCD_SECTION
-
-  SectionIn 4
-
-  SetOutPath "$UBCDDIR"
-  DetailPrint "Create file: smartmontools.inf"
-  FileOpen $0 "$UBCDDIR\smartmontools.inf" "w"
-  FileWrite $0 '; smartmontools.inf$\r$\n; PE Builder v3 plug-in INF file$\r$\n'
-  FileWrite $0 '; Created by smartmontools installer$\r$\n'
-  FileWrite $0 '; http://smartmontools.sourceforge.net/$\r$\n$\r$\n'
-  FileWrite $0 '[Version]$\r$\nSignature= "$$Windows NT$$"$\r$\n$\r$\n'
-  FileWrite $0 '[PEBuilder]$\r$\nName="Disk -Diagnostic: smartmontools"$\r$\n'
-  FileWrite $0 'Enable=1$\r$\nHelp="files\smartctl.8.html"$\r$\n$\r$\n'
-  FileWrite $0 '[WinntDirectories]$\r$\na=Programs\smartmontools,2$\r$\n$\r$\n'
-  FileWrite $0 '[SourceDisksFolders]$\r$\nfiles=a,,1$\r$\n$\r$\n'
-  FileWrite $0 '[Append]$\r$\nnu2menu.xml, smartmontools_nu2menu.xml$\r$\n'
-  FileClose $0
-
-  DetailPrint "Create file: smartmontools_nu2menu.xml"
-  FileOpen $0 "$UBCDDIR\smartmontools_nu2menu.xml" "w"
-  FileWrite $0 '<!-- Nu2Menu entry for smartmontools -->$\r$\n<NU2MENU>$\r$\n'
-  FileWrite $0 '$\t<MENU ID="Programs">$\r$\n$\t$\t<MITEM TYPE="POPUP" MENUID="Disk Tools">'
-  FileWrite $0 'Disk Tools</MITEM>$\r$\n$\t</MENU>$\r$\n$\t<MENU ID="Disk Tools">$\r$\n'
-  FileWrite $0 '$\t$\t<MITEM TYPE="POPUP" MENUID="Diagnostic">Diagnostic</MITEM>$\r$\n$\t</MENU>'
-  FileWrite $0 '$\r$\n$\t<MENU ID="Diagnostic">$\r$\n$\t$\t<MITEM TYPE="ITEM" DISABLED="'
-  FileWrite $0 '@Not(@FileExists(@GetProgramDrive()\Programs\smartmontools\smartctl.exe))" '
-  FileWrite $0 'CMD="RUN" FUNC="cmd.exe /k cd /d @GetProgramDrive()\Programs\smartmontools&'
-  FileWrite $0 'set PATH=@GetProgramDrive()\Programs\smartmontools;%PATH%&smartctl-run.bat  ">'
-  FileWrite $0 'smartctl</MITEM>$\r$\n$\t</MENU>$\r$\n</NU2MENU>$\r$\n'
-  FileClose $0
-  
-  SetOutPath "$UBCDDIR\files"
-  DetailPrint "Create file: smartctl-run.bat"
-  Push "$UBCDDIR\files\smartctl-run.bat"
-  Call CreateSmartctlBat
-  File "${INPDIR}\bin\smartctl.exe"
-  File "${INPDIR}\bin\smartd.exe"
-  File "${INPDIR}\doc\smartctl.8.html"
-  File "${INPDIR}\doc\smartctl.8.txt"
-  File "${INPDIR}\doc\smartd.8.html"
-  File "${INPDIR}\doc\smartd.8.txt"
-  File "${INPDIR}\doc\smartd.conf"
-
-SectionEnd
-
-
 ;--------------------------------------------------------------------
 
 Section "Uninstall"
   
   ; Stop & remove service
-  IfFileExists "$INSTDIR\bin\smartd.exe" 0 nosrv
+  ${If} ${FileExists} "$INSTDIR\bin\smartd.exe"
     ReadRegStr $0 HKLM "System\CurrentControlSet\Services\smartd" "ImagePath"
-    StrCmp $0 "" nosrv
+    ${If} $0 != ""
       ExecWait "net stop smartd"
-      MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Remove smartd service ?" IDYES 0 IDNO nosrv
+      MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Remove smartd service ?" /SD IDNO IDYES 0 IDNO +2
         ExecWait "$INSTDIR\bin\smartd.exe remove"
-  nosrv:
+    ${EndIf}
+  ${EndIf}
 
-  ; Remove installer registry keys
+  ; Remove installer registry key
   DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools"
-  DeleteRegKey HKLM "Software\smartmontools"
 
-  ; Remove conf and log file
-  IfFileExists "$INSTDIR\bin\smartd.conf" 0 noconf
+  ; Remove conf file ?
+  ${If} ${FileExists} "$INSTDIR\bin\smartd.conf"
     ; Assume unchanged if timestamp is equal to sample file
     GetFileTime "$INSTDIR\bin\smartd.conf" $0 $1
     GetFileTime "$INSTDIR\doc\smartd.conf" $2 $3
     StrCmp "$0:$1" "$2:$3" +2 0
-      MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Delete configuration file$\n$INSTDIR\bin\smartd.conf ?" IDYES 0 IDNO noconf
+      MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Delete configuration file$\n$INSTDIR\bin\smartd.conf ?" /SD IDNO IDYES 0 IDNO +2
         Delete "$INSTDIR\bin\smartd.conf"
-  noconf:
+  ${EndIf}
 
-  IfFileExists "$INSTDIR\bin\smartd.log" 0 +3
-    MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Delete log file$\n$INSTDIR\bin\smartd.log ?" IDYES 0 IDNO +2
+  ; Remove log file ?
+  ${If} ${FileExists} "$INSTDIR\bin\smartd.log"
+    MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Delete log file$\n$INSTDIR\bin\smartd.log ?" /SD IDNO IDYES 0 IDNO +2
       Delete "$INSTDIR\bin\smartd.log"
+  ${EndIf}
+
+  ; Remove drivedb-add file ?
+  ${If} ${FileExists} "$INSTDIR\bin\drivedb-add.h"
+    MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2  "Delete local drive database file$\n$INSTDIR\bin\drivedb-add.h ?" /SD IDNO IDYES 0 IDNO +2
+      Delete "$INSTDIR\bin\drivedb-add.h"
+  ${EndIf}
+
+  ; Remove smartd_mailer.conf.ps1 file ?
+  ${If} ${FileExists} "$INSTDIR\bin\smartd_mailer.conf.ps1"
+    MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Delete mailer configuration file$\n$INSTDIR\bin\smartd_mailer.conf.ps1 ?" /SD IDNO IDYES 0 IDNO +2
+      Delete "$INSTDIR\bin\smartd_mailer.conf.ps1"
+  ${EndIf}
 
   ; Remove files
   Delete "$INSTDIR\bin\smartctl.exe"
+  Delete "$INSTDIR\bin\smartctl-nc.exe"
   Delete "$INSTDIR\bin\smartd.exe"
-  Delete "$INSTDIR\bin\syslogevt.exe"
-  Delete "$INSTDIR\bin\smartctl-run.bat"
-  Delete "$INSTDIR\bin\smartd-run.bat"
-  Delete "$INSTDIR\bin\net-run.bat"
+  Delete "$INSTDIR\bin\smartd_mailer.ps1"
+  Delete "$INSTDIR\bin\smartd_mailer.conf.sample.ps1"
+  Delete "$INSTDIR\bin\smartd_warning.cmd" ; TODO: Check for modifications?
+  Delete "$INSTDIR\bin\drivedb.h"
+  Delete "$INSTDIR\bin\drivedb.h.error"
+  Delete "$INSTDIR\bin\drivedb.h.lastcheck"
+  Delete "$INSTDIR\bin\drivedb.h.old"
+  Delete "$INSTDIR\bin\update-smart-drivedb.exe"
+  Delete "$INSTDIR\bin\runcmda.exe"
+  Delete "$INSTDIR\bin\runcmdu.exe"
+  Delete "$INSTDIR\bin\wtssendmsg.exe"
   Delete "$INSTDIR\doc\AUTHORS.txt"
-  Delete "$INSTDIR\doc\CHANGELOG.txt"
+  Delete "$INSTDIR\doc\ChangeLog.txt"
+  Delete "$INSTDIR\doc\ChangeLog-5.0-6.0.txt"
   Delete "$INSTDIR\doc\COPYING.txt"
   Delete "$INSTDIR\doc\INSTALL.txt"
   Delete "$INSTDIR\doc\NEWS.txt"
   Delete "$INSTDIR\doc\README.txt"
   Delete "$INSTDIR\doc\TODO.txt"
-  Delete "$INSTDIR\doc\WARNINGS.txt"
+  Delete "$INSTDIR\doc\checksums*.txt"
   Delete "$INSTDIR\doc\smartctl.8.html"
-  Delete "$INSTDIR\doc\smartctl.8.txt"
+  Delete "$INSTDIR\doc\smartctl.8.pdf"
+  Delete "$INSTDIR\doc\smartctl.8.txt" ; TODO: Remove after smartmontools 6.6
   Delete "$INSTDIR\doc\smartd.8.html"
-  Delete "$INSTDIR\doc\smartd.8.txt"
+  Delete "$INSTDIR\doc\smartd.8.pdf"
+  Delete "$INSTDIR\doc\smartd.8.txt"  ; TODO: Remove after smartmontools 6.6
   Delete "$INSTDIR\doc\smartd.conf"
   Delete "$INSTDIR\doc\smartd.conf.5.html"
-  Delete "$INSTDIR\doc\smartd.conf.5.txt"
+  Delete "$INSTDIR\doc\smartd.conf.5.pdf"
+  Delete "$INSTDIR\doc\smartd.conf.5.txt" ; TODO: Remove after smartmontools 6.6
   Delete "$INSTDIR\uninst-smartmontools.exe"
 
   ; Remove shortcuts
+  SetShellVarContext all
   Delete "$SMPROGRAMS\smartmontools\*.*"
   Delete "$SMPROGRAMS\smartmontools\Documentation\*.*"
   Delete "$SMPROGRAMS\smartmontools\smartctl Examples\*.*"
@@ -416,97 +507,186 @@ Section "Uninstall"
   RMDir  "$INSTDIR"
 
   ; Remove install dir from PATH
-  IfFileExists "$WINDIR\system32\cmd.exe" 0 +3
-    Push "$INSTDIR\bin"
-    Call un.RemoveFromPath
+  Push "$INSTDIR\bin"
+  Call un.RemoveFromPath
 
   ; Remove drive menu registry entries
   !insertmacro DriveMenuRemove
 
   ; Check for still existing entries
-  IfFileExists "$INSTDIR\bin\smartd.exe" 0 +3
-    MessageBox MB_OK|MB_ICONEXCLAMATION "$INSTDIR\bin\smartd.exe could not be removed.$\nsmartd is possibly still running."
-    Goto +3
-  IfFileExists "$INSTDIR" 0 +2
-    MessageBox MB_OK "Note: $INSTDIR could not be removed."
+  ${If} ${FileExists} "$INSTDIR\bin\smartd.exe"
+    MessageBox MB_OK|MB_ICONEXCLAMATION "$INSTDIR\bin\smartd.exe could not be removed.$\nsmartd is possibly still running." /SD IDOK
+  ${ElseIf} ${FileExists} "$INSTDIR"
+    MessageBox MB_OK "Note: $INSTDIR could not be removed." /SD IDOK
+  ${EndIf}
 
-  IfFileExists "$SMPROGRAMS\smartmontools" 0 +2
-    MessageBox MB_OK "Note: $SMPROGRAMS\smartmontools could not be removed."
+  ${If} ${FileExists} "$SMPROGRAMS\smartmontools"
+    MessageBox MB_OK "Note: $SMPROGRAMS\smartmontools could not be removed." /SD IDOK
+  ${EndIf}
 
 SectionEnd
 
 ;--------------------------------------------------------------------
 ; Functions
 
+!macro AdjustSectionSize section
+  SectionGetSize ${section} $0
+  IntOp $0 $0 / 2
+  SectionSetSize ${section} $0
+!macroend
+
 Function .onInit
 
-  ; Get UBCD4Win install location
-  ReadRegStr $0 HKLM "Software\UBCD4Win" "InstallPath"
-  StrCmp $0 "" 0 +2
-    StrCpy $0 "C:\UBCD4Win"
-  StrCpy $UBCDDIR "$0\plugin\Disk\Diagnostic\smartmontools"
+  ; Set default install directories
+  ${If} $INSTDIR == "" ; /D=PATH option not specified ?
+    ReadRegStr $INSTDIR HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "InstallLocation"
+    ${If} $INSTDIR == "" ; Not already installed ?
+      StrCpy $INSTDIR "$PROGRAMFILES\smartmontools"
+!ifdef INPDIR64
+      StrCpy $INSTDIR32 $INSTDIR
+      StrCpy $INSTDIR64 "$PROGRAMFILES64\smartmontools"
+!endif
+    ${EndIf}
+  ${EndIf}
+
+!ifdef INPDIR64
+  ; Check for 64-bit unless already installed in 32-bit location
+  ${If} $INSTDIR64 != ""
+  ${OrIf} $INSTDIR != "$PROGRAMFILES\smartmontools"
+    ; $1 = IsWow64Process(GetCurrentProcess(), ($0=FALSE, &$0))
+    System::Call "kernel32::GetCurrentProcess() i.s"
+    System::Call "kernel32::IsWow64Process(i s, *i 0 r0) i.r1"
+    ${If} "$0 $1" == "1 1" ; 64-bit Windows ?
+      !insertmacro SelectSection ${X64_SECTION}
+    ${EndIf}
+  ${EndIf}
+
+  ; Sizes of binary sections include 32-bit and 64-bit executables
+  !insertmacro AdjustSectionSize ${SMARTCTL_SECTION}
+  !insertmacro AdjustSectionSize ${SMARTD_SECTION}
+  !insertmacro AdjustSectionSize ${SMARTCTL_NC_SECTION}
+!endif
+
+  ; Use 32-bit or 64-bit Notepad++ if installed
+  StrCpy $EDITOR "$PROGRAMFILES\Notepad++\notepad++.exe"
+  ${IfNot} ${FileExists} "$EDITOR"
+    StrCpy $EDITOR "$PROGRAMFILES64\Notepad++\notepad++.exe"
+    ${IfNot} ${FileExists} "$EDITOR"
+      StrCpy $EDITOR "notepad.exe"
+    ${EndIf}
+  ${EndIf}
 
-  ; Hide "Add install dir to PATH" on 9x/ME
-  IfFileExists "$WINDIR\system32\cmd.exe" +2 0
-    SectionSetText ${PATH_SECTION} ""
+  Call ParseCmdLine
 
+!ifdef INPDIR64
+  Call CheckX64
+!endif
 FunctionEnd
 
-; Directory page callbacks
+; Check x64 section and update INSTDIR accordingly
+
+!ifdef INPDIR64
+Function CheckX64
+  ${IfNot} ${SectionIsSelected} ${X64_SECTION}
+    StrCpy $X64 ""
+    ${If} $INSTDIR32 != ""
+    ${AndIf} $INSTDIR == $INSTDIR64
+      StrCpy $INSTDIR $INSTDIR32
+    ${EndIf}
+  ${Else}
+    StrCpy $X64 "t"
+    ${If} $INSTDIR64 != ""
+    ${AndIf} $INSTDIR == $INSTDIR32
+      StrCpy $INSTDIR $INSTDIR64
+    ${EndIf}
+  ${EndIf}
+FunctionEnd
+!endif
 
-!macro CheckSection section
-  SectionGetFlags ${section} $0
-  IntOp $0 $0 & 1
-  IntCmp $0 1 done
+; Command line parsing
+
+!macro GetCmdLineOption var name
+  Push ",$opts,"
+  Push ",${name},"
+  Call StrStr
+  Pop ${var}
+  ${If} ${var} != ""
+    StrCpy $nomatch ""
+  ${EndIf}
 !macroend
 
-Function SkipProgPath
-  !insertmacro CheckSection ${SMARTCTL_SECTION}
-  !insertmacro CheckSection ${SMARTD_SECTION}
-  !insertmacro CheckSection ${DOC_SECTION}
-  !insertmacro CheckSection ${MENU_SECTION}
-  !insertmacro CheckSection ${PATH_SECTION}
-  !insertmacro CheckSection ${DRIVE_0_SECTION}
-  !insertmacro CheckSection ${DRIVE_1_SECTION}
-  !insertmacro CheckSection ${DRIVE_2_SECTION}
-  !insertmacro CheckSection ${DRIVE_3_SECTION}
-  !insertmacro CheckSection ${DRIVE_4_SECTION}
-  !insertmacro CheckSection ${DRIVE_5_SECTION}
-  Abort
-done:
-FunctionEnd
+!macro CheckCmdLineOption name section
+  StrCpy $allopts "$allopts,${name}"
+  !insertmacro GetCmdLineOption $0 ${name}
+  ${If} $0 == ""
+    !insertmacro UnselectSection ${section}
+  ${Else}
+    !insertmacro SelectSection ${section}
+  ${EndIf}
+!macroend
 
-Function SkipUBCDPath
-  !insertmacro CheckSection ${UBCD_SECTION}
-  Abort
-done:
+Function ParseCmdLine
+  ; get /SO option
+  Var /global opts
+  ${GetParameters} $R0
+  ${GetOptions} $R0 "/SO" $opts
+  ${If} ${Errors}
+    Return
+  ${EndIf}
+  Var /global allopts
+  Var /global nomatch
+  StrCpy $nomatch "t"
+!ifdef INPDIR64
+  ; Change previous 64-bit setting
+  StrCpy $allopts ",x32|x64"
+  !insertmacro GetCmdLineOption $0 "x32"
+  ${If} $0 != ""
+    !insertmacro UnselectSection ${X64_SECTION}
+  ${EndIf}
+  !insertmacro GetCmdLineOption $0 "x64"
+  ${If} $0 != ""
+    !insertmacro SelectSection ${X64_SECTION}
+  ${EndIf}
+  ; Leave other sections unchanged if only "x32" or "x64" is specified
+  ${If}   $opts == "x32"
+  ${OrIf} $opts == "x64"
+    Return
+  ${EndIf}
+!endif
+  ; Turn sections on or off
+  !insertmacro CheckCmdLineOption "smartctl" ${SMARTCTL_SECTION}
+  !insertmacro CheckCmdLineOption "smartd" ${SMARTD_SECTION}
+  !insertmacro CheckCmdLineOption "smartctlnc" ${SMARTCTL_NC_SECTION}
+  !insertmacro CheckCmdLineOption "drivedb" ${DRIVEDB_SECTION}
+  !insertmacro CheckCmdLineOption "doc" ${DOC_SECTION}
+  !insertmacro CheckCmdLineOption "uninst" ${UNINST_SECTION}
+  !insertmacro CheckCmdLineOption "menu" ${MENU_SECTION}
+  !insertmacro CheckCmdLineOption "path" ${PATH_SECTION}
+  !insertmacro CheckCmdLineOption "driveremove" ${DRIVE_REMOVE_SECTION}
+  !insertmacro CheckCmdLineOption "drive0" ${DRIVE_0_SECTION}
+  !insertmacro CheckCmdLineOption "drive1" ${DRIVE_1_SECTION}
+  !insertmacro CheckCmdLineOption "drive2" ${DRIVE_2_SECTION}
+  !insertmacro CheckCmdLineOption "drive3" ${DRIVE_3_SECTION}
+  !insertmacro CheckCmdLineOption "drive4" ${DRIVE_4_SECTION}
+  !insertmacro CheckCmdLineOption "drive5" ${DRIVE_5_SECTION}
+  ${If} $opts != "-"
+    ${If} $nomatch != ""
+      StrCpy $0 "$allopts,-" "" 1
+      MessageBox MB_OK "Usage: smartmontools-VERSION.win32-setup [/S] [/SO component,...] [/D=INSTDIR]$\n$\ncomponents:$\n  $0"
+      Abort
+    ${EndIf}
+  ${EndIf}
 FunctionEnd
 
+; Install runcmda.exe only once
 
-; Create smartctl-run.bat
-
-Function CreateSmartctlBat
-  Exch $0
-  FileOpen $0 $0 "w"
-  FileWrite $0 '@echo off$\r$\nif not "%1" == "" goto run$\r$\n'
-  FileWrite $0 'echo Examples (for first drive):$\r$\n'
-  FileWrite $0 'echo smartctl -i sda            Show identify information$\r$\n'
-  FileWrite $0 'echo smartctl -H sda            Show SMART health status$\r$\n'
-  FileWrite $0 'echo smartctl -c sda            Show SMART capabilities$\r$\n'
-  FileWrite $0 'echo smartctl -A sda            Show SMART attributes$\r$\n'
-  FileWrite $0 'echo smartctl -l error sda      Show error log$\r$\n'
-  FileWrite $0 'echo smartctl -l selftest sda   Show self-test log$\r$\n'
-  FileWrite $0 'echo smartctl -a sda            Show all of the above$\r$\n'
-  FileWrite $0 'echo smartctl -t short sda      Start short self test$\r$\n'
-  FileWrite $0 'echo smartctl -t long sda       Start long self test$\r$\n'
-  FileWrite $0 'echo Use "sdb", "sdc", ... for second, third, ... drive.$\r$\n'
-  FileWrite $0 'echo See man page (smartctl.8.*) for further info.$\r$\n'
-  FileWrite $0 'goto end$\r$\n:run$\r$\n'
-  FileWrite $0 'echo smartctl %1 %2 %3 %4 %5$\r$\n'
-  FileWrite $0 'smartctl %1 %2 %3 %4 %5$\r$\n'
-  FileWrite $0 'pause$\r$\n:end$\r$\n'
-  FileClose $0
-  Pop $0
+Function CheckRunCmdA
+  Var /global runcmda
+  ${If} $runcmda == ""
+    StrCpy $runcmda "t"
+    SetOutPath "$INSTDIR\bin"
+    !insertmacro FileExe "bin\runcmda.exe" ""
+  ${EndIf}
 FunctionEnd
 
 
@@ -539,8 +719,34 @@ Function AddToPath
   Push $1
   Push $2
   Push $3
+  Push $4
 
-  ReadRegStr $1 ${Environ} "PATH"
+  ; NSIS ReadRegStr returns empty string on string overflow
+  ; Native calls are used here to check actual length of PATH
+
+  ; $4 = RegOpenKey(HKEY_CURRENT_USER, "Environment", &$3)
+  System::Call "advapi32::RegOpenKey(i 0x80000001, t'Environment', *i.r3) i.r4"
+  IntCmp $4 0 0 done done
+  ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2))
+  ; RegCloseKey($3)
+  System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
+  System::Call "advapi32::RegCloseKey(i $3)"
+
+  ${If} $4 = 234 ; ERROR_MORE_DATA
+    DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
+    MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}" /SD IDOK
+    Goto done
+  ${EndIf}
+
+  ${If} $4 <> 0 ; NO_ERROR
+    ${If} $4 <> 2 ; ERROR_FILE_NOT_FOUND
+      DetailPrint "AddToPath: unexpected error code $4"
+      Goto done
+    ${EndIf}
+    StrCpy $1 ""
+  ${EndIf}
+
+  ; Check if already in PATH
   Push "$1;"
   Push "$0;"
   Call StrStr
@@ -552,16 +758,31 @@ Function AddToPath
   Pop $2
   StrCmp $2 "" 0 done
 
+  ; Prevent NSIS string overflow
+  StrLen $2 $0
+  StrLen $3 $1
+  IntOp $2 $2 + $3
+  IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";")
+  ${If} $2 > ${NSIS_MAX_STRLEN}
+    DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}"
+    MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}." /SD IDOK
+    Goto done
+  ${EndIf}
+
+  ; Append dir to PATH
   DetailPrint "Add to PATH: $0"
   StrCpy $2 $1 1 -1
-  StrCmp $2 ";" 0 +2
+  ${If} $2 == ";"
     StrCpy $1 $1 -1 ; remove trailing ';'
-  StrCmp $1 "" +2   ; no leading ';'
+  ${EndIf}
+  ${If} $1 != "" ; no leading ';'
     StrCpy $0 "$1;$0"
+  ${EndIf}
   WriteRegExpandStr ${Environ} "PATH" $0
   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
 
 done:
+  Pop $4
   Pop $3
   Pop $2
   Pop $1
@@ -586,8 +807,9 @@ Function un.RemoveFromPath
 
   ReadRegStr $1 ${Environ} "PATH"
   StrCpy $5 $1 1 -1
-  StrCmp $5 ";" +2
+  ${If} $5 != ";"
     StrCpy $1 "$1;" ; ensure trailing ';'
+  ${EndIf}
   Push $1
   Push "$0;"
   Call un.StrStr
@@ -601,8 +823,9 @@ Function un.RemoveFromPath
   StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove
   StrCpy $3 "$5$6"
   StrCpy $5 $3 1 -1
-  StrCmp $5 ";" 0 +2
+  ${If} $5 == ";"
     StrCpy $3 $3 -1 ; remove trailing ';'
+  ${EndIf}
   WriteRegExpandStr ${Environ} "PATH" $3
   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
 
@@ -637,13 +860,12 @@ Function ${un}StrStr
   StrCpy $R4 0
   ; $R1=substring, $R2=string, $R3=strlen(substring)
   ; $R4=count, $R5=tmp
-  loop:
+  ${Do}
     StrCpy $R5 $R2 $R3 $R4
-    StrCmp $R5 $R1 done
-    StrCmp $R5 "" done
+    ${IfThen} $R5 == $R1 ${|} ${ExitDo} ${|}
+    ${IfThen} $R5 == ""  ${|} ${ExitDo} ${|}
     IntOp $R4 $R4 + 1
-    Goto loop
-done:
+  ${Loop}
   StrCpy $R1 $R2 "" $R4
   Pop $R5
   Pop $R4
@@ -654,3 +876,60 @@ FunctionEnd
 !macroend
 !insertmacro StrStr ""
 !insertmacro StrStr "un."
+
+
+;--------------------------------------------------------------------
+; Set Run As Administrator flag in shortcut
+;
+; Slightly modified version from:
+; http://nsis.sourceforge.net/IShellLink_Set_RunAs_flag
+;
+
+!define IPersistFile {0000010b-0000-0000-c000-000000000046}
+!define CLSID_ShellLink {00021401-0000-0000-C000-000000000046}
+!define IID_IShellLinkA {000214EE-0000-0000-C000-000000000046}
+!define IID_IShellLinkW {000214F9-0000-0000-C000-000000000046}
+!define IShellLinkDataList {45e2b4ae-b1c3-11d0-b92f-00a0c90312e1}
+!ifdef NSIS_UNICODE
+  !define IID_IShellLink ${IID_IShellLinkW}
+!else
+  !define IID_IShellLink ${IID_IShellLinkA}
+!endif
+
+Function ShellLinkSetRunAs
+  ; Set archive location of $PLUGINSDIR
+  Goto +2
+    SetOutPath "$INSTDIR"
+
+  System::Store S ; push $0-$9, $R0-$R9
+  pop $9
+  ; $0 = CoCreateInstance(CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, IID_IShellLink, &$1)
+  System::Call "ole32::CoCreateInstance(g'${CLSID_ShellLink}',i0,i1,g'${IID_IShellLink}',*i.r1)i.r0"
+  ${If} $0 = 0
+    System::Call "$1->0(g'${IPersistFile}',*i.r2)i.r0" ; $0 = $1->QueryInterface(IPersistFile, &$2)
+    ${If} $0 = 0
+      System::Call "$2->5(w '$9',i 0)i.r0" ; $0 = $2->Load($9, STGM_READ)
+      ${If} $0 = 0
+        System::Call "$1->0(g'${IShellLinkDataList}',*i.r3)i.r0" ; $0 = $1->QueryInterface(IShellLinkDataList, &$3)
+        ${If} $0 = 0
+          System::Call "$3->6(*i.r4)i.r0"; $0 = $3->GetFlags(&$4)
+          ${If} $0 = 0
+            System::Call "$3->7(i $4|0x2000)i.r0" ; $0 = $3->SetFlags($4|SLDF_RUNAS_USER)
+            ${If} $0 = 0
+              System::Call "$2->6(w '$9',i1)i.r0" ; $2->Save($9, TRUE)
+            ${EndIf}
+          ${EndIf}
+          System::Call "$3->2()" ; $3->Release()
+        ${EndIf}
+        System::Call "$2->2()" ; $2->Release()
+      ${EndIf}
+    ${EndIf}
+    System::Call "$1->2()" ; $1->Release()
+  ${EndIf}
+  ${If} $0 <> 0
+    DetailPrint "Set RunAsAdmin: $9 failed ($0)"
+  ${Else}
+    DetailPrint "Set RunAsAdmin: $9"
+  ${EndIf}
+  System::Store L ; pop $R9-$R0, $9-$0
+FunctionEnd