Bläddra i källkod

feat(Builder): integrate nsis target building (#11)

Evshiron Magicka 8 år sedan
förälder
incheckning
28a247d72a
67 ändrade filer med 15093 tillägg och 56 borttagningar
  1. BIN
      assets/nsis/Bin/LibraryLocal.exe
  2. BIN
      assets/nsis/Bin/RegTool.bin
  3. BIN
      assets/nsis/Bin/makensis.exe
  4. BIN
      assets/nsis/Bin/zlib1.dll
  5. 144 0
      assets/nsis/COPYING
  6. 404 0
      assets/nsis/Docs/MultiUser/Readme.html
  7. 707 0
      assets/nsis/Docs/StrFunc/StrFunc.txt
  8. 17 0
      assets/nsis/Docs/makensisw/License.txt
  9. 223 0
      assets/nsis/Docs/makensisw/Readme.txt
  10. 75 0
      assets/nsis/Include/Colors.nsh
  11. 2015 0
      assets/nsis/Include/FileFunc.nsh
  12. 244 0
      assets/nsis/Include/InstallOptions.nsh
  13. 191 0
      assets/nsis/Include/LangFile.nsh
  14. 870 0
      assets/nsis/Include/Library.nsh
  15. 853 0
      assets/nsis/Include/LogicLib.nsh
  16. 526 0
      assets/nsis/Include/Memento.nsh
  17. 469 0
      assets/nsis/Include/MultiUser.nsh
  18. 310 0
      assets/nsis/Include/Sections.nsh
  19. 1760 0
      assets/nsis/Include/StrFunc.nsh
  20. 1211 0
      assets/nsis/Include/TextFunc.nsh
  21. 203 0
      assets/nsis/Include/UpgradeDLL.nsh
  22. 173 0
      assets/nsis/Include/Util.nsh
  23. 90 0
      assets/nsis/Include/VB6RunTime.nsh
  24. 234 0
      assets/nsis/Include/Win/COM.nsh
  25. 51 0
      assets/nsis/Include/Win/Propkey.nsh
  26. 68 0
      assets/nsis/Include/Win/WinDef.nsh
  27. 64 0
      assets/nsis/Include/Win/WinError.nsh
  28. 209 0
      assets/nsis/Include/Win/WinNT.nsh
  29. 199 0
      assets/nsis/Include/Win/WinUser.nsh
  30. 231 0
      assets/nsis/Include/WinCore.nsh
  31. 706 0
      assets/nsis/Include/WinMessages.nsh
  32. 509 0
      assets/nsis/Include/WinVer.nsh
  33. 1800 0
      assets/nsis/Include/WordFunc.nsh
  34. 61 0
      assets/nsis/Include/x64.nsh
  35. BIN
      assets/nsis/Menu/images/header.gif
  36. BIN
      assets/nsis/Menu/images/line.gif
  37. BIN
      assets/nsis/Menu/images/site.gif
  38. 64 0
      assets/nsis/Menu/index.html
  39. 22 0
      assets/nsis/Menu/notinstalled.html
  40. BIN
      assets/nsis/NSIS.chm
  41. BIN
      assets/nsis/NSIS.exe
  42. BIN
      assets/nsis/Plugins/x86-ansi/TypeLib.dll
  43. BIN
      assets/nsis/Plugins/x86-unicode/TypeLib.dll
  44. BIN
      assets/nsis/Stubs/bzip2-x86-ansi
  45. BIN
      assets/nsis/Stubs/bzip2-x86-unicode
  46. BIN
      assets/nsis/Stubs/bzip2_solid-x86-ansi
  47. BIN
      assets/nsis/Stubs/bzip2_solid-x86-unicode
  48. BIN
      assets/nsis/Stubs/lzma-x86-ansi
  49. BIN
      assets/nsis/Stubs/lzma-x86-unicode
  50. BIN
      assets/nsis/Stubs/lzma_solid-x86-ansi
  51. BIN
      assets/nsis/Stubs/lzma_solid-x86-unicode
  52. BIN
      assets/nsis/Stubs/uninst
  53. BIN
      assets/nsis/Stubs/zlib-x86-ansi
  54. BIN
      assets/nsis/Stubs/zlib-x86-unicode
  55. BIN
      assets/nsis/Stubs/zlib_solid-x86-ansi
  56. BIN
      assets/nsis/Stubs/zlib_solid-x86-unicode
  57. BIN
      assets/nsis/makensis.exe
  58. BIN
      assets/nsis/makensisw.exe
  59. 62 0
      assets/nsis/nsisconf.nsh
  60. 3 1
      assets/project/package.json
  61. 47 0
      src/lib/Builder.ts
  62. 1 0
      src/lib/WinConfig.ts
  63. 182 0
      src/lib/nsis-gen/NsisComposer.ts
  64. 45 0
      src/lib/nsis-gen/index.ts
  65. 3 42
      test/Builder.js
  66. 1 13
      test/Runner.js
  67. 46 0
      test/nsis-gen.js

BIN
assets/nsis/Bin/LibraryLocal.exe


BIN
assets/nsis/Bin/RegTool.bin


BIN
assets/nsis/Bin/makensis.exe


BIN
assets/nsis/Bin/zlib1.dll


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 144 - 0
assets/nsis/COPYING


+ 404 - 0
assets/nsis/Docs/MultiUser/Readme.html

@@ -0,0 +1,404 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+    <title>Multi-User Header File (MultiUser.nsh)</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+    <style type="text/css">
+        td
+        {
+            padding: 5px;
+            vertical-align: top;
+            border-bottom: 1px solid black;
+        }
+    </style>
+</head>
+<body>
+    <h1>
+        Multi-User Header File (MultiUser.nsh)</h1>
+    <p>
+        <i>Installer configuration for multi-user Windows environments</i></p>
+    <h2>
+        Table of Contents</h2>
+    <ul>
+        <li><a href="#introduction">Introduction</a></li>
+        <li><a href="#executionlevel">Initalization and Execution Level</a>
+            <li><a href="#installationmode">Installation Mode</a></ul>
+    <h2>
+        <a name="introduction"></a>Introduction</h2>
+    <p>
+        Modern Windows versions support multiple users accounts on a single computer, each
+        with different privileges. For security reasons, the privileges of applications
+        can also be limited. For an installer, the <i>execution level</i> and <i>installation
+            mode</i> are important. The execution level determines the privileges of the
+        installer application. For example, to install hardware drivers, administrator privileges
+        are required. Applications can also be installed for a single user or for all users
+        on a computer, which is determined by the installation mode. Installation for all
+        users requires a higher execution level as compared with a single user setup. The
+        MultiUser.nsh header files provides the features to automatically handle all these
+        aspects related to user accounts and installer privileges.</p>
+    <p>
+        Note that all settings need to be set before including the MultiUser.nsh header
+        file.</p>
+    <h2>
+        Initialization and <a name="executionlevel"></a>Execution Level&nbsp;</h2>
+    <p>
+        Before the MultiUser.nsh file is included, the MULTIUSER_EXECUTIONLEVEL define should
+        be set to one of the following values depending on the execution level that is required:</p>
+    <table>
+        <tr>
+            <td>
+                <b>Value </b>
+            </td>
+            <td>
+                <b>Description</b>
+            </td>
+            <td>
+                <b>Typical application</b>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                Admin
+            </td>
+            <td>
+                Administrator privileges are required
+            </td>
+            <td>
+                Access data of all users accounts
+            </td>
+        </tr>
+        <tr>
+            <td>
+                Power
+            </td>
+            <td>
+                Power User privileges are required<br />
+                (Power Users no longer exist in Windows Vista. For Vista this is equivalent to Admin)
+            </td>
+            <td>
+                Installation for all users (writing to &quot;Program Files&quot; or HKLM registry
+                keys), driver installation
+            </td>
+        </tr>
+        <tr>
+            <td>
+                Highest
+            </td>
+            <td>
+                Request the highest possible execution level for the current user
+            </td>
+            <td>
+                Mixed-mode installer that can both be installed per-machine or per-user
+            </td>
+        </tr>
+        <tr>
+            <td>
+                Standard
+            </td>
+            <td>
+                No special rights required
+            </td>
+            <td>
+                Installation for current user only
+            </td>
+        </tr>
+    </table>
+    <p>
+        Insert the MULTIUSER_INIT and MULTIUSER_UNINT macros in the .onInit and un.onInit
+        function to verify these privileges. If no uninstaller is created in the script,
+        set MULTIUSER_NOUNINSTALL.</p>
+    <blockquote>
+        <pre>!define MULTIUSER_EXECUTIONLEVEL Highest
+;!define MULTIUSER_NOUNINSTALL ;Uncomment if no uninstaller is created
+!include MultiUser.nsh
+
+...
+
+Function .onInit
+  !insertmacro MULTIUSER_INIT
+FunctionEnd
+
+Function un.onInit
+  !insertmacro MULTIUSER_UNINIT
+FunctionEnd</pre>
+    </blockquote>
+    <p>
+        Whether the required privileges can be obtained depends on the user that starts
+        the installer:</p>
+    <ul>
+        <li>Windows NT 4/2000/XP/2003 give the installer the same privileges as the user itself.
+            If the privileges of the user are not sufficient (e.g. Admin level is required is
+            set but the user has no administrator rights), the macros will display an error
+            message and quit the installer. If is however possible to manually run the installer
+            with an administrator account.</li>
+        <li>Windows Vista restricts the privileges of all applications by default. Depending
+            on requested execution level, MultiUser.nsh will set the RequestExecutionLevel flag
+            to request privileges. The user will be asked for confirmation and (if necessary)
+            for an administrator password.</li>
+        <li>Windows 95/98/98 do not set any restrictions on users or applications. Administrator
+            rights are always available.</li>
+    </ul>
+    <p>
+        It is recommended to insert these initialization macros before macros that require
+        user intervention. For example, it does not make sense to ask a user for an installer
+        language if the installer will quit afterwards because the user account does not
+        have the required privileges. After the macros are inserted, the variable $MultiUser.Privileges
+        will contain the current execution level (Admin, Power, User or Guest).</p>
+    <p>
+        The following additional settings are available to customize the initialization:</p>
+    <table>
+        <tr>
+            <td>
+                <b>Setting<td>
+                    <b>Description</b>
+                </td>
+        </tr>
+        <tr>
+            <td>
+                MULTIUSER_INIT_TEXT_ADMINREQUIRED
+            </td>
+            <td>
+                Error message to be displayed when administrator rights are required but not available.
+            </td>
+        </tr>
+        <tr>
+            <td>
+                MULTIUSER_INIT_TEXT_POWERREQUIRED
+            </td>
+            <td>
+                Error message to be displayed when Power User rights are required but not available.
+            </td>
+        </tr>
+        <tr>
+            <td>
+                MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE
+            </td>
+            <td>
+                Error message to be displayed when administrator or Power User rights are required
+                because of an installation mode setting on the command line (see below) but are
+                not available.
+            </td>
+        </tr>
+        <tr>
+            <td>
+                MULTIUSER_INIT_FUNCTIONQUIT<br />
+                MULTIUSER_INIT_UNFUNCTIONQUIT
+            </td>
+            <td>
+                A custom function to be called when the installer is closed due to insufficient
+                privileges.
+            </td>
+        </tr>
+    </table>
+    <h2>
+        <a name="installationmode"></a>Installation Mode</h2>
+    <p>
+        As mentioned before, applications can both be installed for a single users or for
+        all users on a computer. Applications for all users are typically installed in the
+        Program Files folder and appear in the Start Menu of every user. On the contrary,
+        applications for a single user are usually installed in the local Application Data
+        folder and only a appear in the Start Menu of the user who installed the application.</p>
+    <p>
+        By default, MultiUser.nsh will set the installation mode for a per-machine installation
+        if Administrator or Power User rights are available (this is always the case if
+        the execution level is set to Admin or Power, if Highest is set it depends on the
+        user account). For the Standard execution level the installation will always be
+        for a single user. On Windows 95/98/Me installation for a single user is not possible.</p>
+    <p>
+        The following settings are available to change the default installation mode:
+        <table>
+            <tr>
+                <td>
+                    <b>Setting</b>
+                </td>
+                <td>
+                    <b>Description</b>
+                </td>
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
+                </td>
+                <td>
+                    Set default to a per-user installation, even if the rights for a per-machine installation
+                    are available.
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
+                </td>
+                <td>
+                    Non-empty registry key that is created during the installation in either HKCU or
+                    HKLM. The default installation mode will automatically be set to the previously
+                    selected mode depending on the location of the key.
+                </td>
+            </tr>
+        </table>
+        <p>
+            After initialization, the variable $MultiUser.InstallMode will contain the current
+            installation mode (AllUsers or CurrentUser).
+        </p>
+        <h3>
+            Mixed-Mode Installation</h3>
+        <p>
+            For the Admin and Power levels, both a per-machine as well as a per-user installation
+            is possible. If the Highest level is set and the user is an Administrator or Power
+            User, both options are also available.</p>
+        <p>
+            Usually it's a good thing to give the user to choice between these options. For
+            users of the Modern UI version 2, a page is provided that asks the user for the
+            installation mode. To use this page, define MULTIUSER_MUI before including User.nsh.
+            Then, the MULTIUSER_PAGE_INSTALLMODE macro can be used just like a normal Modern
+            UI page (this page will automatically be skipped when running Windows 95/98/Me):</p>
+        <pre>!define MULTIUSER_EXECUTIONLEVEL Highest
+<b>!define MULTIUSER_MUI</b>
+!define MULTIUSER_INSTALLMODE_COMMANDLINE
+!include MultiUser.nsh
+!include MUI2.nsh
+
+<b>!insertmacro MULTIUSER_PAGE_INSTALLMODE</b>
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES 
+
+!insertmacro MUI_LANGUAGE English
+
+...
+
+Function .onInit
+  !insertmacro MULTIUSER_INIT
+FunctionEnd
+
+Function un.onInit
+  !insertmacro MULTIUSER_UNINIT
+FunctionEnd
+</pre>
+        <p>
+            The MULTIUSER_INSTALLMODE_COMMANDLINE setting that also appears in this example
+            enables the installation mode to be set using the /AllUsers or /CurrentUser command
+            line parameters. This is especially useful for silent setup.</p>
+        <p>
+            The following settings can be used to customize the texts on the page (in addition
+            to the general Modern UI page settings):</p>
+        <table>
+            <tr>
+                <td>
+                    <b>Setting</b>
+                </td>
+                <td>
+                    <b>Description</b>
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MULTIUSER_INSTALLMODEPAGE_TEXT_TOP
+                </td>
+                <td>
+                    Text to display on the top of the page.
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS
+                </td>
+                <td>
+                    Text to display on the combo button for a per-machine installation.
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER
+                </td>
+                <td>
+                    Text to display on the combo button for a per-user installation.
+                </td>
+            </tr>
+        </table>
+        <h3>
+            Installation Mode Initalization</h3>
+        <p>
+            The SetShellVarContext flag (which determines the folders for e.g. shortcuts, like
+            $DESKTOP) is automatically set depending on the installation mode. In addition,
+            the following settings can be used to perform additional actions when the installation
+            mode is initialized:</p>
+        <table>
+            <tr>
+                <td>
+                    <b>Setting</b>
+                </td>
+                <td>
+                    <b>Description</b>
+                </td>
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MULTIUSER_INSTALLMODE_INSTDIR
+                </td>
+                <td>
+                    Name of the folder in which to install the application, without a path. This folder
+                    will be located in Program Files for a per-machine installation and in the local
+                    Application Data folder for a per-user installation (if supported).
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
+                </td>
+                <td>
+                    Registry key from which to obtain a previously stored installation folder. It will
+                    be retrieved from HKCU for per-user and HKLM for per-machine.
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MULTIUSER_INSTALLMODE_FUNCTION<br />
+                    MULTIUSER_INSTALLMODE_UNFUNCTION
+                </td>
+                <td>
+                    A custom fuction to be called during the initialization of the installation mode
+                    to set additional installer settings that depend on the mode
+                </td>
+        </table>
+        <p>
+            To set the installation mode manually, call one of these four functions:</p>
+        <table>
+            <tr>
+                <td>
+                    <b>Function name</b>
+                </td>
+                <td>
+                    <b>Installation mode</b>
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MultiUser.InstallMode.AllUsers
+                </td>
+                <td>
+                    Installer: Per-machine installation
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    MultiUser.InstallMode.CurrentUser
+                    <td>
+                        Installer: Per-user installation
+                    </td>
+            </tr>
+            <tr>
+                <td>
+                    un.MultiUser.InstallMode.AllUsers<td>
+                        Uninstaller: Per-machine installation
+                    </td>
+            </tr>
+            <tr>
+                <td>
+                    un.MultiUser.InstallMode.CurrentUser<td>
+                        Uninstaller: Per-user installation
+                    </td>
+            </tr>
+        </table>
+</body>
+</html>

+ 707 - 0
assets/nsis/Docs/StrFunc/StrFunc.txt

@@ -0,0 +1,707 @@
+String Functions Header File Readme
+-----------------------------------
+
+String Functions Header File contains a set of good string manipulation
+functions in a much simpler way to include and call in NSIS scripts.
+
+How to use
+----------
+
+  Basic Syntax
+  ------------
+
+  Parameters are specified in this format:
+  required (required) (option1 | option2) [optional or add. options]
+  [option1 | option2]
+
+  The stars in command titles (*****) are the function usefulness in my
+  opinion. The more starts, the more useful it is. 5 stars (*****) is the
+  most useful.
+
+  Any time when is mentioned "Default is" means that you can use the value
+  mentioned or keep it blank, the result is the same.
+
+  If you want a certain value (e.g. a text) to be language-specific, set a
+  language string (using LangString) and define $(STRINGNAME) as value.
+
+  If you want to add ` to a string, you should always escape it using $\`
+  because the header file macro functions use ` to separate parameters.
+
+  1. Include Header file
+  ----------------------
+
+    !include "StrFunc.nsh"
+
+    StrFunc.nsh has to be inside Include directory, so you don't have to
+    specify a path.
+
+    You have to put this command before any command used in this header file.
+
+  2. Defines
+  ----------
+
+    This header file contains defines that automate the life of some who
+    fear a lot of changes sometimes imposed in this header file, or who have
+    applications that put it to work at maximum capacity. Before you try
+    these, take a look at the information below:
+
+      - Every item on a define value is separated by a "|", and every subitem
+        (items in an item) is separated by " ".
+
+      - Use ${StrTok} $var "${DefineName}" "|" "$counter" "0" to get every
+        item inside the define. For subitems, use ${StrTok} $var2 "$var" " "
+        "$counter2" "0" after getting the value for a desired item.
+
+      - ${StrFunc_List} is automatically made by the header file. The rest
+        is manually added to the header.
+
+    2.1 Defines List:
+    -----------------
+
+    StrFunc_List - Lists all function names currently available on StrFunc
+                   header file.
+
+    *_List       - Lists all parameter names currently available for "*"
+                   function. (* = function name - i.e. StrTok_List).
+
+    *_TypeList   - Lists the types of all parameters on "*" function.
+                   (* = function name - i.e. StrTok_List). Possible types
+                   for each parameter:
+
+                   - Output - Needs a variable to output a function result.
+
+                   - Text   - Needs text or number to be input.
+
+                   - Mixed  - Needs text, number or option to be inputed.
+                              Each subitem following the "Mixed" word is an
+                              option. The first option is ever the default
+                              one. Two following spaces "  " means that
+                              that subitem is empty.
+
+                   - Option - Needs an option to be inputed. Each subitem
+                              following the "Option" word is an option.
+                              The first option is ever the default one. Two
+                              following spaces "  " means that that subitem
+                              is empty.
+
+  3. Commands
+  -----------
+
+  Some commands have special specifications to work. Consult command's
+  documentation on "3.3 Commands" section.
+
+    3.1 How To Use Commands In Install Sections and Functions
+    ---------------------------------------------------------
+
+    Every command used in install sections and functions have to be called
+    first before and out of any sections and functions, and without
+    parameters.
+
+    Example:
+    --------
+
+    ${StrStr}
+    
+    3.2 How To Use Commands In Uninstall Sections and Functions
+    -----------------------------------------------------------
+
+    Commands with Uninstall Sections and Functions support have "Un" before
+    the words inside curly brackets "{}".
+
+    Example:
+    --------
+    
+    ${UnStrStr}
+
+    A complete example with both Install and Uninstall Commands:
+    ------------------------------------------------------------
+
+
+    !include "StrFunc.nsh"
+
+    ${StrStr} # Supportable for Install Sections and Functions
+
+    ${UnStrStr} # Supportable for Uninstall Sections and Functions
+
+    Section
+
+      ${StrStr} $0 "OK! Now what?" "wh"
+
+    SectionEnd
+
+    Section Uninstall
+
+      ${UnStrStr} $0 "OK! Now what?" "wh"
+
+    SectionEnd
+
+    3.3 Commands
+    ------------
+
+    =========================================================================
+    **                                                             ${StrCase}
+    -------------------------------------------------------------------------
+    ResultVar String Type(|L|U|T|S|<>)
+    =========================================================================
+    Converts "String" to "Type" Case. Uses LogicLib.
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String to convert to "Type" case.
+      
+      Type
+      Type of string case to convert to:
+
+        - "" = Original Case (same as "String")
+        - L = Lower Case (this is just an example. a very simple one.)
+        - U = Upper Case (THIS IS JUST AN EXAMPLE. A VERY SIMPLE ONE.)
+        - T = Title Case (This Is Just An Example. A Very Simple One.)
+        - S = Sentence Case (This is just an example. A very simple one.)
+        - <> = Switch Case (This is just an example. A very simple one.)
+        
+      Default value is "" (Original Case).
+
+    Result Value -> ResultVar:
+
+      "String" in "Type" case.
+
+    Example:
+
+      ${StrCase} $0 '"Você" is "You" in English.' "U"
+                    [__(_)__()___()__()__(____)_]
+
+      $0 = '"VOCÊ" IS "YOU" IN ENGLISH.'
+
+    =========================================================================
+    *                                                               ${StrClb}
+    -------------------------------------------------------------------------
+    ResultVar String Action(|>|<|<>)
+    =========================================================================
+    Makes an action with the clipboard depending on value of parameter
+    "Action". Uses LogicLib.
+
+    Parameters:
+
+      String
+      If "Action" = ">" or "<>" - String to put on the clipboard.
+
+      Action
+      Can be one of the following values:
+
+        - "" = Cleans the clipboard.
+        - ">" = Set string to clipboard.
+        - "<" = Get string from clipboard.
+        - "<>" = Swap string with clipboard's.
+
+    Result Value -> ResultVar:
+
+      If "Action" = "<" or "<>" - String found on the clipboard.
+
+    =========================================================================
+    ***                                                        ${StrIOToNSIS}
+    -------------------------------------------------------------------------
+    ResultVar String
+    =========================================================================
+    Convert "String" from Install Options plugin to be supported by NSIS.
+    Escape, back-slash, carriage return, line feed and tab characters are
+    converted.
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String to convert to be supportable for NSIS.
+
+    Result Value -> ResultVar:
+
+      "String" supportable for NSIS.
+
+    Example:
+
+      ${StrIOToNSIS} $0 "\r\n\t\\This is just an example\\"
+                        [()()()()_______________________()]
+
+      $0 = "$\r$\n$\t\This is just an example\"
+
+    =========================================================================
+    *                                                               ${StrLoc}
+    -------------------------------------------------------------------------
+    ResultVar String StrToSearchFor CounterDirection(>|<)
+    =========================================================================
+    Searches for "StrToSearchFor" in "String" and returns its location,
+    according to "CounterDirection".
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String where to search "StrToSearchFor".
+
+      StrToSearchFor
+      String to search in "String".
+
+      CounterDirection(>|<)
+      Direction where the counter increases to. Default is ">".
+      (> = increases from left to right, < = increases from right to left)
+
+    Result Value -> ResultVar:
+
+      Where "StrToSearchFor" is, according to "OffsetDirection".
+
+    Example: 
+
+      ${StrLoc} $0 "This is just an example" "just" "<"
+                            (__)<<<<<<<<<<<
+
+      $0 = "11"
+
+    =========================================================================
+    ***                                                        ${StrNSISToIO}
+    -------------------------------------------------------------------------
+    ResultVar String
+    =========================================================================
+    Converts "String" from NSIS to be supported by Install Options plugin.
+    Escape, back-slash, carriage return, line feed and tab characters are
+    converted.
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String to convert to be supportable for Install Options plugin.
+
+    Result Value -> ResultVar:
+
+      "String" supportable for Install Options plugin.
+
+    Example:
+
+      ${StrNSISToIO} $0 "$\r$\n$\t\This is just an example\"
+                        [(_)(_)(_)^_______________________^]
+
+      $0 = "\r\n\t\\This is just an example\\"
+
+    =========================================================================
+    *****                                                           ${StrRep}
+    -------------------------------------------------------------------------
+    ResultVar String StrToReplace ReplacementString
+    =========================================================================
+    Searches for all "StrToReplace" in "String" replacing those with
+    "ReplacementString".
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String where to search "StrToReplace".
+
+      StrToReplaceFor
+      String to search in "String".
+
+      StringToBeReplacedWith
+      String to replace "StringToReplace" when it is found in "String".
+
+    Result Value -> ResultVar:
+
+      "String" with all occurrences of "StringToReplace" replaced with
+      "ReplacementString".
+
+    Example: 
+
+      ${StrRep} $0 "This is just an example" "an" "one"
+                    [____________()_______]
+
+      $0 = "This is just one example"
+
+    =========================================================================
+    ***                                                            ${StrSort}
+    -------------------------------------------------------------------------
+    ResultVar String LeftStr CenterStr RightStr IncludeLeftStr(1|0)
+    IncludeCenterStr(1|0) IncludeRightStr(1|0)
+    =========================================================================
+    Searches for "CenterStr" in "String", and returns only the value
+    between "LeftStr" and "RightStr", including or not the "CenterStr" using
+    "IncludeCenterStr" and/or the "LeftStr" using "IncludeLeftStr" and
+    "RightStr" using "IncludeRightStr".
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String where to search "CenterStr".
+
+      LeftStr
+      The first occurrence of "LeftStr" on the left of "CenterStr".
+      If it is an empty value, or was not found, will return
+      everything on the left of "CenterStr".
+
+      CenterStr
+      String to search in "String".
+
+      RightStr
+      The first occurrence of "RightStr" on the right of "CenterStr".
+      If it is an empty value, or was not found, will return
+      everything on the right of "CenterStr".
+
+      IncludeLeftStr(1|0)
+      Include or not the "LeftStr" in the result value. Default is 1
+      (True). (1 = True, 0 = False)
+
+      IncludeCenterStr(1|0)
+      Include or not the "CenterStr" in the result value. Default is 1
+      (True). (1 = True, 0 = False)
+
+      IncludeRightStr(1|0)
+      Include or not the "RightStr" in the result value. Default is 1
+      (True). (1 = True, 0 = False)
+
+    Result Value -> ResultVar:
+
+      String between "LeftStr" and "RightStr" of a found "CenterStr"
+      including or not the "LeftStr" and "RightStr" if
+      "IncludeLeftRightStr" is 1 and/or the "CenterStr" if
+      "IncludeCenterStr" is 1.
+
+    Example: 
+
+      ${StrSort} $0 "This is just an example" " just" "" "ple" "0" "0" "0"
+                    [_______(___)_______]( )
+                              C           R
+
+      $0 = "This is an exam"
+
+    =========================================================================
+    *****                                                           ${StrStr}
+    -------------------------------------------------------------------------
+    ResultVar String StrToSearchFor
+    =========================================================================
+    Searches for "StrToSearchFor" in "String".
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String where to search "StrToSearchFor".
+
+      StrToSearchFor
+      String to search in "String".
+
+    Result Value -> ResultVar:
+
+      "StrToSearchFor" + the string after where "StrToSearchFor" was found in
+      "String".
+
+    Example: 
+
+      ${StrStr} $0 "This is just an example" "just"
+                   >>>>>>>>>{_)____________]
+
+      $0 = "just an example"
+
+    =========================================================================
+    *****                                                        ${StrStrAdv}
+    -------------------------------------------------------------------------
+    ResultVar String StrToSearchFor SearchDirection(>|<)
+    ResultStrDirection(>|<) DisplayStrToSearch(1|0) Loops CaseSensitive(0|1)
+    =========================================================================
+    Searches for "StrToSearchFor" in "String" in the direction specified by
+    "SearchDirection" and looping "Loops" times.
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String where to search "StrToSearchFor".
+
+      StrToSearchFor
+      String to search in "String".
+
+      SearchDirection (>|<)
+      Where do you want to direct the search. Default is ">" (to right).
+      (< = To left, > = To right)
+
+      ResultStrDirection (>|<)
+      Where the result string will be based on in relation of
+      "StrToSearchFor"
+      position. Default is ">" (to right). (< = To left, > = To right)
+
+      DisplayStrToSearch (1|0)
+      Display "StrToSearchFor" in the result. Default is "1" (True).
+      (1 = True, 0 = False)
+
+      Loops
+      Number of times the code will search "StrToSearchFor" in "String" not
+      including the original execution. Default is "0" (1 code execution).
+
+      CaseSensitive(0|1)
+      If "1" the search will be case-sensitive (differentiates between cases).
+      If "0" it is case-insensitive (does not differentiate between cases).
+      Default is "0" (Case-Insensitive).
+
+
+    Result Value -> ResultVar:
+
+      "StrToSearchFor" if "DisplayStrToSearch" is 1 + the result string after
+      or before "StrToSearchFor", depending on "ResultStrDirection".
+
+    Result with Errors:
+
+      When "StrToSearchFor" was not found, will return an empty string.
+
+      When you put nothing in "StrToSearchFor", will return "String" and set
+      error flag.
+
+      When you put nothing in "String", will return an empty string and set
+      error flag.
+
+    Example: 
+
+      ${StrStrAdv} $0 "This IS really just an example" "IS " ">" ">" "0" "0" "1"
+                       >>>>>( )[____________________]                       
+
+
+      $0 = "really just an example"
+
+    =========================================================================
+    ****                                                            ${StrTok}
+    -------------------------------------------------------------------------
+    ResultVar String Separators ResultPart[L] SkipEmptyParts(1|0)
+    =========================================================================
+    Returns the part "ResultPart" between two "Separators" inside
+    "String".
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String where to search for "Separators".
+
+      Separators
+      Characters to find on "String".
+
+      ResultPart[L]
+      The part want to be found on "StrToTokenize" between two "Separators".
+      Can be any number, starting at 0, and "L" that is the last part.
+      Default is L (Last part).
+
+      SkipEmptyParts(1|0)
+      Skips empty string parts between two "Separators". Default is 1 (True).
+      (1 = True, 0 = False)
+
+    Result Value -> ResultVar:
+
+      "String" part number "Part" between two "Separators".
+
+    Examples: 
+
+      1) ${StrTok} $0 "This is, or is not, just an example" " ," "4" "1"
+                       (  ) ()  () () [_]  (  ) () (     )
+                       0    1   2  3  4    5    6  7 
+         $0 = "not"
+
+      2) ${StrTok} $0 "This is, or is not, just an example" " ," "4" "0"
+                       (  ) () ^() [] ( ) ^(  ) () (     )
+                       0    1  23  4  5   67    8  9
+         $0 = "is"
+
+    =========================================================================
+    *                                                      ${StrTrimNewLines}
+    -------------------------------------------------------------------------
+    ResultVar String
+    =========================================================================
+    Deletes unnecessary new lines at end of "String".
+
+    Parameters:
+
+      ResultVar
+      Destination where result is returned.
+
+      String
+      String where to search unnecessary new lines at end of "String".
+
+    Result Value -> ResultVar:
+
+      "String" with unnecessary end new lines removed.
+
+    Example:
+
+      ${StrTrimNewLines} $0 "$\r$\nThis is just an example$\r$\n$\r$\n"
+                            [_____________________________(_)(_)(_)(_)]
+
+      $0 = "$\r$\nThis is just an example"
+
+Functions included and not included
+--------------------------------------------------
+
+11 functions have been included
+  They are not available on Archive
+  They are on LogicLib format
+
+15 functions have not been included
+  12 were not included because of better functions
+    6 were not included because of AdvStrTok (called here as StrTok)
+      First String Part Function
+      Save on Variables Function
+      Sort Strings (1, 2 and 3) Functions
+      StrTok Function
+    2 were not included because of StrCase
+      StrLower Function
+      StrUpper Function
+    2 were not included because of StrClb
+      StrClbSet Function
+      StrClbGet Function
+    1 was not included because of NSISToIO and IOToNSIS
+      Convert / to // in Paths Function
+    1 was not included because of original String Replace Function (called
+      here as StrRep)
+      Another String Replace Function
+  2 were not included because they aren't useful anymore
+    Slash <-> Backslash Converter Function
+    Trim Function
+  1 was not included because of bugs
+    Number to String Converter Function
+
+Version History
+---------------
+
+1.09 - 10/22/2004
+
+- Fixed stack problems involving: StrCase, StrRep, StrSort, StrTok.
+- Fixed StrClb: When "Action" = "<>", handle was wrongly outputed as
+  text.
+- Fixed StrSort, StrStrAdv documentation examples.
+- Fixed StrIOToNSIS, StrLoc, StrNSISToIO, StrRep, StrStr: sometimes
+  didn't find "StrToSearch" at all.
+
+1.08 - 10/12/2004
+
+- Converted all the functions to LogicLib.
+- StrSort: Totally remade and it can break old scripts. See
+  documentation for details.
+- StrTok: "ResultPart" has to start from 0 and it can break old scripts.
+  See documentation for details.
+- Added defines: StrFunc_List, *_List and *_TypeList.
+- Fixed StrStrAdv: Variables $R0-$R3 couldn't be used on scripts before
+  calling.
+- StrRep: Cut down some variables.
+- Arranged correctly the order of StrSort on the documentation.
+
+1.07 - 09/21/2004
+
+- Removed ${UnStrFunc} command. Now you can just include uninstall
+  functions commands like ${UnStrStr} to be supported by uninstall functions
+  and sections.
+- Added case-sensitive comparation option for StrStrAdv.
+- StrCase now uses System.dll which makes case conversions effective with
+all latin letters (i.e. ê).
+- Added switch case and original case for StrCase.
+- StrClbSet and StrClbGet removed, added StrClb.
+- Made compact the most usual operations inside the header file. File size
+reduced.
+
+1.06 - 03/26/2004
+
+- StrNumToStr removed due to complex number handling on some languages.
+- Fixed the bug where the old string was attached to string returned by
+  StrCase when $R5 variable was used.
+
+1.05 - 03/17/2004
+
+- Fixed a bug with StrCase, Title Case wasn't working as should be.
+- Fixed a bug with StrStrAdv, previous fix created another bug, string not
+  returned correctly when using backwards search with "DisplayStrToSearch" as
+  "0".
+
+1.04 - 03/07/2004
+
+- Added new StrCase, removed StrLower and StrUpper.
+- Organized by name commands inside header and readme files.
+
+1.03 - 02/12/2004
+
+- Added commands support for uninstall sections and functions.
+- Fixed variables switch in "StrLoc" and "StrTok" after using these.
+
+1.02 - 02/07/2004
+
+- Fixed StrLoc.
+- Fixed Documentation about StrLoc. "Direction" is really "OffsetDirection".
+- Added my new AdvStrSort, and removed the old one.
+
+1.01 - 02/05/2004
+
+- Fixed Documentation about StrSort and StrTok.
+- Fixed StrTok default value for the string part. Now it's "L".
+- Fixed StrStrAdv fixed wrong search when had a combination of same
+  substrings one after another in a string.
+- Fixed StrLoc: when a string isn't found, don't return any value at all.
+
+1.00 - 02/01/2004
+
+- Added documentation.
+- Renamed header file to "StrFunc.nsh".
+- Added 1 function, StrLoc.
+- Modified StrStrAdv, removed some lines.
+- Fixed StrTok, 2 simple numbers made it loop everytime.
+- Fixed some small issues on the header file.
+
+0.02 - 01/24/2004
+
+- Completed StrFunc.nsh file. Need some tests and the readme.
+
+0.01 - 01/22/2004
+
+- First version to test ideas...
+
+Credits
+-------
+
+  Made by Diego Pedroso (aka deguix).
+
+Functions Credits
+-----------------
+
+- All functions are made by Diego Pedroso on LogicLib format. They
+  are based on functions by Amir Szekely, Dave Laundon, Hendri
+  Adriaens, Nik Medved, Joost Verburg, Stuart Welch, Ximon Eighteen,
+  "bigmac666" and "bluenet". "bluenet"'s version of StrIOToNSIS and
+  StrNSISToIO on LogicLib format were included.
+
+License
+-------
+
+This header file is provided 'as-is', without any express or implied
+warranty. In no event will the author be held liable for any damages
+arising from the use of this header file.
+
+Permission is granted to anyone to use this header file for any purpose,
+including commercial applications, and to alter it and redistribute
+it freely, subject to the following restrictions:
+
+1. The origin of this header file must not be misrepresented;
+   you must not claim that you wrote the original header file.
+   If you use this header file in a product, an acknowledgment in the
+   product documentation would be appreciated but is not required.
+2. Altered versions must be plainly marked as such,
+   and must not be misrepresented as being the original header file.
+3. This notice may not be removed or altered from any distribution.

+ 17 - 0
assets/nsis/Docs/makensisw/License.txt

@@ -0,0 +1,17 @@
+Copyright (c) 2002 Robert Rainwater <rrainwater@yahoo.com>
+
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.

+ 223 - 0
assets/nsis/Docs/makensisw/Readme.txt

@@ -0,0 +1,223 @@
+----------------------------------------------------
+MakeNSISW - MakeNSIS Windows Wrapper
+----------------------------------------------------
+
+
+About MakeNSISW
+---------------
+MakeNSISW is a wrapper for the MakeNSIS that is distributed with
+NSIS (http://www.nullsoft.com/free/nsis/).  MakeNSISW allows you 
+to compile NSIS scripts using a Windows GUI interface.  To install
+MakeNSISW, compile the source using Visual C++ or Mingw.
+
+
+Requirements
+------------
+MakeNSISW requires NSIS be installed on your system.  The default 
+directory for this installation is $PROGRAMFILES\NSIS\Contrib\MakeNSISW.
+
+
+Usage:
+------
+If you installed the Shell Extensions option during the installation, then
+all that is required is that you choose 'Compile NSI' from the right-
+click menu on a NSIS script.  This will invoke MakeNSISW.
+
+The format of the parameters when calling MakeNSISW from the commandline is:
+  makensisw [options] [script.nsi | - [...]]
+
+For the options, please see the MakeNSIS documentation.
+
+
+Shortcut Keys
+-------------
+Ctrl+A: Select All text
+Ctrl+B: Open Script Folder
+Ctrl+C: Copy selected text
+Ctrl+D: Opens the Define Symbols dialog
+Ctrl+E: Edits the script
+Ctrl+F: Find text
+Ctrl+L: Load a script
+Ctrl+R: Recompiles the script
+Ctrl+T: Tests the installer
+Ctrl+W: Clear Log Window
+Alt+X: Exits the application
+F1: View Documentation
+
+
+Version History
+---------------
+0.1
+ - Initial Release
+
+0.2
+ - Added ability to save output and copy output
+
+0.3
+ - Added option to recompile script (F2 or File|Recompile)
+ - Added Help Menu
+ - Return code is now always set
+ - Added Accelerator key support for Exit and Recompile
+ - No longer uses NSIS's version string
+ - Made clearer status message in title bar
+ - Disabled menu/accelerator functions during compile
+
+0.4
+ - Fixed Copy Selected bug
+
+0.5
+ - Minor Makefile changes (mingw)
+ - Moved strings into global strings to make editing easier
+ - Added Clear Log Command under Edit menu
+ - Recompile no longer clears the log window (use F5)
+ - Close is now the default button when you hit enter
+ - added VC++ project, updated resources to work with VC++
+ - rearranged directory structure
+ - makefiles now target ../../makensisw.exe
+ - removed makensisw home link in help menu (hope this is ok,
+   doesn't really seem needed to me)
+ - made display use a fixed width font (Some people may not like
+   this, but I do)
+ - added 'test' button (peeks output for 'Output' line)
+ - made it so that the log shows the most recent 32k.
+ - made it so that the log always clears on a recompile.
+ - compiled with VC++ so no longer needs msvcrt.dll
+ - made the compiler name be a full path (for more flexibility)
+
+0.6
+ - print correct usage if unable to execute compiler
+ - removed mingw warnings
+ - set title/branding before errors
+ - some docs changes
+ - Added Edit|Edit Script function
+
+0.7
+ - Edit Script should now work for output>32k
+ - Added resize support (thanks to felfert)
+ - Added window position saving (thanks to felfert)
+ - Disable some items when exec of makensis failed
+
+0.8
+ - Added window size constraints (thanks to bcheck)
+ - Cleaned up the resource file
+
+0.9
+ - Removed global strings (moved into #defines)
+ - Some GUI changes
+ - No longer focused Close button (its default anyways)
+ - Fixed resize bug on minimize/restore (thanks to felfert)
+ - Made window placement stored in HKLM instead of HKCU, cause
+   I hate things that get littered in HKCU.
+
+1.0
+ - Fixed bug with large output causing crash
+
+1.1
+ - Crash may actually be fixed
+
+1.2
+ - XP visual style support
+
+1.3
+ - Added Documentation menu item
+ - Fix GUI problem with About dialog
+
+1.4
+ - Edit Script command will now work with or without file associations
+ - Added default filename for save dialog
+ - Use standard fonts
+ - Documentation menuitem caused recompile
+
+1.5
+ - Fixed Copy All function
+
+1.6
+ - Reduced size from 44k to 12k (kichik)
+ - Editbox not limited to 32k (now using richedit control)
+ - Made the log window font-size smaller.
+
+1.7
+ - Added check for warnings
+ - Added sound for sucessfull compilations
+ - Update home page and documentation menu items to Sourceforge page
+
+1.8
+ - Contents of log window are now streamed in
+ - Empty log window check (to prevent random crashes)
+
+1.9
+ - Text always scrolls to bottom (kichik)
+ - Updated link to new docs
+ - Makensisw now takes the same parameters as makensis.exe
+ - Fixed some random crashes
+ - Drag and Drop Support into the Makensisw window
+ - Updated icon to more sexy one
+ - Added Load Script option on File menu
+ - Added Search Dialog (Ctrl+F) (kichik)
+ - Added Select All (Ctrl+A), Copy (Ctrl+C), Exit (Alt+X) keys
+ - Branding text now reflects NSIS version
+ - Added some simple tool tips
+ - Added Context Menu in log window
+ - Added resize gripper
+ - Ctrl+L loads a script
+ - Added Clear Log (Ctrl+W)
+ - Browse Script (Ctrl+B) launches explorer in script directory
+ - Check for Update command
+ - Added link to the NSIS Forum under Help menu
+ - Bunch of other stuff not worth mentioning
+ - Define Symbols menu (Ctrl+D)
+
+2.0
+ - Improved user interface
+ - Define Symbols is available even if a script is not loaded
+ - Defined Symbols are saved on exit and reloaded on start
+ - Added NSIS Update menu
+ - Added toolbar for commonly used menus
+ - Made the Toolbar style flat
+ - Added option for compile & run
+ - Added compressor setting option
+ - Added support for lzma compression
+ - Added named Symbols sets.
+
+2.1
+ - Added "Cancel compilation" menu item
+
+2.2
+- Settings saved in HKCU instead of HKLM
+- Added menu accelerators to MRU list
+
+2.3
+- Escape button closes MakeNSISw
+
+2.3.1
+- Fixed broken command line parameter handling
+
+2.3.2
+- The size gripper can be used to resize the window
+
+2.3.3
+- Update check switched from JNetLib to WinInet
+- New file type icons
+
+
+Copyright Information
+---------------------
+Copyright (c) 2002 Robert Rainwater
+Contributors: Justin Frankel, Fritz Elfert, Amir Szekely, 
+              Sunil Kamath, Joost Verburg, Anders Kjersem.
+
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.

+ 75 - 0
assets/nsis/Include/Colors.nsh

@@ -0,0 +1,75 @@
+!ifndef COLORS_NSH
+!define COLORS_NSH
+
+!verbose push
+!verbose 3
+
+# Squad
+# Rob Segal
+# Joel
+# Yathosho
+
+
+# Predefined HTML Hex colors
+!define WHITE "FFFFFF"
+!define BLACK "000000"
+!define YELLOW "FFFF00"
+!define RED "FF0000"
+!define GREEN "00FF00"
+!define BLUE "0000FF"
+!define MAGENTA "FF00FF"
+!define CYAN "00FFFF"
+
+# Function to convert red , green and blue integer values to HTML Hex format
+!define RGB '!insertmacro rgb2hex'
+
+# Function to convert red, green and blue integer values to Hexadecimal (0xRRGGBB) format
+!define HEX '!insertmacro rgb2hex2'
+
+# Function to get the r value from a RGB number
+!define GetRvalue '!insertmacro redvalue'
+
+# Function to get the g value from a RGB number
+!define GetGvalue '!insertmacro greenvalue'
+
+# Function to get the b value from a RGB number
+!define GetBvalue '!insertmacro bluevalue'
+
+# Function to get the r value from a Hex number
+!define GetRvalueX '!insertmacro bluevalue'
+
+# Function to get the g value from a Hex number
+!define GetGvalueX '!insertmacro greenvalue'
+
+# Function to get the r value from a HEX number
+!define GetBvalueX '!insertmacro redvalue'
+
+!macro rgb2hex output R G B
+IntFmt "${output}" "%02X" "${R}"
+IntFmt "${output}" "${output}%02X" "${G}"
+IntFmt "${output}" "${output}%02X" "${B}"
+!macroend
+
+!macro rgb2hex2 output R G B
+IntFmt "${output}" "%02X" "${B}"
+IntFmt "${output}" "${output}%02X" "${G}"
+IntFmt "${output}" "${output}%02X" "${R}"
+!macroend
+
+!macro redvalue output hexval
+StrCpy ${output} ${hexval} 2 0
+IntFmt "${output}" "%02i" "0x${output}"
+!macroend
+
+!macro greenvalue output hexval
+StrCpy ${output} ${hexval} 2 2
+IntFmt "${output}" "%02i" "0x${output}"
+!macroend
+
+!macro bluevalue output hexval
+StrCpy ${output} ${hexval} 2 4
+IntFmt "${output}" "%02i" "0x${output}"
+!macroend
+
+!verbose pop
+!endif

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 2015 - 0
assets/nsis/Include/FileFunc.nsh


+ 244 - 0
assets/nsis/Include/InstallOptions.nsh

@@ -0,0 +1,244 @@
+/*
+
+InstallOptions.nsh
+Macros and conversion functions for InstallOptions
+
+*/
+
+!ifndef ___NSIS__INSTALL_OPTIONS__NSH___
+!define ___NSIS__INSTALL_OPTIONS__NSH___
+
+!include LogicLib.nsh
+
+!macro INSTALLOPTIONS_FUNCTION_READ_CONVERT
+  !insertmacro INSTALLOPTIONS_FUNCTION_IO2NSIS ""
+!macroend
+
+!macro INSTALLOPTIONS_UNFUNCTION_READ_CONVERT
+  !insertmacro INSTALLOPTIONS_FUNCTION_IO2NSIS un.
+!macroend
+
+!macro INSTALLOPTIONS_FUNCTION_WRITE_CONVERT
+  !insertmacro INSTALLOPTIONS_FUNCTION_NSIS2IO ""
+!macroend
+
+!macro INSTALLOPTIONS_UNFUNCTION_WRITE_CONVERT
+  !insertmacro INSTALLOPTIONS_FUNCTION_NSIS2IO un.
+!macroend
+
+!macro INSTALLOPTIONS_FUNCTION_NSIS2IO UNINSTALLER_FUNCPREFIX
+
+  ; Convert an NSIS string to a form suitable for use by InstallOptions
+  ; Usage:
+  ;   Push <NSIS-string>
+  ;   Call Nsis2Io
+  ;   Pop <IO-string>
+
+  Function ${UNINSTALLER_FUNCPREFIX}Nsis2Io
+
+    Exch $0 ; The source
+    Push $1 ; The output
+    Push $2 ; Temporary char
+    Push $3 ; Length
+    Push $4 ; Loop index
+    StrCpy $1 "" ; Initialise the output
+
+    StrLen $3 $0
+    IntOp $3 $3 - 1
+
+    ${For} $4 0 $3
+      StrCpy $2 $0 1 $4
+      ${If}     $2 == '\'
+        StrCpy $2 '\\'
+      ${ElseIf} $2 == '$\r'
+        StrCpy $2 '\r'
+      ${ElseIf} $2 == '$\n'
+        StrCpy $2 '\n'
+      ${ElseIf} $2 == '$\t'
+        StrCpy $2 '\t'
+      ${EndIf}
+      StrCpy $1 $1$2
+    ${Next}
+
+    StrCpy $0 $1
+    Pop $4
+    Pop $3
+    Pop $2
+    Pop $1
+    Exch $0
+
+  FunctionEnd
+
+!macroend
+
+!macro INSTALLOPTIONS_FUNCTION_IO2NSIS UNINSTALLER_FUNCPREFIX
+
+  ; Convert an InstallOptions string to a form suitable for use by NSIS
+  ; Usage:
+  ;   Push <IO-string>
+  ;   Call Io2Nsis
+  ;   Pop <NSIS-string>
+
+  Function ${UNINSTALLER_FUNCPREFIX}Io2Nsis
+
+    Exch $0 ; The source
+    Push $1 ; The output
+    Push $2 ; Temporary char
+    Push $3 ; Length
+    Push $4 ; Loop index
+    StrCpy $1 "" ; Initialise the output
+
+    StrLen $3 $0
+    IntOp $3 $3 - 1
+
+    ${For} $4 0 $3
+      StrCpy $2 $0 2 $4
+      ${If}     $2 == '\\'
+        StrCpy $2 '\'
+        IntOp $4 $4 + 1
+      ${ElseIf} $2 == '\r'
+        StrCpy $2 '$\r'
+        IntOp $4 $4 + 1
+      ${ElseIf} $2 == '\n'
+        StrCpy $2 '$\n'
+        IntOp $4 $4 + 1
+      ${ElseIf} $2 == '\t'
+        StrCpy $2 '$\t'
+        IntOp $4 $4 + 1
+      ${EndIf}
+      StrCpy $2 $2 1
+      StrCpy $1 $1$2
+    ${Next}
+
+    StrCpy $0 $1
+    Pop $4
+    Pop $3
+    Pop $2
+    Pop $1
+    Exch $0
+
+  FunctionEnd
+
+!macroend
+
+!macro INSTALLOPTIONS_EXTRACT FILE
+
+  InitPluginsDir
+  File "/oname=$PLUGINSDIR\${FILE}" "${FILE}"
+!ifdef NSIS_UNICODE
+  InstallOptions::make_unicode "$PLUGINSDIR\${FILE}"
+!endif
+  !insertmacro INSTALLOPTIONS_WRITE "${FILE}" "Settings" "RTL" "$(^RTL)"
+
+!macroend
+
+!macro INSTALLOPTIONS_EXTRACT_AS FILE FILENAME
+
+  InitPluginsDir
+  File "/oname=$PLUGINSDIR\${FILENAME}" "${FILE}"
+!ifdef NSIS_UNICODE
+  InstallOptions::make_unicode "$PLUGINSDIR\${FILENAME}"
+!endif
+  !insertmacro INSTALLOPTIONS_WRITE "${FILENAME}" "Settings" "RTL" "$(^RTL)"
+
+!macroend
+
+!macro INSTALLOPTIONS_DISPLAY FILE
+
+  Push $0
+
+  InstallOptions::dialog "$PLUGINSDIR\${FILE}"
+  Pop $0
+
+  Pop $0
+
+!macroend
+
+!macro INSTALLOPTIONS_DISPLAY_RETURN FILE
+
+  InstallOptions::dialog "$PLUGINSDIR\${FILE}"
+
+!macroend
+
+!macro INSTALLOPTIONS_INITDIALOG FILE
+
+  InstallOptions::initDialog "$PLUGINSDIR\${FILE}"
+
+!macroend
+
+!macro INSTALLOPTIONS_SHOW
+
+  Push $0
+
+  InstallOptions::show
+  Pop $0
+
+  Pop $0
+
+!macroend
+
+!macro INSTALLOPTIONS_SHOW_RETURN
+
+  InstallOptions::show
+
+!macroend
+
+!macro INSTALLOPTIONS_READ VAR FILE SECTION KEY
+
+  ReadIniStr ${VAR} "$PLUGINSDIR\${FILE}" "${SECTION}" "${KEY}"
+
+!macroend
+
+!macro INSTALLOPTIONS_WRITE FILE SECTION KEY VALUE
+
+  WriteIniStr "$PLUGINSDIR\${FILE}" "${SECTION}" "${KEY}" "${VALUE}"
+
+!macroend
+
+!macro INSTALLOPTIONS_READ_CONVERT VAR FILE SECTION KEY
+
+  ReadIniStr ${VAR} "$PLUGINSDIR\${FILE}" "${SECTION}" "${KEY}"
+  Push ${VAR}
+  Call Io2Nsis
+  Pop ${VAR}
+
+!macroend
+
+!macro INSTALLOPTIONS_READ_UNCONVERT VAR FILE SECTION KEY
+
+  ReadIniStr ${VAR} "$PLUGINSDIR\${FILE}" "${SECTION}" "${KEY}"
+  Push ${VAR}
+  Call un.Io2Nsis
+  Pop ${VAR}
+
+!macroend
+
+!macro INSTALLOPTIONS_WRITE_CONVERT FILE SECTION KEY VALUE
+
+  Push $0
+  StrCpy $0 "${VALUE}"
+  Push $0
+  Call Nsis2Io
+  Pop $0
+  
+  WriteIniStr "$PLUGINSDIR\${FILE}" "${SECTION}" "${KEY}" $0
+
+  Pop $0
+
+!macroend
+  
+!macro INSTALLOPTIONS_WRITE_UNCONVERT FILE SECTION KEY VALUE
+
+  Push $0
+  StrCpy $0 "${VALUE}"
+  Push $0
+  Call un.Nsis2Io
+  Pop $0
+  
+  WriteIniStr "$PLUGINSDIR\${FILE}" "${SECTION}" "${KEY}" $0
+
+  Pop $0
+
+!macroend
+
+!endif # ___NSIS__INSTALL_OPTIONS__NSH___

+ 191 - 0
assets/nsis/Include/LangFile.nsh

@@ -0,0 +1,191 @@
+/*
+
+LangFile.nsh
+
+Header file to create language files that can be
+included with a single command.
+
+Copyright 2008-2016 Joost Verburg, Anders Kjersem
+
+* Either LANGFILE_INCLUDE or LANGFILE_INCLUDE_WITHDEFAULT
+  can be called from the script to include a language file.
+
+  - LANGFILE_INCLUDE takes the language file name as parameter.
+  - LANGFILE_INCLUDE_WITHDEFAULT takes as additional second
+    parameter, the default language file to load missing strings from.
+
+* Language strings in the language file have the format:
+  ${LangFileString} LANGSTRING_NAME "Text"
+
+* There are two types of language header files:
+
+  - NSIS multi-lang support; these must start with the LANGFILE macro and 
+    provide strings for features like MUI and MultiUser. If you are adding 
+    support for a new language to NSIS you should make a copy of English.nsh 
+    and translate this .nsh along with the .nlf.
+  - Custom installer strings; these must start with the LANGFILE_EXT macro and 
+    contain translated versions of 
+    custom strings used in a particular installer.
+    This is useful if you want to put the translations for each language in 
+    their own separate file.
+
+* Example:
+
+  ; Setup.nsi
+  !include "MUI.nsh"
+  !insertmacro MUI_PAGE_INSTFILES
+  !insertmacro MUI_LANGUAGE "Danish"
+  !insertmacro LANGFILE_INCLUDE "DanishExtra.nsh"
+  !insertmacro MUI_LANGUAGE "Swedish"
+  !insertmacro LANGFILE_INCLUDE "SwedishExtra.nsh"
+  Section
+  MessageBox MB_OK "$(myCustomString)"
+  SectionEnd
+
+  ; SwedishExtra.nsh
+  !insertmacro LANGFILE_EXT Swedish
+  ${LangFileString} myCustomString "Bork bork"
+
+*/
+
+!ifndef LANGFILE_INCLUDED
+!define LANGFILE_INCLUDED
+
+!macro LANGFILE_INCLUDE FILENAME
+
+  ;Called from script: include a language file
+
+  !ifdef LangFileString
+    !undef LangFileString
+  !endif
+
+  !define LangFileString "!insertmacro LANGFILE_SETSTRING"
+
+  !define LANGFILE_SETNAMES
+  !include "${FILENAME}"
+  !undef LANGFILE_SETNAMES
+
+  ;Create language strings
+  !define /redef LangFileString "!insertmacro LANGFILE_LANGSTRING"
+  !include "${FILENAME}"
+
+!macroend
+
+!macro LANGFILE_INCLUDE_WITHDEFAULT FILENAME FILENAME_DEFAULT
+
+  ;Called from script: include a language file
+  ;Obtains missing strings from a default file
+
+  !ifdef LangFileString
+    !undef LangFileString
+  !endif
+
+  !define LangFileString "!insertmacro LANGFILE_SETSTRING"
+
+  !define LANGFILE_SETNAMES
+  !include "${FILENAME}"
+  !undef LANGFILE_SETNAMES
+
+  ;Include default language for missing strings
+  !define LANGFILE_PRIV_INCLUDEISFALLBACK "${FILENAME_DEFAULT}"
+  !include "${FILENAME_DEFAULT}"
+  !undef LANGFILE_PRIV_INCLUDEISFALLBACK
+
+  ;Create language strings
+  !define /redef LangFileString "!insertmacro LANGFILE_LANGSTRING"
+  !include "${FILENAME_DEFAULT}"
+
+!macroend
+
+!macro LANGFILE NLFID ENGNAME NATIVENAME NATIVEASCIINAME
+
+  ;Start of standard NSIS language file
+
+  ; NLFID: Must match the name of the .nlf file
+  ; ENGNAME: English name of language, "=" if it is the same as NLFID
+  ; NATIVENAME: Native name of language. (In Unicode)
+  ; NATIVEASCIINAME: Native name of language using only ASCII, "=" if it is the same as NATIVENAME
+
+  ; Example: LANGFILE "Swedish" = "Svenska" =
+  ; For more examples, see French.nsh, Greek.nsh and PortugueseBR.nsh
+
+  !ifdef LANGFILE_SETNAMES
+
+    !ifdef LANGFILE_IDNAME
+      !undef LANGFILE_IDNAME
+    !endif
+
+    !define LANGFILE_IDNAME "${NLFID}"
+
+    ; ModernUI or the .nsi can change LANGFILE_LANGDLL_FMT if desired
+    !ifndef LANGFILE_LANGDLL_FMT
+      !ifndef NSIS_UNICODE
+        !define LANGFILE_LANGDLL_FMT "%ENGNAME% / %NATIVEASCIINAME%"
+      !endif
+      !define /ifndef LANGFILE_LANGDLL_FMT "%NATIVENAME%"
+    !endif
+
+    !ifndef "LANGFILE_${NLFID}_NAME"
+      !if "${ENGNAME}" == "="
+        !define /redef ENGNAME "${NLFID}"
+      !endif
+      !if "${NATIVEASCIINAME}" == "="
+        !define /redef NATIVEASCIINAME "${NATIVENAME}"
+      !endif
+
+      !define "LANGFILE_${NLFID}_ENGLISHNAME" "${ENGNAME}"
+      !ifdef NSIS_UNICODE
+        !define "LANGFILE_${NLFID}_NAME" "${NATIVENAME}"
+      !else
+        !define "LANGFILE_${NLFID}_NAME" "${NATIVEASCIINAME}"
+      !endif
+
+      !searchreplace LANGFILE_${NLFID}_LANGDLL "${LANGFILE_LANGDLL_FMT}" %NATIVEASCIINAME% "${NATIVEASCIINAME}"
+      !searchreplace LANGFILE_${NLFID}_LANGDLL "${LANGFILE_${NLFID}_LANGDLL}" %NATIVENAME% "${NATIVENAME}"
+      !searchreplace LANGFILE_${NLFID}_LANGDLL "${LANGFILE_${NLFID}_LANGDLL}" %ENGNAME% "${ENGNAME}"
+
+    !endif
+
+  !endif
+
+!macroend
+
+!macro LANGFILE_EXT IDNAME
+
+  ;Start of installer language file
+  
+  !ifdef LANGFILE_SETNAMES
+
+    !ifdef LANGFILE_IDNAME
+      !undef LANGFILE_IDNAME
+    !endif
+
+    !define LANGFILE_IDNAME "${IDNAME}"
+
+  !endif
+
+!macroend
+
+!macro LANGFILE_SETSTRING NAME VALUE
+
+  ;Set define with translated string
+
+  !ifndef ${NAME}
+    !define "${NAME}" "${VALUE}"
+    !ifdef LANGFILE_PRIV_INCLUDEISFALLBACK
+      !warning 'LangString "${NAME}" for language ${LANGFILE_IDNAME} is missing, using fallback from "${LANGFILE_PRIV_INCLUDEISFALLBACK}"'
+    !endif
+  !endif
+
+!macroend
+
+!macro LANGFILE_LANGSTRING NAME DUMMY
+
+  ;Create a language string from a define and undefine
+
+  LangString "${NAME}" "${LANG_${LANGFILE_IDNAME}}" "${${NAME}}"
+  !undef "${NAME}"
+
+!macroend
+
+!endif

+ 870 - 0
assets/nsis/Include/Library.nsh

@@ -0,0 +1,870 @@
+#
+# Library.nsh
+#
+# A system for the installation and uninstallation of dynamic
+# link libraries (DLL) and type libraries (TLB). Using this
+# system you can handle the complete setup with one single
+# line of code:
+#
+#  * File copying
+#  * File copying on reboot
+#  * Version checks
+#  * Registration and unregistration
+#  * Registration and unregistration on reboot
+#  * Shared DLL counting
+#  * Windows File Protection checks
+#
+# For more information, read appendix B in the documentation.
+#
+
+!verbose push
+!verbose 3
+
+!ifndef LIB_INCLUDED
+
+!define LIB_INCLUDED
+
+!ifndef SHCNE_ASSOCCHANGED
+  !define SHCNE_ASSOCCHANGED 0x08000000
+!endif
+!ifndef SHCNF_IDLIST
+  !define SHCNF_IDLIST 0x0000
+!endif
+
+!define REGTOOL_VERSION v3
+!define REGTOOL_KEY NSIS.Library.RegTool.${REGTOOL_VERSION}
+
+!include LogicLib.nsh
+!include x64.nsh
+
+### GetParent macro, don't pass $1 or $2 as INTPUT or OUTPUT
+!macro __InstallLib_Helper_GetParent INPUT OUTPUT
+
+  # Copied from FileFunc.nsh
+
+  StrCpy ${OUTPUT} ${INPUT}
+
+  Push $1
+  Push $2
+
+  StrCpy $2 ${OUTPUT} 1 -1
+  StrCmp $2 '\' 0 +3
+  StrCpy ${OUTPUT} ${OUTPUT} -1
+  goto -3
+
+  StrCpy $1 0
+  IntOp $1 $1 - 1
+  StrCpy $2 ${OUTPUT} 1 $1
+  StrCmp $2 '\' +2
+  StrCmp $2 '' 0 -3
+  StrCpy ${OUTPUT} ${OUTPUT} $1
+
+  Pop $2
+  Pop $1
+
+!macroend
+
+### Initialize session id (GUID)
+!macro __InstallLib_Helper_InitSession
+
+  !ifndef __InstallLib_SessionGUID_Defined
+
+    !define __InstallLib_SessionGUID_Defined
+
+    Var /GLOBAL __INSTALLLLIB_SESSIONGUID
+
+  !endif
+
+  !define __InstallLib_Helper_InitSession_Label "Library_${__FILE__}${__LINE__}"
+
+  StrCmp $__INSTALLLLIB_SESSIONGUID '' 0 "${__InstallLib_Helper_InitSession_Label}"
+
+    System::Call 'ole32::CoCreateGuid(g .s)'
+    Pop $__INSTALLLLIB_SESSIONGUID
+
+  "${__InstallLib_Helper_InitSession_Label}:"
+
+  !undef __InstallLib_Helper_InitSession_Label
+
+!macroend
+
+### Add a RegTool entry to register after reboot
+!macro __InstallLib_Helper_AddRegToolEntry mode filename tempdir
+
+  Push $R0
+  Push $R1
+  Push $R2
+  Push $R3
+
+  ;------------------------
+  ;Copy the parameters
+
+  Push "${filename}"
+  Push "${tempdir}"
+
+  Pop $R2 ; temporary directory
+  Pop $R1 ; file name to register
+
+  ;------------------------
+  ;Initialize session id
+
+  !insertmacro __InstallLib_Helper_InitSession
+
+  ;------------------------
+  ;Advance counter
+
+  StrCpy $R0 0
+  ReadRegDWORD $R0 HKLM "Software\${REGTOOL_KEY}\$__INSTALLLLIB_SESSIONGUID" "count"
+  IntOp $R0 $R0 + 1
+  WriteRegDWORD HKLM "Software\${REGTOOL_KEY}\$__INSTALLLLIB_SESSIONGUID" "count" "$R0"
+
+  ;------------------------
+  ;Setup RegTool
+
+  ReadRegStr $R3 HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" "${REGTOOL_KEY}"
+  StrCpy $R3 $R3 -4 1
+  IfFileExists $R3 +3
+
+    File /oname=$R2\${REGTOOL_KEY}.$__INSTALLLLIB_SESSIONGUID.exe "${NSISDIR}\Bin\RegTool.bin"
+    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
+      "${REGTOOL_KEY}" '"$R2\${REGTOOL_KEY}.$__INSTALLLLIB_SESSIONGUID.exe" /S'
+
+  ;------------------------
+  ;Add RegTool entry
+
+  WriteRegStr HKLM "Software\${REGTOOL_KEY}\$__INSTALLLLIB_SESSIONGUID" "$R0.file" "$R1"
+  WriteRegStr HKLM "Software\${REGTOOL_KEY}\$__INSTALLLLIB_SESSIONGUID" "$R0.mode" "${mode}"
+
+  Pop $R3
+  Pop $R2
+  Pop $R1
+  Pop $R0
+
+!macroend
+
+### Get library version
+!macro __InstallLib_Helper_GetVersion TYPE FILE
+
+  !tempfile LIBRARY_TEMP_NSH
+
+  !ifdef NSIS_WIN32_MAKENSIS
+
+    !execute '"${NSISDIR}\Bin\LibraryLocal.exe" "${TYPE}" "${FILE}" "${LIBRARY_TEMP_NSH}"'
+
+  !else
+
+    !execute 'LibraryLocal "${TYPE}" "${FILE}" "${LIBRARY_TEMP_NSH}"'
+
+    !if ${TYPE} == 'T'
+
+      !warning "LibraryLocal currently supports TypeLibs version detection on Windows only"
+
+    !endif
+
+  !endif
+
+  !include "${LIBRARY_TEMP_NSH}"
+  !delfile "${LIBRARY_TEMP_NSH}"
+  !undef LIBRARY_TEMP_NSH
+
+!macroend
+
+### Install library
+!macro InstallLib libtype shared install localfile destfile tempbasedir
+
+  !verbose push
+  !verbose 3
+
+  Push $R0
+  Push $R1
+  Push $R2
+  Push $R3
+  Push $R4
+  Push $R5
+
+  ;------------------------
+  ;Define
+
+  !define INSTALLLIB_UNIQUE "${__FILE__}${__LINE__}"
+
+  !define INSTALLLIB_LIBTYPE_${libtype}
+  !define INSTALLLIB_LIBTYPE_SET INSTALLLIB_LIBTYPE_${libtype}
+  !define INSTALLLIB_SHARED_${shared}
+  !define INSTALLLIB_SHARED_SET INSTALLLIB_SHARED_${shared}
+  !define INSTALLLIB_INSTALL_${install}
+  !define INSTALLLIB_INSTALL_SET INSTALLLIB_INSTALL_${install}
+
+  ;------------------------
+  ;Validate
+
+  !ifndef INSTALLLIB_LIBTYPE_DLL & INSTALLLIB_LIBTYPE_REGDLL & INSTALLLIB_LIBTYPE_TLB & \
+    INSTALLLIB_LIBTYPE_REGDLLTLB & INSTALLLIB_LIBTYPE_REGEXE
+    !error "InstallLib: Incorrect setting for parameter: libtype"
+  !endif
+
+  !ifndef INSTALLLIB_INSTALL_REBOOT_PROTECTED & INSTALLLIB_INSTALL_REBOOT_NOTPROTECTED & \
+    INSTALLLIB_INSTALL_NOREBOOT_PROTECTED & INSTALLLIB_INSTALL_NOREBOOT_NOTPROTECTED
+    !error "InstallLib: Incorrect setting for parameter: install"
+  !endif
+
+  ;------------------------
+  ;x64 settings
+
+  !ifdef LIBRARY_X64
+
+    ${DisableX64FSRedirection}
+
+  !endif
+
+  ;------------------------
+  ;Copy the parameters used on run-time to a variable
+  ;This allows the usage of variables as parameter
+
+  StrCpy $R4 "${destfile}"
+  StrCpy $R5 "${tempbasedir}"
+
+  ;------------------------
+  ;Shared library count
+
+  !ifndef INSTALLLIB_SHARED_NOTSHARED
+
+    StrCmp ${shared} "" 0 "installlib.noshareddllincrease_${INSTALLLIB_UNIQUE}"
+
+      !ifdef LIBRARY_X64
+
+        SetRegView 64
+
+      !endif
+
+      ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R4
+      ClearErrors
+      IntOp $R0 $R0 + 1
+      WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R4 $R0
+
+      !ifdef LIBRARY_X64
+
+        SetRegView lastused
+
+      !endif
+
+    "installlib.noshareddllincrease_${INSTALLLIB_UNIQUE}:"
+
+  !endif
+
+  ;------------------------
+  ;Check Windows File Protection
+
+  !ifdef INSTALLLIB_INSTALL_REBOOT_PROTECTED | INSTALLLIB_INSTALL_NOREBOOT_PROTECTED
+
+    !define LIBRARY_DEFINE_DONE_LABEL
+
+    System::Call "sfc::SfcIsFileProtected(i 0, w R4) i.R0"
+
+      StrCmp $R0 "error" "installlib.notprotected_${INSTALLLIB_UNIQUE}"
+      StrCmp $R0 "0" "installlib.notprotected_${INSTALLLIB_UNIQUE}"
+
+    Goto "installlib.done_${INSTALLLIB_UNIQUE}"
+
+    "installlib.notprotected_${INSTALLLIB_UNIQUE}:"
+
+  !endif
+
+  ;------------------------
+  ;Check file
+
+  IfFileExists $R4 0 "installlib.copy_${INSTALLLIB_UNIQUE}"
+
+  ;------------------------
+  ;Get version information
+
+  !ifndef LIBRARY_IGNORE_VERSION
+
+    !insertmacro __InstallLib_Helper_GetVersion D "${LOCALFILE}"
+
+    !ifdef LIBRARY_VERSION_FILENOTFOUND
+      !error "InstallLib: The library ${LOCALFILE} could not be found."
+    !endif
+
+    !ifndef LIBRARY_VERSION_NONE
+
+      !define LIBRARY_DEFINE_UPGRADE_LABEL
+      !define LIBRARY_DEFINE_REGISTER_LABEL
+
+      StrCpy $R0 ${LIBRARY_VERSION_HIGH}
+      StrCpy $R1 ${LIBRARY_VERSION_LOW}
+
+      GetDLLVersion $R4 $R2 $R3
+
+      !undef LIBRARY_VERSION_HIGH
+      !undef LIBRARY_VERSION_LOW
+
+      !ifndef INSTALLLIB_LIBTYPE_TLB & INSTALLLIB_LIBTYPE_REGDLLTLB
+
+        IntCmpU $R0 $R2 0 "installlib.register_${INSTALLLIB_UNIQUE}" "installlib.upgrade_${INSTALLLIB_UNIQUE}"
+        IntCmpU $R1 $R3 "installlib.register_${INSTALLLIB_UNIQUE}" "installlib.register_${INSTALLLIB_UNIQUE}" \
+          "installlib.upgrade_${INSTALLLIB_UNIQUE}"
+
+      !else
+
+        !insertmacro __InstallLib_Helper_GetVersion T "${LOCALFILE}"
+
+        !ifdef LIBRARY_VERSION_FILENOTFOUND
+          !error "InstallLib: The library ${LOCALFILE} could not be found."
+        !endif
+
+        !ifndef LIBRARY_VERSION_NONE
+
+          IntCmpU $R0 $R2 0 "installlib.register_${INSTALLLIB_UNIQUE}" "installlib.upgrade_${INSTALLLIB_UNIQUE}"
+          IntCmpU $R1 $R3 0 "installlib.register_${INSTALLLIB_UNIQUE}" \
+            "installlib.upgrade_${INSTALLLIB_UNIQUE}"
+
+        !else
+
+          IntCmpU $R0 $R2 0 "installlib.register_${INSTALLLIB_UNIQUE}" "installlib.upgrade_${INSTALLLIB_UNIQUE}"
+          IntCmpU $R1 $R3 "installlib.register_${INSTALLLIB_UNIQUE}" "installlib.register_${INSTALLLIB_UNIQUE}" \
+            "installlib.upgrade_${INSTALLLIB_UNIQUE}"
+
+        !endif
+
+      !endif
+
+    !else
+
+      !undef LIBRARY_VERSION_NONE
+
+      !ifdef INSTALLLIB_LIBTYPE_TLB | INSTALLLIB_LIBTYPE_REGDLLTLB
+
+        !insertmacro __InstallLib_Helper_GetVersion T "${LOCALFILE}"
+
+      !endif
+
+    !endif
+
+    !ifdef INSTALLLIB_LIBTYPE_TLB | INSTALLLIB_LIBTYPE_REGDLLTLB
+
+      !ifndef LIBRARY_VERSION_NONE
+
+        !ifndef LIBRARY_DEFINE_UPGRADE_LABEL
+
+          !define LIBRARY_DEFINE_UPGRADE_LABEL
+
+        !endif
+
+        !ifndef LIBRARY_DEFINE_REGISTER_LABEL
+
+          !define LIBRARY_DEFINE_REGISTER_LABEL
+
+        !endif
+
+        StrCpy $R0 ${LIBRARY_VERSION_HIGH}
+        StrCpy $R1 ${LIBRARY_VERSION_LOW}
+
+        TypeLib::GetLibVersion $R4
+        Pop $R3
+        Pop $R2
+
+        IntCmpU $R0 $R2 0 "installlib.register_${INSTALLLIB_UNIQUE}" "installlib.upgrade_${INSTALLLIB_UNIQUE}"
+        IntCmpU $R1 $R3 "installlib.register_${INSTALLLIB_UNIQUE}" "installlib.register_${INSTALLLIB_UNIQUE}" \
+          "installlib.upgrade_${INSTALLLIB_UNIQUE}"
+
+        !undef LIBRARY_VERSION_HIGH
+        !undef LIBRARY_VERSION_LOW
+
+      !else
+
+        !undef LIBRARY_VERSION_NONE
+
+      !endif
+
+    !endif
+
+  !endif
+
+  ;------------------------
+  ;Upgrade
+
+  !ifdef LIBRARY_DEFINE_UPGRADE_LABEL
+
+    !undef LIBRARY_DEFINE_UPGRADE_LABEL
+
+    "installlib.upgrade_${INSTALLLIB_UNIQUE}:"
+
+  !endif
+
+  ;------------------------
+  ;Copy
+
+  !ifdef INSTALLLIB_INSTALL_NOREBOOT_PROTECTED | INSTALLLIB_INSTALL_NOREBOOT_NOTPROTECTED
+
+    "installlib.copy_${INSTALLLIB_UNIQUE}:"
+
+    StrCpy $R0 $R4
+    Call ":installlib.file_${INSTALLLIB_UNIQUE}"
+
+  !else
+
+    !ifndef LIBRARY_DEFINE_REGISTER_LABEL
+
+      !define LIBRARY_DEFINE_REGISTER_LABEL
+
+    !endif
+
+    !ifndef LIBRARY_DEFINE_DONE_LABEL
+
+      !define LIBRARY_DEFINE_DONE_LABEL
+
+    !endif
+
+    ClearErrors
+
+    StrCpy $R0 $R4
+    Call ":installlib.file_${INSTALLLIB_UNIQUE}"
+
+    IfErrors 0 "installlib.register_${INSTALLLIB_UNIQUE}"
+
+    SetOverwrite lastused
+
+    ;------------------------
+    ;Copy on reboot
+
+    GetTempFileName $R0 $R5
+    Call ":installlib.file_${INSTALLLIB_UNIQUE}"
+    Rename /REBOOTOK $R0 $R4
+
+    ;------------------------
+    ;Register on reboot
+
+    Call ":installlib.regonreboot_${INSTALLLIB_UNIQUE}"
+
+    Goto "installlib.done_${INSTALLLIB_UNIQUE}"
+
+    "installlib.copy_${INSTALLLIB_UNIQUE}:"
+      StrCpy $R0 $R4
+      Call ":installlib.file_${INSTALLLIB_UNIQUE}"
+
+  !endif
+
+  ;------------------------
+  ;Register
+
+  !ifdef LIBRARY_DEFINE_REGISTER_LABEL
+
+    !undef LIBRARY_DEFINE_REGISTER_LABEL
+
+    "installlib.register_${INSTALLLIB_UNIQUE}:"
+
+  !endif
+
+  !ifdef INSTALLLIB_LIBTYPE_REGDLL | INSTALLLIB_LIBTYPE_TLB | INSTALLLIB_LIBTYPE_REGDLLTLB | INSTALLLIB_LIBTYPE_REGEXE
+
+    !ifdef INSTALLLIB_INSTALL_REBOOT_PROTECTED | INSTALLLIB_INSTALL_REBOOT_NOTPROTECTED
+
+      IfRebootFlag 0 "installlib.regnoreboot_${INSTALLLIB_UNIQUE}"
+
+        Call ":installlib.regonreboot_${INSTALLLIB_UNIQUE}"
+
+        Goto "installlib.registerfinish_${INSTALLLIB_UNIQUE}"
+
+      "installlib.regnoreboot_${INSTALLLIB_UNIQUE}:"
+
+    !endif
+
+    !ifdef INSTALLLIB_LIBTYPE_TLB | INSTALLLIB_LIBTYPE_REGDLLTLB
+
+      TypeLib::Register $R4
+
+    !endif
+
+    !ifdef INSTALLLIB_LIBTYPE_REGDLL | INSTALLLIB_LIBTYPE_REGDLLTLB
+
+      !ifndef LIBRARY_X64
+
+        RegDll $R4
+
+      !else
+
+        ExecWait '"$SYSDIR\regsvr32.exe" /s "$R4"'
+
+      !endif
+
+    !endif
+
+    !ifdef INSTALLLIB_LIBTYPE_REGEXE
+
+      ExecWait '"$R4" /regserver'
+
+    !endif
+
+    !ifdef INSTALLLIB_INSTALL_REBOOT_PROTECTED | INSTALLLIB_INSTALL_REBOOT_NOTPROTECTED
+
+      "installlib.registerfinish_${INSTALLLIB_UNIQUE}:"
+
+    !endif
+
+  !endif
+
+  !ifdef LIBRARY_SHELL_EXTENSION
+
+    System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, i 0, i 0)'
+
+  !endif
+
+  !ifdef LIBRARY_COM
+
+    System::Call 'Ole32::CoFreeUnusedLibraries()'
+
+  !endif
+
+  ;------------------------
+  ;Done
+
+  !ifdef LIBRARY_DEFINE_DONE_LABEL
+
+    !undef LIBRARY_DEFINE_DONE_LABEL
+
+  "installlib.done_${INSTALLLIB_UNIQUE}:"
+
+  !endif
+
+  Pop $R5
+  Pop $R4
+  Pop $R3
+  Pop $R2
+  Pop $R1
+  Pop $R0
+
+  ;------------------------
+  ;End
+
+  Goto "installlib.end_${INSTALLLIB_UNIQUE}"
+
+  ;------------------------
+  ;Extract
+
+  !ifdef INSTALLLIB_INSTALL_REBOOT_PROTECTED | INSTALLLIB_INSTALL_REBOOT_NOTPROTECTED
+
+    SetOverwrite try
+
+  !else
+
+    SetOverwrite on
+
+  !endif
+
+  "installlib.file_${INSTALLLIB_UNIQUE}:"
+    SetFileAttributes $R0 FILE_ATTRIBUTE_NORMAL
+    ClearErrors
+    File /oname=$R0 "${LOCALFILE}"
+    Return
+
+  SetOverwrite lastused
+
+  ;------------------------
+  ;Register on reboot
+
+  !ifdef INSTALLLIB_INSTALL_REBOOT_PROTECTED | INSTALLLIB_INSTALL_REBOOT_NOTPROTECTED
+
+    "installlib.regonreboot_${INSTALLLIB_UNIQUE}:"
+
+      !ifdef INSTALLLIB_LIBTYPE_REGDLL | INSTALLLIB_LIBTYPE_REGDLLTLB
+        !ifndef LIBRARY_X64
+          !insertmacro __InstallLib_Helper_AddRegToolEntry 'D' "$R4" "$R5"
+        !else
+          !insertmacro __InstallLib_Helper_AddRegToolEntry 'DX' "$R4" "$R5"
+        !endif
+      !endif
+
+      !ifdef INSTALLLIB_LIBTYPE_TLB | INSTALLLIB_LIBTYPE_REGDLLTLB
+        !insertmacro __InstallLib_Helper_AddRegToolEntry 'T' "$R4" "$R5"
+      !endif
+
+      !ifdef INSTALLLIB_LIBTYPE_REGEXE
+        !insertmacro __InstallLib_Helper_AddRegToolEntry 'E' "$R4" "$R5"
+      !endif
+
+      Return
+
+  !endif
+
+  ;------------------------
+  ;End label
+
+  "installlib.end_${INSTALLLIB_UNIQUE}:"
+
+  !ifdef LIBRARY_X64
+
+    ${EnableX64FSRedirection}
+
+  !endif
+
+  ;------------------------
+  ;Undefine
+
+  !undef INSTALLLIB_UNIQUE
+
+  !undef ${INSTALLLIB_LIBTYPE_SET}
+  !undef INSTALLLIB_LIBTYPE_SET
+  !undef ${INSTALLLIB_SHARED_SET}
+  !undef INSTALLLIB_SHARED_SET
+  !undef ${INSTALLLIB_INSTALL_SET}
+  !undef INSTALLLIB_INSTALL_SET
+
+  !verbose pop
+
+!macroend
+
+### Uninstall library
+!macro UnInstallLib libtype shared uninstall file
+
+  !verbose push
+  !verbose 3
+
+  Push $R0
+  Push $R1
+
+  ;------------------------
+  ;Define
+
+  !define UNINSTALLLIB_UNIQUE "${__FILE__}${__LINE__}"
+
+  !define UNINSTALLLIB_LIBTYPE_${libtype}
+  !define UNINSTALLLIB_LIBTYPE_SET UNINSTALLLIB_LIBTYPE_${libtype}
+  !define UNINSTALLLIB_SHARED_${shared}
+  !define UNINSTALLLIB_SHARED_SET UNINSTALLLIB_SHARED_${shared}
+  !define UNINSTALLLIB_UNINSTALL_${uninstall}
+  !define UNINSTALLLIB_UNINSTALL_SET UNINSTALLLIB_UNINSTALL_${uninstall}
+
+  ;------------------------
+  ;Validate
+
+  !ifndef UNINSTALLLIB_LIBTYPE_DLL & UNINSTALLLIB_LIBTYPE_REGDLL & UNINSTALLLIB_LIBTYPE_TLB & \
+    UNINSTALLLIB_LIBTYPE_REGDLLTLB & UNINSTALLLIB_LIBTYPE_REGEXE
+    !error "UnInstallLib: Incorrect setting for parameter: libtype"
+  !endif
+
+  !ifndef UNINSTALLLIB_SHARED_NOTSHARED & UNINSTALLLIB_SHARED_SHARED
+    !error "UnInstallLib: Incorrect setting for parameter: shared"
+  !endif
+
+  !ifndef UNINSTALLLIB_UNINSTALL_NOREMOVE & UNINSTALLLIB_UNINSTALL_REBOOT_PROTECTED & \
+    UNINSTALLLIB_UNINSTALL_REBOOT_NOTPROTECTED & UNINSTALLLIB_UNINSTALL_NOREBOOT_PROTECTED & \
+    UNINSTALLLIB_UNINSTALL_NOREBOOT_NOTPROTECTED
+    !error "UnInstallLib: Incorrect setting for parameter: uninstall"
+  !endif
+
+  ;------------------------
+  ;x64 settings
+
+  !ifdef LIBRARY_X64
+
+    ${DisableX64FSRedirection}
+
+  !endif
+
+  ;------------------------
+  ;Copy the parameters used on run-time to a variable
+  ;This allows the usage of variables as parameter
+
+  StrCpy $R1 "${file}"
+
+  ;------------------------
+  ;Shared library count
+
+  !ifdef UNINSTALLLIB_SHARED_SHARED
+
+    !define UNINSTALLLIB_DONE_LABEL
+
+    !ifdef LIBRARY_X64
+
+      SetRegView 64
+
+    !endif
+
+    ReadRegDword $R0 HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1
+    StrCmp $R0 "" "uninstalllib.shareddlldone_${UNINSTALLLIB_UNIQUE}"
+
+    IntOp $R0 $R0 - 1
+    IntCmp $R0 0 "uninstalllib.shareddllremove_${UNINSTALLLIB_UNIQUE}" \
+      "uninstalllib.shareddllremove_${UNINSTALLLIB_UNIQUE}" "uninstalllib.shareddllinuse_${UNINSTALLLIB_UNIQUE}"
+
+    "uninstalllib.shareddllremove_${UNINSTALLLIB_UNIQUE}:"
+      DeleteRegValue HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1
+      !ifndef UNINSTALLLIB_SHARED_SHAREDNOREMOVE
+        Goto "uninstalllib.shareddlldone_${UNINSTALLLIB_UNIQUE}"
+      !endif
+
+    "uninstalllib.shareddllinuse_${UNINSTALLLIB_UNIQUE}:"
+      WriteRegDWORD HKLM Software\Microsoft\Windows\CurrentVersion\SharedDLLs $R1 $R0
+
+        !ifdef LIBRARY_X64
+
+          SetRegView lastused
+
+        !endif
+
+      Goto "uninstalllib.done_${UNINSTALLLIB_UNIQUE}"
+
+    "uninstalllib.shareddlldone_${UNINSTALLLIB_UNIQUE}:"
+
+    !ifdef LIBRARY_X64
+
+      SetRegView lastused
+
+    !endif
+
+  !endif
+
+  ;------------------------
+  ;Remove
+
+  !ifndef UNINSTALLLIB_UNINSTALL_NOREMOVE
+
+    ;------------------------
+    ;Check Windows File Protection
+
+    !ifdef UNINSTALLLIB_UNINSTALL_REBOOT_PROTECTED | UNINSTALLLIB_UNINSTALL_NOREBOOT_PROTECTED
+
+      !ifndef UNINSTALLLIB_DONE_LABEL
+
+        !define UNINSTALLLIB_DONE_LABEL
+
+      !endif
+
+      System::Call "sfc::SfcIsFileProtected(i 0, w $R1) i.R0"
+
+        StrCmp $R0 "error" "uninstalllib.notprotected_${UNINSTALLLIB_UNIQUE}"
+        StrCmp $R0 "0" "uninstalllib.notprotected_${UNINSTALLLIB_UNIQUE}"
+
+      Goto "uninstalllib.done_${UNINSTALLLIB_UNIQUE}"
+
+      "uninstalllib.notprotected_${UNINSTALLLIB_UNIQUE}:"
+
+    !endif
+
+    ;------------------------
+    ;Unregister
+
+    !ifdef UNINSTALLLIB_LIBTYPE_REGDLL | UNINSTALLLIB_LIBTYPE_REGDLLTLB
+
+      !ifndef LIBRARY_X64
+
+        UnRegDLL $R1
+
+      !else
+
+        ExecWait '"$SYSDIR\regsvr32.exe" /s /u "$R1"'
+
+      !endif
+
+    !endif
+
+    !ifdef UNINSTALLLIB_LIBTYPE_REGEXE
+
+      ExecWait '"$R1" /unregserver'
+
+    !endif
+
+    !ifdef UNINSTALLLIB_LIBTYPE_TLB | UNINSTALLLIB_LIBTYPE_REGDLLTLB
+
+      TypeLib::UnRegister $R1
+
+    !endif
+
+    !ifdef LIBRARY_SHELL_EXTENSION
+
+      System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, i 0, i 0)'
+
+    !endif
+
+    !ifdef LIBRARY_COM
+
+      System::Call 'Ole32::CoFreeUnusedLibraries()'
+
+    !endif
+
+    ;------------------------
+    ;Delete
+
+    Delete $R1
+
+    !ifdef UNINSTALLLIB_UNINSTALL_REBOOT_PROTECTED | UNINSTALLLIB_UNINSTALL_REBOOT_NOTPROTECTED
+
+      ${If} ${FileExists} $R1
+        # File is in use, can't just delete.
+        # Move file to another location before using Delete /REBOOTOK. This way, if
+        #  the user installs a new version of the DLL, it won't be deleted after
+        #  reboot. See bug #1097642 for more information on this.
+
+        # Try moving to $TEMP.
+        GetTempFileName $R0
+        Delete $R0
+        Rename $R1 $R0
+
+        ${If} ${FileExists} $R1
+          # Still here, delete temporary file, in case the file was copied
+          #  and not deleted. This happens when moving from network drives,
+          #  for example.
+          Delete $R0
+
+          # Try moving to directory containing the file.
+          !insertmacro __InstallLib_Helper_GetParent $R1 $R0
+          GetTempFileName $R0 $R0
+          Delete $R0
+          Rename $R1 $R0
+
+          ${If} ${FileExists} $R1
+            # Still here, delete temporary file.
+            Delete $R0
+
+            # Give up moving, simply Delete /REBOOTOK the file.
+            StrCpy $R0 $R1
+          ${EndIf}
+        ${EndIf}
+
+        # Delete the moved file.
+        Delete /REBOOTOK $R0
+      ${EndIf}
+
+    !endif
+
+  !endif
+
+  ;------------------------
+  ;Done
+
+  !ifdef UNINSTALLLIB_DONE_LABEL
+
+    !undef UNINSTALLLIB_DONE_LABEL
+
+    "uninstalllib.done_${UNINSTALLLIB_UNIQUE}:"
+
+  !endif
+
+  !ifdef LIBRARY_X64
+
+    ${EnableX64FSRedirection}
+
+  !endif
+
+  Pop $R1
+  Pop $R0
+
+  ;------------------------
+  ;Undefine
+
+  !undef UNINSTALLLIB_UNIQUE
+
+  !undef ${UNINSTALLLIB_LIBTYPE_SET}
+  !undef UNINSTALLLIB_LIBTYPE_SET
+  !undef ${UNINSTALLLIB_SHARED_SET}
+  !undef UNINSTALLLIB_SHARED_SET
+  !undef ${UNINSTALLLIB_UNINSTALL_SET}
+  !undef UNINSTALLLIB_UNINSTALL_SET
+
+  !verbose pop
+
+!macroend
+
+!endif
+
+!verbose pop

+ 853 - 0
assets/nsis/Include/LogicLib.nsh

@@ -0,0 +1,853 @@
+; NSIS LOGIC LIBRARY - LogicLib.nsh
+; Version 2.6 - 08/12/2007
+; By dselkirk@hotmail.com
+; and eccles@users.sf.net
+; with IfNot support added by Message
+;
+; Questions/Comments -
+; See http://forums.winamp.com/showthread.php?s=&postid=1116241
+;
+; Description:
+;   Provides the use of various logic statements within NSIS.
+;
+; Usage:
+;   The following "statements" are available:
+;       If|IfNot|Unless..{ElseIf|ElseIfNot|ElseUnless}..[Else]..EndIf|EndUnless
+;         - Conditionally executes a block of statements, depending on the value
+;           of an expression. IfNot and Unless are equivalent and
+;           interchangeable, as are ElseIfNot and ElseUnless.
+;       AndIf|AndIfNot|AndUnless|OrIf|OrIfNot|OrUnless
+;         - Adds any number of extra conditions to If, IfNot, Unless, ElseIf,
+;           ElseIfNot and ElseUnless statements.
+;       IfThen|IfNotThen..|..|
+;         - Conditionally executes an inline statement, depending on the value
+;           of an expression.
+;       IfCmd..||..|
+;         - Conditionally executes an inline statement, depending on a true
+;           value of the provided NSIS function.
+;       Select..{Case[2|3|4|5]}..[CaseElse|Default]..EndSelect
+;         - Executes one of several blocks of statements, depending on the value
+;           of an expression.
+;       Switch..{Case|CaseElse|Default}..EndSwitch
+;         - Jumps to one of several labels, depending on the value of an
+;           expression.
+;       Do[While|Until]..{ExitDo|Continue|Break}..Loop[While|Until]
+;         - Repeats a block of statements until stopped, or depending on the
+;           value of an expression.
+;       While..{ExitWhile|Continue|Break}..EndWhile
+;         - An alias for DoWhile..Loop (for backwards-compatibility)
+;       For[Each]..{ExitFor|Continue|Break}..Next
+;         - Repeats a block of statements varying the value of a variable.
+;
+;   The following "expressions" are available:
+;       Standard (built-in) string tests (which are case-insensitive):
+;         a == b; a != b
+;       Additional case-insensitive string tests (using System.dll):
+;         a S< b; a S>= b; a S> b; a S<= b
+;       Case-sensitive string tests:
+;         a S== b; a S!= b
+;       Standard (built-in) signed integer tests:
+;         a = b; a <> b; a < b; a >= b; a > b; a <= b; a & b
+;       Standard (built-in) unsigned integer tests:
+;         a U< b; a U>= b; a U> b; a U<= b
+;       64-bit integer tests (using System.dll):
+;         a L= b; a L<> b; a L< b; a L>= b; a L> b; a L<= b
+;       ptrdiff_t integer tests
+;         a P= b; a P<> b; a P< b; a P>= b; a P> b; a P<= b
+;       size_t integer tests
+;         a Z= b; a Z<> b; a Z< b; a Z>= b; a Z> b; a Z<= b
+;       Built-in NSIS flag tests:
+;         ${Abort}; ${Errors}; ${RebootFlag}; ${Silent}
+;       Built-in NSIS other tests:
+;         ${FileExists} a
+;       Any conditional NSIS instruction test:
+;         ${Cmd} a
+;       Section flag tests:
+;         ${SectionIsSelected} a; ${SectionIsSectionGroup} a;
+;         ${SectionIsSectionGroupEnd} a; ${SectionIsBold} a;
+;         ${SectionIsReadOnly} a; ${SectionIsExpanded} a;
+;         ${SectionIsPartiallySelected} a
+;
+; Examples:
+;   See LogicLib.nsi in the Examples folder for lots of example usage.
+
+!verbose push
+!verbose 3
+!ifndef LOGICLIB_VERBOSITY
+  !define LOGICLIB_VERBOSITY 3
+!endif
+!define _LOGICLIB_VERBOSITY ${LOGICLIB_VERBOSITY}
+!undef LOGICLIB_VERBOSITY
+!verbose ${_LOGICLIB_VERBOSITY}
+
+!ifndef LOGICLIB
+  !define LOGICLIB
+  !define | "'"
+  !define || "' '"
+  !define LOGICLIB_COUNTER 0
+
+  !include Sections.nsh
+
+  !macro _LOGICLIB_TEMP
+    !ifndef _LOGICLIB_TEMP
+      !define _LOGICLIB_TEMP
+      Var /GLOBAL _LOGICLIB_TEMP  ; Temporary variable to aid the more elaborate logic tests
+    !endif
+  !macroend
+
+  !macro LogicLib_JumpToBranch _Jump _Skip
+    StrCmp "" ""  `${_Jump}` ${_Skip}
+  !macroend
+
+  !macro _IncreaseCounter
+    !define /redef /math LOGICLIB_COUNTER `${LOGICLIB_COUNTER}` + 1
+  !macroend
+
+  !macro _PushLogic
+    !insertmacro _PushScope Logic _LogicLib_Label_${LOGICLIB_COUNTER}
+    !insertmacro _IncreaseCounter
+  !macroend
+
+  !macro _PopLogic
+    !insertmacro _PopScope Logic
+  !macroend
+
+  !macro _PushScope Type label
+    !ifdef _${Type}                                       ; If we already have a statement
+      !define _Cur${Type} ${_${Type}}
+      !undef _${Type}
+      !define _${Type} ${label}
+      !define ${_${Type}}Prev${Type} ${_Cur${Type}}       ; Save the current logic
+      !undef _Cur${Type}
+    !else
+      !define _${Type} ${label}                           ; Initialise for first statement
+    !endif
+  !macroend
+
+  !macro _PopScope Type
+    !ifndef _${Type}
+      !error "Cannot use _Pop${Type} without a preceding _Push${Type}"
+    !endif
+    !ifdef ${_${Type}}Prev${Type}                         ; If a previous statment was active then restore it
+      !define _Cur${Type} ${_${Type}}
+      !undef _${Type}
+      !define _${Type} ${${_Cur${Type}}Prev${Type}}
+      !undef ${_Cur${Type}}Prev${Type}
+      !undef _Cur${Type}
+    !else
+      !undef _${Type}
+    !endif
+  !macroend
+
+  ; String tests
+  !macro _== _a _b _t _f
+    StrCmp `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+
+  !macro _!= _a _b _t _f
+    !insertmacro _== `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  ; Case-sensitive string tests
+  !macro _S== _a _b _t _f
+    StrCmpS `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+
+  !macro _S!= _a _b _t _f
+    !insertmacro _S== `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  ; Extra string tests (cannot do these case-sensitively - I tried and lstrcmp still ignored the case)
+  !macro _StrCmpI _a _b _e _l _m
+    !insertmacro _LOGICLIB_TEMP
+    System::Call `kernel32::lstrcmpi(ts, ts) i.s` `${_a}` `${_b}`
+    Pop $_LOGICLIB_TEMP
+    IntCmp $_LOGICLIB_TEMP 0 `${_e}` `${_l}` `${_m}`
+  !macroend
+
+  !macro _S< _a _b _t _f
+    !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
+  !macroend
+
+  !macro _S>= _a _b _t _f
+    !insertmacro _S< `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _S> _a _b _t _f
+    !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _S<= _a _b _t _f
+    !insertmacro _S> `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  ; Integer tests
+  !macro _= _a _b _t _f
+    IntCmp `${_a}` `${_b}` `${_t}` `${_f}` `${_f}`
+  !macroend
+
+  !macro _<> _a _b _t _f
+    !insertmacro _= `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _< _a _b _t _f
+    IntCmp `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
+  !macroend
+
+  !macro _>= _a _b _t _f
+    !insertmacro _< `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _> _a _b _t _f
+    IntCmp `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _<= _a _b _t _f
+    !insertmacro _> `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _& _a _b _t _f
+    !insertmacro _LOGICLIB_TEMP
+    IntOp $_LOGICLIB_TEMP `${_a}` & `${_b}`
+    !insertmacro _<> $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
+  !macroend
+
+  ; Unsigned integer tests (NB: no need for extra equality tests)
+  !macro _U< _a _b _t _f
+    IntCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
+  !macroend
+
+  !macro _U>= _a _b _t _f
+    !insertmacro _U< `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _U> _a _b _t _f
+    IntCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _U<= _a _b _t _f
+    !insertmacro _U> `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  ; Int64 tests
+  !macro _Int64Cmp _a _o _b _t _f
+    !insertmacro _LOGICLIB_TEMP
+    System::Int64Op `${_a}` `${_o}` `${_b}`
+    Pop $_LOGICLIB_TEMP
+    !insertmacro _= $_LOGICLIB_TEMP 0 `${_f}` `${_t}`
+  !macroend
+
+  !macro _L= _a _b _t _f
+    !insertmacro _Int64Cmp `${_a}` = `${_b}` `${_t}` `${_f}`
+  !macroend
+
+  !macro _L<> _a _b _t _f
+    !insertmacro _L= `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _L< _a _b _t _f
+    !insertmacro _Int64Cmp `${_a}` < `${_b}` `${_t}` `${_f}`
+  !macroend
+
+  !macro _L>= _a _b _t _f
+    !insertmacro _L< `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  !macro _L> _a _b _t _f
+    !insertmacro _Int64Cmp `${_a}` > `${_b}` `${_t}` `${_f}`
+  !macroend
+
+  !macro _L<= _a _b _t _f
+    !insertmacro _L> `${_a}` `${_b}` `${_f}` `${_t}`
+  !macroend
+
+  ; ptrdiff_t & size_t tests
+  !macro LogicLib_PtrDiffTest _o _a _b _t _f
+    !if "${NSIS_PTR_SIZE}" <= 4
+      !insertmacro _${_o} `${_a}` `${_b}` `${_t}` `${_f}`
+    !else
+      !insertmacro _L${_o} `${_a}` `${_b}` `${_t}` `${_f}`
+    !endif
+  !macroend
+  !macro _P= _a _b _t _f
+    !insertmacro LogicLib_PtrDiffTest = `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+  !macro _P<> _a _b _t _f
+    !insertmacro LogicLib_PtrDiffTest <> `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+  !macro _P< _a _b _t _f
+    !insertmacro LogicLib_PtrDiffTest < `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+  !macro _P>= _a _b _t _f
+    !insertmacro LogicLib_PtrDiffTest >= `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+  !macro _P> _a _b _t _f
+    !insertmacro LogicLib_PtrDiffTest > `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+  !macro _P<= _a _b _t _f
+    !insertmacro LogicLib_PtrDiffTest <= `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+  !include Util.nsh
+  !macro _Z= _a _b _t _f
+    !insertmacro LogicLib_PtrDiffTest = `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+  !macro _Z<> _a _b _t _f
+    !insertmacro LogicLib_PtrDiffTest <> `${_a}` `${_b}` `${_t}` `${_f}`
+  !macroend
+  !macro _Z< _a _b _t _f
+    !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
+  !macroend
+  !macro _Z>= _a _b _t _f
+    !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_t}` `${_f}` `${_t}`
+  !macroend
+  !macro _Z> _a _b _t _f
+    !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
+  !macroend
+  !macro _Z<= _a _b _t _f
+    !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_t}` `${_t}` `${_f}`
+  !macroend
+
+  ; Flag tests
+  !macro _Abort _a _b _t _f
+    IfAbort `${_t}` `${_f}`
+  !macroend
+  !define Abort `"" Abort ""`
+
+  !macro _Errors _a _b _t _f
+    IfErrors `${_t}` `${_f}`
+  !macroend
+  !define Errors `"" Errors ""`
+
+  !macro _FileExists _a _b _t _f
+    IfFileExists `${_b}` `${_t}` `${_f}`
+  !macroend
+  !define FileExists `"" FileExists`
+
+  !macro _RebootFlag _a _b _t _f
+    IfRebootFlag `${_t}` `${_f}`
+  !macroend
+  !define RebootFlag `"" RebootFlag ""`
+
+  !macro _Silent _a _b _t _f
+    IfSilent `${_t}` `${_f}`
+  !macroend
+  !define Silent `"" Silent ""`
+
+  ; "Any instruction" test
+  !macro _Cmd _a _b _t _f
+    !define _t=${_t}
+    !ifdef _t=                                            ; If no true label then make one
+      !define __t _LogicLib_Label_${LOGICLIB_COUNTER}
+      !insertmacro _IncreaseCounter
+    !else
+      !define __t ${_t}
+    !endif
+    ${_b} ${__t}
+    !define _f=${_f}
+    !ifndef _f=                                           ; If a false label then go there
+      Goto ${_f}
+    !endif
+    !undef _f=${_f}
+    !ifdef _t=                                            ; If we made our own true label then place it
+      ${__t}:
+    !endif
+    !undef __t
+    !undef _t=${_t}
+  !macroend
+  !define Cmd `"" Cmd`
+
+  ; Section flag test
+  !macro _SectionFlagIsSet _a _b _t _f
+    !insertmacro _LOGICLIB_TEMP
+    SectionGetFlags `${_b}` $_LOGICLIB_TEMP
+    IntOp $_LOGICLIB_TEMP $_LOGICLIB_TEMP & `${_a}`
+    !insertmacro _= $_LOGICLIB_TEMP `${_a}` `${_t}` `${_f}`
+  !macroend
+  !define SectionIsSelected `${SF_SELECTED} SectionFlagIsSet`
+  !define SectionIsSubSection `${SF_SUBSEC} SectionFlagIsSet`
+  !define SectionIsSubSectionEnd `${SF_SUBSECEND} SectionFlagIsSet`
+  !define SectionIsSectionGroup `${SF_SECGRP} SectionFlagIsSet`
+  !define SectionIsSectionGroupEnd `${SF_SECGRPEND} SectionFlagIsSet`
+  !define SectionIsBold `${SF_BOLD} SectionFlagIsSet`
+  !define SectionIsReadOnly `${SF_RO} SectionFlagIsSet`
+  !define SectionIsExpanded `${SF_EXPAND} SectionFlagIsSet`
+  !define SectionIsPartiallySelected `${SF_PSELECTED} SectionFlagIsSet`
+
+  !define IfCmd `!insertmacro _IfThen "" Cmd ${|}`
+
+  !macro _If _c _a _o _b
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !insertmacro _PushLogic
+    !define ${_Logic}If
+    !define ${_Logic}Else _LogicLib_ElseLabel_${LOGICLIB_COUNTER} ; Get a label for the Else
+    !insertmacro _IncreaseCounter
+    !define _c=${_c}
+    !ifdef _c=true                                        ; If is true
+      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
+    !else                                                 ; If condition is false
+      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
+    !endif
+    !undef _c=${_c}
+    !verbose pop
+  !macroend
+  !define If     `!insertmacro _If true`
+  !define Unless `!insertmacro _If false`
+  !define IfNot  `!insertmacro _If false`
+
+  !macro _And _c _a _o _b
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _Logic | ${_Logic}If
+      !error "Cannot use And without a preceding If or IfNot/Unless"
+    !endif
+    !ifndef ${_Logic}Else
+      !error "Cannot use And following an Else"
+    !endif
+    !define _c=${_c}
+    !ifdef _c=true                                        ; If is true
+      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
+    !else                                                 ; If condition is false
+      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
+    !endif
+    !undef _c=${_c}
+    !verbose pop
+  !macroend
+  !define AndIf     `!insertmacro _And true`
+  !define AndUnless `!insertmacro _And false`
+  !define AndIfNot  `!insertmacro _And false`
+
+  !macro _Or _c _a _o _b
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _Logic | ${_Logic}If
+      !error "Cannot use Or without a preceding If or IfNot/Unless"
+    !endif
+    !ifndef ${_Logic}Else
+      !error "Cannot use Or following an Else"
+    !endif
+    !define _label _LogicLib_Label_${LOGICLIB_COUNTER}    ; Skip this test as we already
+    !insertmacro _IncreaseCounter
+    Goto ${_label}                                        ; have a successful result
+    ${${_Logic}Else}:                                     ; Place the Else label
+    !undef ${_Logic}Else                                  ; and remove it
+    !define ${_Logic}Else _LogicLib_ElseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new If
+    !insertmacro _IncreaseCounter
+    !define _c=${_c}
+    !ifdef _c=true                                        ; If is true
+      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
+    !else                                                 ; If condition is false
+      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
+    !endif
+    !undef _c=${_c}
+    ${_label}:
+    !undef _label
+    !verbose pop
+  !macroend
+  !define OrIf     `!insertmacro _Or true`
+  !define OrUnless `!insertmacro _Or false`
+  !define OrIfNot  `!insertmacro _Or false`
+
+  !macro _Else
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _Logic | ${_Logic}If
+      !error "Cannot use Else without a preceding If or IfNot/Unless"
+    !endif
+    !ifndef ${_Logic}Else
+      !error "Cannot use Else following an Else"
+    !endif
+    !ifndef ${_Logic}EndIf                                ; First Else for this If?
+      !define ${_Logic}EndIf _LogicLib_EndIfLabel_${LOGICLIB_COUNTER} ; Get a label for the EndIf
+      !insertmacro _IncreaseCounter
+    !endif
+    Goto ${${_Logic}EndIf}                                ; Go to the EndIf
+    ${${_Logic}Else}:                                     ; Place the Else label
+    !undef ${_Logic}Else                                  ; and remove it
+    !verbose pop
+  !macroend
+  !define Else `!insertmacro _Else`
+
+  !macro _ElseIf _c _a _o _b
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${Else}                                               ; Perform the Else
+    !define ${_Logic}Else _LogicLib_ElseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new If
+    !insertmacro _IncreaseCounter
+    !define _c=${_c}
+    !ifdef _c=true                                        ; If is true
+      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
+    !else                                                 ; If condition is false
+      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
+    !endif
+    !undef _c=${_c}
+    !verbose pop
+  !macroend
+  !define ElseIf     `!insertmacro _ElseIf true`
+  !define ElseUnless `!insertmacro _ElseIf false`
+  !define ElseIfNot  `!insertmacro _ElseIf false`
+
+  !macro _EndIf _n
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _Logic | ${_Logic}If
+      !error "Cannot use End${_n} without a preceding If or IfNot/Unless"
+    !endif
+    !ifdef ${_Logic}Else
+      ${${_Logic}Else}:                                   ; Place the Else label
+      !undef ${_Logic}Else                                ; and remove it
+    !endif
+    !ifdef ${_Logic}EndIf
+      ${${_Logic}EndIf}:                                  ; Place the EndIf
+      !undef ${_Logic}EndIf                               ; and remove it
+    !endif
+    !undef ${_Logic}If
+    !insertmacro _PopLogic
+    !verbose pop
+  !macroend
+  !define EndIf     `!insertmacro _EndIf If`
+  !define EndUnless `!insertmacro _EndIf Unless`
+
+  !macro _IfThen _a _o _b _t
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${If} `${_a}` `${_o}` `${_b}`
+      ${_t}
+    ${EndIf}
+    !verbose pop
+  !macroend
+  !define IfThen `!insertmacro _IfThen`
+
+  !macro _IfNotThen _a _o _b _t
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${IfNot} `${_a}` `${_o}` `${_b}`
+      ${_t}
+    ${EndIf}
+    !verbose pop
+  !macroend
+  !define IfNotThen `!insertmacro _IfNotThen`
+
+  !macro _ForEach _v _f _t _o _s
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    StrCpy "${_v}" "${_f}"                                ; Assign the initial value
+    Goto +2                                               ; Skip the loop expression for the first iteration
+    !define _DoLoopExpression `IntOp "${_v}" "${_v}" "${_o}" "${_s}"` ; Define the loop expression
+    !define _o=${_o}
+    !ifdef _o=+                                           ; Check the loop expression operator
+      !define __o >                                       ; to determine the correct loop condition
+    !else ifdef _o=-
+      !define __o <
+    !else
+      !error "Unsupported ForEach step operator (must be + or -)"
+    !endif
+    !undef _o=${_o}
+    !insertmacro _Do For false `${_v}` `${__o}` `${_t}`   ; Let Do do the rest
+    !undef __o
+    !verbose pop
+  !macroend
+  !define ForEach `!insertmacro _ForEach`
+
+  !macro _For _v _f _t
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${ForEach} `${_v}` `${_f}` `${_t}` + 1                ; Pass on to ForEach
+    !verbose pop
+  !macroend
+  !define For `!insertmacro _For`
+
+  !define ExitFor `!insertmacro _Goto ExitFor For`
+
+  !define Next      `!insertmacro _Loop For Next "" "" "" ""`
+
+  !define While     `!insertmacro _Do While true`
+
+  !define ExitWhile `!insertmacro _Goto ExitWhile While`
+
+  !define EndWhile  `!insertmacro _Loop While EndWhile "" "" "" ""`
+
+  !macro _Do _n _c _a _o _b
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !insertmacro _PushLogic
+    !define ${_Logic}${_n} _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the start of the loop
+    !insertmacro _IncreaseCounter
+    ${${_Logic}${_n}}:
+    !insertmacro _PushScope Exit${_n} _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the end of the loop
+    !insertmacro _IncreaseCounter
+    !insertmacro _PushScope Break ${_Exit${_n}}           ; Break goes to the end of the loop
+    !ifdef _DoLoopExpression
+      ${_DoLoopExpression}                                ; Special extra parameter for inserting code
+      !undef _DoLoopExpression                            ; between the Continue label and the loop condition
+    !endif
+    !define _c=${_c}
+    !ifdef _c=                                            ; No starting condition
+      !insertmacro _PushScope Continue _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for Continue at the end of the loop
+      !insertmacro _IncreaseCounter
+    !else
+      !insertmacro _PushScope Continue ${${_Logic}${_n}}  ; Continue goes to the start of the loop
+      !ifdef _c=true                                      ; If is true
+        !insertmacro _${_o} `${_a}` `${_b}` "" ${_Exit${_n}}
+      !else                                               ; If condition is false
+        !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ""
+      !endif
+    !endif
+    !undef _c=${_c}
+    !define ${_Logic}Condition ${_c}                      ; Remember the condition used
+    !verbose pop
+  !macroend
+  !define Do      `!insertmacro _Do Do "" "" "" ""`
+  !define DoWhile `!insertmacro _Do Do true`
+  !define DoUntil `!insertmacro _Do Do false`
+
+  !macro _Goto _n _s
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _${_n}
+      !error "Cannot use ${_n} without a preceding ${_s}"
+    !endif
+    Goto ${_${_n}}
+    !verbose pop
+  !macroend
+  !define ExitDo   `!insertmacro _Goto ExitDo Do`
+
+  !macro _Loop _n _e _c _a _o _b
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _Logic | ${_Logic}${_n}
+      !error "Cannot use ${_e} without a preceding ${_n}"
+    !endif
+    !define _c=${${_Logic}Condition}
+    !ifdef _c=                                            ; If Do had no condition place the Continue label
+      ${_Continue}:
+    !endif
+    !undef _c=${${_Logic}Condition}
+    !define _c=${_c}
+    !ifdef _c=                                            ; No ending condition
+      Goto ${${_Logic}${_n}}
+    !else ifdef _c=true                                   ; If condition is true
+      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}${_n}} ${_Exit${_n}}
+    !else                                                 ; If condition is false
+      !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ${${_Logic}${_n}}
+    !endif
+    !undef _c=${_c}
+    Goto ${_Continue}                                     ; Just to ensure it is referenced at least once
+    Goto ${_Exit${_n}}                                    ; Just to ensure it is referenced at least once
+    ${_Exit${_n}}:                                        ; Place the loop exit point
+    !undef ${_Logic}Condition
+    !insertmacro _PopScope Continue
+    !insertmacro _PopScope Break
+    !insertmacro _PopScope Exit${_n}
+    !undef ${_Logic}${_n}
+    !insertmacro _PopLogic
+    !verbose pop
+  !macroend
+  !define Loop      `!insertmacro _Loop Do Loop "" "" "" ""`
+  !define LoopWhile `!insertmacro _Loop Do LoopWhile true`
+  !define LoopUntil `!insertmacro _Loop Do LoopUntil false`
+
+  !define Continue `!insertmacro _Goto Continue "For or Do or While"`
+  !define Break    `!insertmacro _Goto Break "For or Do or While"`
+
+  !macro _Select _a
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !insertmacro _PushLogic
+    !define ${_Logic}Select `${_a}`                       ; Remember the left hand side of the comparison
+    !verbose pop
+  !macroend
+  !define Select `!insertmacro _Select`
+
+  !macro _Select_CaseElse
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _Logic | ${_Logic}Select
+      !error "Cannot use Case without a preceding Select"
+    !endif
+    !ifdef ${_Logic}EndSelect                             ; This is set only after the first case
+      !ifndef ${_Logic}Else
+        !error "Cannot use Case following a CaseElse"
+      !endif
+      Goto ${${_Logic}EndSelect}                          ; Go to EndSelect (Ends the previous Case)
+      !define /IfNDef _LogicLib_EndSelectLabelUsed_${_Logic}
+      ${${_Logic}Else}:                                   ; Place the Else label
+      !undef ${_Logic}Else                                ; and remove it
+    !else
+      !define ${_Logic}EndSelect _LogicLib_EndSelectLabel_${LOGICLIB_COUNTER} ; Get a label for the EndSelect
+      !insertmacro _IncreaseCounter
+    !endif
+    !verbose pop
+  !macroend
+  !define CaseElse `!insertmacro _CaseElse`
+  !define Case_Else `!insertmacro _CaseElse`              ; Compatibility with 2.2 and earlier
+  !define Default `!insertmacro _CaseElse`                ; For the C-minded
+
+  !macro _Select_Case _a
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${CaseElse}                                           ; Perform the CaseElse
+    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
+    !insertmacro _IncreaseCounter
+    !insertmacro _== `${${_Logic}Select}` `${_a}` "" ${${_Logic}Else}
+    !verbose pop
+  !macroend
+  !define Case `!insertmacro _Case`
+
+  !macro _Case2 _a _b
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${CaseElse}                                           ; Perform the CaseElse
+    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
+    !insertmacro _IncreaseCounter
+    !insertmacro _== `${${_Logic}Select}` `${_a}` +2 ""
+    !insertmacro _== `${${_Logic}Select}` `${_b}` "" ${${_Logic}Else}
+    !verbose pop
+  !macroend
+  !define Case2 `!insertmacro _Case2`
+
+  !macro _Case3 _a _b _c
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${CaseElse}                                           ; Perform the CaseElse
+    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
+    !insertmacro _IncreaseCounter
+    !insertmacro _== `${${_Logic}Select}` `${_a}` +3 ""
+    !insertmacro _== `${${_Logic}Select}` `${_b}` +2 ""
+    !insertmacro _== `${${_Logic}Select}` `${_c}` "" ${${_Logic}Else}
+    !verbose pop
+  !macroend
+  !define Case3 `!insertmacro _Case3`
+
+  !macro _Case4 _a _b _c _d
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${CaseElse}                                           ; Perform the CaseElse
+    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
+    !insertmacro _IncreaseCounter
+    !insertmacro _== `${${_Logic}Select}` `${_a}` +4 ""
+    !insertmacro _== `${${_Logic}Select}` `${_b}` +3 ""
+    !insertmacro _== `${${_Logic}Select}` `${_c}` +2 ""
+    !insertmacro _== `${${_Logic}Select}` `${_d}` "" ${${_Logic}Else}
+    !verbose pop
+  !macroend
+  !define Case4 `!insertmacro _Case4`
+
+  !macro _Case5 _a _b _c _d _e
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    ${CaseElse}                                           ; Perform the CaseElse
+    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
+    !insertmacro _IncreaseCounter
+    !insertmacro _== `${${_Logic}Select}` `${_a}` +5 ""
+    !insertmacro _== `${${_Logic}Select}` `${_b}` +4 ""
+    !insertmacro _== `${${_Logic}Select}` `${_c}` +3 ""
+    !insertmacro _== `${${_Logic}Select}` `${_d}` +2 ""
+    !insertmacro _== `${${_Logic}Select}` `${_e}` "" ${${_Logic}Else}
+    !verbose pop
+  !macroend
+  !define Case5 `!insertmacro _Case5`
+
+  !macro _EndSelect
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _Logic | ${_Logic}Select
+      !error "Cannot use EndSelect without a preceding Select"
+    !endif
+    !ifdef ${_Logic}Else
+      ${${_Logic}Else}:                                   ; Place the Else label
+      !undef ${_Logic}Else                                ; and remove it
+    !endif
+    !ifdef ${_Logic}EndSelect                             ; This won't be set if there weren't any cases
+      !ifdef _LogicLib_EndSelectLabelUsed_${_Logic}                 ; There is no jump to ${${_Logic}EndSelect}: if there is only one Case
+        ${${_Logic}EndSelect}:                            ; Place the EndSelect
+        !undef _LogicLib_EndSelectLabelUsed_${_Logic}
+      !endif
+      !undef ${_Logic}EndSelect                           ; and remove it
+    !endif
+    !undef ${_Logic}Select
+    !insertmacro _PopLogic
+    !verbose pop
+  !macroend
+  !define EndSelect `!insertmacro _EndSelect`
+
+  !macro _Switch _a
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !insertmacro _PushLogic
+    !insertmacro _PushScope Switch ${_Logic}              ; Keep a separate stack for switch data
+    !insertmacro _PushScope Break _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a lable for beyond the end of the switch
+    !insertmacro _IncreaseCounter
+    !define ${_Switch}Var `${_a}`                         ; Remember the left hand side of the comparison
+    !tempfile ${_Switch}Tmp                               ; Create a temporary file
+    !define ${_Logic}Switch _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the end of the switch
+    !insertmacro _IncreaseCounter
+    Goto ${${_Logic}Switch}                               ; and go there
+    !verbose pop
+  !macroend
+  !define Switch `!insertmacro _Switch`
+
+  !macro _Case _a
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifdef _Logic & ${_Logic}Select                       ; Check for an active Select
+      !insertmacro _Select_Case `${_a}`
+    !else ifndef _Switch                                  ; If not then check for an active Switch
+      !error "Cannot use Case without a preceding Select or Switch"
+    !else
+      !define _label _LogicLib_Label_${LOGICLIB_COUNTER}  ; Get a label for this case,
+      !insertmacro _IncreaseCounter
+      ${_label}:                                          ; place it and add it's check to the temp file
+      !appendfile "${${_Switch}Tmp}" `!insertmacro _== $\`${${_Switch}Var}$\` $\`${_a}$\` ${_label} ""$\n`
+      !undef _label
+    !endif
+    !verbose pop
+  !macroend
+
+  !macro _CaseElse
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifdef _Logic & ${_Logic}Select                       ; Check for an active Select
+      !insertmacro _Select_CaseElse
+    !else ifndef _Switch                                  ; If not then check for an active Switch
+      !error "Cannot use Case without a preceding Select or Switch"
+    !else ifdef ${_Switch}Else                            ; Already had a default case?
+      !error "Cannot use CaseElse following a CaseElse"
+    !else
+      !define ${_Switch}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the default case,
+      !insertmacro _IncreaseCounter
+      ${${_Switch}Else}:                                  ; and place it
+    !endif
+    !verbose pop
+  !macroend
+
+  !macro _EndSwitch
+    !verbose push
+    !verbose ${LOGICLIB_VERBOSITY}
+    !ifndef _Logic | ${_Logic}Switch
+      !error "Cannot use EndSwitch without a preceding Switch"
+    !endif
+    Goto ${_Break}                                        ; Skip the jump table
+    ${${_Logic}Switch}:                                   ; Place the end of the switch
+    !undef ${_Logic}Switch
+    !include "${${_Switch}Tmp}"                           ; Include the jump table
+    !delfile "${${_Switch}Tmp}"                           ; and clear it up
+    !ifdef ${_Switch}Else                                 ; Was there a default case?
+      Goto ${${_Switch}Else}                              ; then go there if all else fails
+      !undef ${_Switch}Else
+    !endif
+    !undef ${_Switch}Tmp
+    !undef ${_Switch}Var
+    ${_Break}:                                            ; Place the break label
+    !insertmacro _PopScope Break
+    !insertmacro _PopScope Switch
+    !insertmacro _PopLogic
+    !verbose pop
+  !macroend
+  !define EndSwitch `!insertmacro _EndSwitch`
+
+!endif ; LOGICLIB
+!verbose 3
+!define LOGICLIB_VERBOSITY ${_LOGICLIB_VERBOSITY}
+!undef _LOGICLIB_VERBOSITY
+!verbose pop

+ 526 - 0
assets/nsis/Include/Memento.nsh

@@ -0,0 +1,526 @@
+!verbose push
+!verbose 3
+
+!include LogicLib.nsh
+!include Sections.nsh
+
+!ifndef ___MEMENTO_NSH___
+!define ___MEMENTO_NSH___
+
+#####################################
+### Memento                       ###
+#####################################
+
+/*
+
+Memento is a set of macros that allow installers to remember user selection
+across separate runs of the installer. Currently, it can remember the state
+of sections and mark new sections as bold. In the future, it'll integrate
+InstallOptions and maybe even the Modern UI.
+
+A usage example can be found in `Examples\Memento.nsi`.
+
+*/
+
+#####################################
+### Usage Instructions            ###
+#####################################
+
+/*
+
+1. Declare usage of Memento by including Memento.nsh at the top of the script.
+
+      !include Memento.nsh
+
+2. Define MEMENTO_REGISTRY_ROOT and MEMENTO_REGISTRY_KEY with the a registry key
+   where sections' state should be saved.
+
+      !define MEMENTO_REGISTRY_ROOT HKLM
+      !define MEMENTO_REGISTRY_KEY \
+                Software\Microsoft\Windows\CurrentVersion\Uninstall\MyProgram
+
+3. Replace Section with ${MementoSection} and SectionEnd with ${MementoSectionEnd}
+   for sections that whose state should be remembered by Memento.
+
+   For sections that should be unselected by default, use ${MementoSection}'s
+   brother - ${MementoUnselectedSection}.
+
+   Sections that don't already have an identifier must be assigned one.
+
+   Section identifiers must stay the same across different versions of the
+   installer or their state will be forgotten.
+
+4. Use ${MementoSectionDone} after the last ${MementoSection}.
+
+5. Add a call to ${MementoSectionRestore} to .onInit to restore the state
+   of all sections from the registry.
+
+      Function .onInit
+
+        ${MementoSectionRestore}
+
+      FunctionEnd
+
+6. Add a call to ${MementoSectionSave} to .onInstSuccess to save the state
+   of all sections to the registry.
+
+      Function .onInstSuccess
+
+        ${MementoSectionSave}
+
+      FunctionEnd
+
+7. Tattoo the location of the chosen registry key on your arm.
+
+*/
+
+#####################################
+### User API                      ###
+#####################################
+
+;
+; ${MementoSection}
+;
+;   Defines a section whose state is remembered by Memento.
+;
+;   Usage is similar to Section.
+;
+;     ${MementoSection} "name" "some_id"
+;
+
+!define MementoSection "!insertmacro MementoSection"
+
+;
+; ${MementoSectionEnd}
+;
+;   Ends a section previously opened using ${MementoSection}.
+;
+;   Usage is similar to SectionEnd.
+;
+;     ${MementoSection} "name" "some_id"
+;        # some code...
+;     ${MementoSectionEnd}
+;
+
+;
+; ${MementoUnselectedSection}
+;
+;   Defines a section whose state is remembered by Memento and is
+;   unselected by default.
+;
+;   Usage is similar to Section with the /o switch.
+;
+;     ${MementoUnselectedSection} "name" "some_id"
+;
+
+!define MementoUnselectedSection "!insertmacro MementoUnselectedSection"
+
+;
+; ${MementoSectionEnd}
+;
+;   Ends a section previously opened using ${MementoSection}.
+;
+;   Usage is similar to SectionEnd.
+;
+;     ${MementoSection} "name" "some_id"
+;        # some code...
+;     ${MementoSectionEnd}
+;
+
+!define MementoSectionEnd "!insertmacro MementoSectionEnd"
+
+;
+; ${MementoSectionDone}
+;
+;   Used after all ${MementoSection} have been set.
+;
+;     ${MementoSection} "name1" "some_id1"
+;        # some code...
+;     ${MementoSectionEnd}
+;
+;     ${MementoSection} "name2" "some_id2"
+;        # some code...
+;     ${MementoSectionEnd}
+;
+;     ${MementoSection} "name3" "some_id3"
+;        # some code...
+;     ${MementoSectionEnd}
+;
+;     ${MementoSectionDone}
+;
+
+!define MementoSectionDone "!insertmacro MementoSectionDone"
+
+;
+; ${MementoSectionRestore}
+;
+;   Restores the state of all Memento sections from the registry.
+;
+;   Commonly used in .onInit.
+;
+;     Function .onInit
+;
+;       ${MementoSectionRestore}
+;
+;     FunctionEnd
+;
+
+!define MementoSectionRestore "!insertmacro MementoSectionRestore"
+
+;
+; ${MementoSectionSave}
+;
+;   Saves the state of all Memento sections to the registry.
+;
+;   Commonly used in .onInstSuccess.
+;
+;     Function .onInstSuccess
+;
+;       ${MementoSectionSave}
+;
+;     FunctionEnd
+;
+
+!define MementoSectionSave "!insertmacro MementoSectionSave"
+
+
+#####################################
+### Internal Defines              ###
+#####################################
+
+!define __MementoSectionIndex 1
+
+#####################################
+### Internal Macros               ###
+#####################################
+
+!macro __MementoCheckSettings
+
+  !ifndef MEMENTO_REGISTRY_ROOT | MEMENTO_REGISTRY_KEY
+
+    !error "MEMENTO_REGISTRY_ROOT and MEMENTO_REGISTRY_KEY must be defined before using any of Memento's macros"
+
+  !endif
+
+!macroend
+
+!macro __MementoSection flags name id
+
+  !insertmacro __MementoCheckSettings
+
+  !ifndef __MementoSectionIndex
+
+    !error "MementoSectionDone already used!"
+
+  !endif
+
+  !define __MementoSectionLastSectionId `${id}`
+
+  !verbose pop
+
+  Section ${flags} `${name}` `${id}`
+
+  !verbose push
+  !verbose 3
+
+!macroend
+
+#####################################
+### User Macros                   ###
+#####################################
+
+!macro MementoSection name id
+
+  !verbose push
+  !verbose 3
+
+  !insertmacro __MementoSection "" `${name}` `${id}`
+
+  !verbose pop
+
+!macroend
+
+!macro MementoUnselectedSection name id
+
+  !verbose push
+  !verbose 3
+
+  !insertmacro __MementoSection /o `${name}` `${id}`
+
+  !define __MementoSectionUnselected
+
+  !verbose pop
+
+!macroend
+
+!macro MementoSectionEnd
+
+  SectionEnd
+
+  !verbose push
+  !verbose 3
+
+  !insertmacro __MementoCheckSettings
+
+  !ifndef __MementoSectionIndex
+
+    !error "MementoSectionDone already used!"
+
+  !endif
+
+  !define /MATH __MementoSectionIndexNext \
+      ${__MementoSectionIndex} + 1
+
+  Function __MementoSectionMarkNew${__MementoSectionIndex}
+
+    ClearErrors
+    ReadRegDWORD $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}`
+
+    ${If} ${Errors}
+
+      !insertmacro SetSectionFlag `${${__MementoSectionLastSectionId}}` ${SF_BOLD}
+
+    ${EndIf}
+
+    GetFunctionAddress $0 __MementoSectionMarkNew${__MementoSectionIndexNext}
+    Goto $0
+
+  FunctionEnd
+
+  Function __MementoSectionRestoreStatus${__MementoSectionIndex}
+
+    ClearErrors
+    ReadRegDWORD $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}`
+
+    !ifndef __MementoSectionUnselected
+
+      ${If} ${Errors}
+      ${OrIf} $0 != 0
+
+        !insertmacro SelectSection `${${__MementoSectionLastSectionId}}`
+
+      ${Else}
+
+        !insertmacro UnselectSection `${${__MementoSectionLastSectionId}}`
+
+      ${EndIf}
+
+    !else
+
+      !undef __MementoSectionUnselected
+
+      ${If} ${Errors}
+      ${OrIf} $0 == 0
+
+        !insertmacro UnselectSection `${${__MementoSectionLastSectionId}}`
+
+      ${Else}
+
+        !insertmacro SelectSection `${${__MementoSectionLastSectionId}}`
+
+      ${EndIf}
+
+    !endif
+
+    GetFunctionAddress $0 __MementoSectionRestoreStatus${__MementoSectionIndexNext}
+    Goto $0
+
+  FunctionEnd
+
+  Function __MementoSectionSaveStatus${__MementoSectionIndex}
+
+    ${If} ${SectionIsSelected} `${${__MementoSectionLastSectionId}}`
+
+      WriteRegDWORD ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}` 1
+
+    ${Else}
+
+      WriteRegDWORD ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` `MementoSection_${__MementoSectionLastSectionId}` 0
+
+    ${EndIf}
+
+    GetFunctionAddress $0 __MementoSectionSaveStatus${__MementoSectionIndexNext}
+    Goto $0
+
+  FunctionEnd
+
+  !undef __MementoSectionIndex
+  !define __MementoSectionIndex ${__MementoSectionIndexNext}
+  !undef __MementoSectionIndexNext
+
+  !undef __MementoSectionLastSectionId
+
+  !verbose pop
+
+!macroend
+
+!macro MementoSectionDone
+
+  !verbose push
+  !verbose 3
+
+  !insertmacro __MementoCheckSettings
+
+  Function __MementoSectionMarkNew${__MementoSectionIndex}
+  FunctionEnd
+
+  Function __MementoSectionRestoreStatus${__MementoSectionIndex}
+  FunctionEnd
+
+  Function __MementoSectionSaveStatus${__MementoSectionIndex}
+  FunctionEnd
+
+  !undef __MementoSectionIndex
+
+  !verbose pop
+
+!macroend
+
+!macro MementoSectionRestore
+
+  !verbose push
+  !verbose 3
+
+  !insertmacro __MementoCheckSettings
+
+  Push $0
+  Push $1
+  Push $2
+  Push $3
+
+    # check for first usage
+
+    ClearErrors
+
+    ReadRegStr $0 ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` MementoSectionUsed
+
+    ${If} ${Errors}
+
+      # use script defaults on first run
+      Goto done
+
+    ${EndIf}
+
+    # mark new components in bold
+    
+    Call __MementoSectionMarkNew1
+
+    # mark section groups in bold
+
+    StrCpy $0 0
+    StrCpy $1 ""
+    StrCpy $2 ""
+    StrCpy $3 ""
+
+    loop:
+
+      ClearErrors
+
+      ${If} ${SectionIsBold} $0
+
+        ${If} $1 != ""
+
+          !insertmacro SetSectionFlag $1 ${SF_BOLD}
+
+        ${EndIf}
+
+        ${If} $2 != ""
+
+          !insertmacro SetSectionFlag $2 ${SF_BOLD}
+
+        ${EndIf}
+
+        ${If} $3 != ""
+
+          !insertmacro SetSectionFlag $3 ${SF_BOLD}
+
+        ${EndIf}
+
+      ${ElseIf} ${Errors}
+
+        Goto loop_end
+
+      ${EndIf}
+
+      ${If} ${SectionIsSectionGroup} $0
+
+        ${If} $1 == ""
+
+          StrCpy $1 $0
+
+        ${ElseIf} $2 == ""
+
+          StrCpy $2 $0
+
+        ${ElseIf} $3 == ""
+
+          StrCpy $3 $0
+
+        ${EndIf}
+
+      ${EndIf}
+
+      ${If} ${SectionIsSectionGroupEnd} $0
+
+        ${If} $3 != ""
+
+          StrCpy $3 ""
+
+        ${ElseIf} $2 != ""
+
+          StrCpy $2 ""
+
+        ${ElseIf} $1 != ""
+
+          StrCpy $1 ""
+
+        ${EndIf}
+
+      ${EndIf}
+
+      IntOp $0 $0 + 1
+
+    Goto loop
+    loop_end:
+
+    # restore sections' status
+
+    Call __MementoSectionRestoreStatus1
+
+  # all done
+
+  done:
+
+  Pop $3
+  Pop $2
+  Pop $1
+  Pop $0
+
+  !verbose pop
+
+!macroend
+
+!macro MementoSectionSave
+
+  !verbose push
+  !verbose 3
+
+  !insertmacro __MementoCheckSettings
+
+  Push $0
+
+    WriteRegStr ${MEMENTO_REGISTRY_ROOT} `${MEMENTO_REGISTRY_KEY}` MementoSectionUsed ""
+  
+    Call __MementoSectionSaveStatus1
+
+  Pop $0
+
+  !verbose pop
+
+!macroend
+
+
+
+!endif # ___MEMENTO_NSH___
+
+!verbose pop

+ 469 - 0
assets/nsis/Include/MultiUser.nsh

@@ -0,0 +1,469 @@
+/*
+
+MultiUser.nsh
+
+Installer configuration for multi-user Windows environments
+
+Copyright 2008-2016 Joost Verburg
+
+*/
+
+!ifndef MULTIUSER_INCLUDED
+!define MULTIUSER_INCLUDED
+!verbose push
+!verbose 3
+
+;Standard NSIS header files
+
+!ifdef MULTIUSER_MUI
+  !include MUI2.nsh
+!endif
+!include nsDialogs.nsh
+!include LogicLib.nsh
+!include WinVer.nsh
+!include FileFunc.nsh
+
+;Variables
+
+Var MultiUser.Privileges
+Var MultiUser.InstallMode
+
+;Command line installation mode setting
+
+!ifdef MULTIUSER_INSTALLMODE_COMMANDLINE
+  !include StrFunc.nsh
+  !ifndef StrStr_INCLUDED
+    ${StrStr}
+  !endif
+  !ifndef MULTIUSER_NOUNINSTALL
+    !ifndef UnStrStr_INCLUDED
+      ${UnStrStr}
+    !endif
+  !endif
+  
+  Var MultiUser.Parameters
+  Var MultiUser.Result
+!endif
+
+;Installation folder stored in registry
+
+!ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
+  Var MultiUser.InstDir
+!endif
+
+!ifdef MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY & MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
+  Var MultiUser.DefaultKeyValue
+!endif
+
+;Windows Vista UAC setting
+
+!if "${MULTIUSER_EXECUTIONLEVEL}" == Admin
+  RequestExecutionLevel admin
+  !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
+!else if "${MULTIUSER_EXECUTIONLEVEL}" == Power
+  RequestExecutionLevel admin
+  !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
+!else if "${MULTIUSER_EXECUTIONLEVEL}" == Highest
+  RequestExecutionLevel highest
+  !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
+!else
+  RequestExecutionLevel user
+!endif
+
+/*
+
+Install modes
+
+*/
+
+!macro MULTIUSER_INSTALLMODE_ALLUSERS UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
+
+  ;Install mode initialization - per-machine
+
+  ${ifnot} ${IsNT}
+    ${orif} $MultiUser.Privileges == "Admin"
+    ${orif} $MultiUser.Privileges == "Power"
+  
+    StrCpy $MultiUser.InstallMode AllUsers
+  
+    SetShellVarContext all
+  
+    !if "${UNINSTALLER_PREFIX}" != UN
+      ;Set default installation location for installer
+      !ifdef MULTIUSER_INSTALLMODE_INSTDIR
+        StrCpy $INSTDIR "$PROGRAMFILES\${MULTIUSER_INSTALLMODE_INSTDIR}"
+      !endif
+    !endif
+  
+    !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
+  
+      ReadRegStr $MultiUser.InstDir HKLM "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}"
+  
+      ${if} $MultiUser.InstDir != ""
+        StrCpy $INSTDIR $MultiUser.InstDir
+      ${endif}
+  
+    !endif
+  
+    !ifdef MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION
+      Call "${MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION}"
+    !endif
+    
+  ${endif}
+
+!macroend
+
+!macro MULTIUSER_INSTALLMODE_CURRENTUSER UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
+
+  ;Install mode initialization - per-user
+  
+  ${if} ${IsNT}  
+  
+    StrCpy $MultiUser.InstallMode CurrentUser
+    
+    SetShellVarContext current
+  
+    !if "${UNINSTALLER_PREFIX}" != UN
+      ;Set default installation location for installer  
+      !ifdef MULTIUSER_INSTALLMODE_INSTDIR
+        ${if} ${AtLeastWin2000}
+          StrCpy $INSTDIR "$LOCALAPPDATA\${MULTIUSER_INSTALLMODE_INSTDIR}"
+        ${else}
+          StrCpy $INSTDIR "$PROGRAMFILES\${MULTIUSER_INSTALLMODE_INSTDIR}"
+        ${endif}
+      !endif
+    !endif
+  
+    !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
+  
+      ReadRegStr $MultiUser.InstDir HKCU "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}"
+  
+      ${if} $MultiUser.InstDir != ""
+        StrCpy $INSTDIR $MultiUser.InstDir
+      ${endif}
+  
+    !endif
+  
+    !ifdef MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION
+      Call "${MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION}"
+    !endif
+  
+  ${endif}
+
+!macroend
+
+Function MultiUser.InstallMode.AllUsers
+  !insertmacro MULTIUSER_INSTALLMODE_ALLUSERS "" ""
+FunctionEnd
+
+Function MultiUser.InstallMode.CurrentUser
+  !insertmacro MULTIUSER_INSTALLMODE_CURRENTUSER "" ""
+FunctionEnd
+
+!ifndef MULTIUSER_NOUNINSTALL
+
+Function un.MultiUser.InstallMode.AllUsers
+  !insertmacro MULTIUSER_INSTALLMODE_ALLUSERS UN .un
+FunctionEnd
+
+Function un.MultiUser.InstallMode.CurrentUser
+  !insertmacro MULTIUSER_INSTALLMODE_CURRENTUSER UN .un
+FunctionEnd
+
+!endif
+
+/*
+
+Installer/uninstaller initialization
+
+*/
+
+!macro MULTIUSER_INIT_QUIT UNINSTALLER_FUNCPREFIX
+
+  !ifdef MULTIUSER_INIT_${UNINSTALLER_FUNCPREFIX}FUNCTIONQUIT
+    Call "${MULTIUSER_INIT_${UNINSTALLER_FUNCPREFIX}FUCTIONQUIT}
+  !else
+    Quit
+  !endif
+
+!macroend
+
+!macro MULTIUSER_INIT_TEXTS
+
+  !ifndef MULTIUSER_INIT_TEXT_ADMINREQUIRED
+    !define MULTIUSER_INIT_TEXT_ADMINREQUIRED "$(^Caption) requires administrator privileges."
+  !endif
+
+  !ifndef MULTIUSER_INIT_TEXT_POWERREQUIRED
+    !define MULTIUSER_INIT_TEXT_POWERREQUIRED "$(^Caption) requires at least Power User privileges."
+  !endif
+
+  !ifndef MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE
+    !define MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE "Your user account does not have sufficient privileges to install $(^Name) for all users of this computer."
+  !endif
+
+!macroend
+
+!macro MULTIUSER_INIT_CHECKS UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
+
+  ;Installer initialization - check privileges and set install mode
+
+  !insertmacro MULTIUSER_INIT_TEXTS
+
+  UserInfo::GetAccountType
+  Pop $MultiUser.Privileges
+  
+  ${if} ${IsNT}
+  
+    ;Check privileges
+  
+    !if "${MULTIUSER_EXECUTIONLEVEL}" == Admin
+  
+      ${if} $MultiUser.Privileges != "Admin"
+        MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
+        !insertmacro MULTIUSER_INIT_QUIT "${UNINSTALLER_FUNCPREFIX}"
+      ${endif}
+  
+    !else if "${MULTIUSER_EXECUTIONLEVEL}" == Power
+  
+      ${if} $MultiUser.Privileges != "Power"
+        ${andif} $MultiUser.Privileges != "Admin"
+        ${if} ${AtMostWinXP}
+           MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_POWERREQUIRED}"
+        ${else}
+           MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
+        ${endif}        
+        !insertmacro MULTIUSER_INIT_QUIT "${UNINSTALLER_FUNCPREFIX}"
+      ${endif}
+  
+    !endif
+    
+    !ifdef MULTIUSER_EXECUTIONLEVEL_ALLUSERS
+    
+      ;Default to per-machine installation if possible
+    
+      ${if} $MultiUser.Privileges == "Admin"
+        ${orif} $MultiUser.Privileges == "Power"
+        !ifndef MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
+          Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
+        !else
+          Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
+        !endif
+
+        !ifdef MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY & MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
+
+          ;Set installation mode to setting from a previous installation
+
+          !ifndef MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
+            ReadRegStr $MultiUser.DefaultKeyValue HKLM "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
+            ${if} $MultiUser.DefaultKeyValue == ""
+              ReadRegStr $MultiUser.DefaultKeyValue HKCU "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
+              ${if} $MultiUser.DefaultKeyValue != ""
+                Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
+              ${endif}
+            ${endif}
+          !else
+            ReadRegStr $MultiUser.DefaultKeyValue HKCU "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
+            ${if} $MultiUser.DefaultKeyValue == ""
+              ReadRegStr $MultiUser.DefaultKeyValue HKLM "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
+              ${if} $MultiUser.DefaultKeyValue != ""
+                Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
+              ${endif}
+            ${endif}
+          !endif
+
+        !endif
+
+      ${else}
+        Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
+      ${endif}
+    
+    !else
+
+      Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
+
+    !endif  
+  
+    !ifdef MULTIUSER_INSTALLMODE_COMMANDLINE
+    
+      ;Check for install mode setting on command line
+
+      ${${UNINSTALLER_FUNCPREFIX}GetParameters} $MultiUser.Parameters
+  
+      ${${UNINSTALLER_PREFIX}StrStr} $MultiUser.Result $MultiUser.Parameters "/CurrentUser"    
+    
+      ${if} $MultiUser.Result != ""
+        Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
+      ${endif}    
+  
+      ${${UNINSTALLER_PREFIX}StrStr} $MultiUser.Result $MultiUser.Parameters "/AllUsers"    
+    
+      ${if} $MultiUser.Result != ""
+        ${if} $MultiUser.Privileges == "Admin"
+          ${orif} $MultiUser.Privileges == "Power"
+          Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
+        ${else}
+          MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE}"
+        ${endif}
+      ${endif}
+  
+    !endif
+    
+  ${else}
+  
+    ;Not running Windows NT, per-user installation not supported
+    
+    Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
+  
+  ${endif}
+
+!macroend
+
+!macro MULTIUSER_INIT
+  !verbose push
+  !verbose 3
+  
+  !insertmacro MULTIUSER_INIT_CHECKS "" ""
+  
+  !verbose pop 
+!macroend
+
+!ifndef MULTIUSER_NOUNINSTALL
+
+!macro MULTIUSER_UNINIT
+  !verbose push
+  !verbose 3
+  
+  !insertmacro MULTIUSER_INIT_CHECKS Un un.
+  
+  !verbose pop 
+!macroend
+
+!endif
+
+/*
+
+Modern UI 2 page
+
+*/
+
+!ifdef MULTIUSER_MUI
+
+!macro MULTIUSER_INSTALLMODEPAGE_INTERFACE
+
+  !ifndef MULTIUSER_INSTALLMODEPAGE_INTERFACE
+    !define MULTIUSER_INSTALLMODEPAGE_INTERFACE
+    Var MultiUser.InstallModePage
+    
+    Var MultiUser.InstallModePage.Text
+    
+    Var MultiUser.InstallModePage.AllUsers
+    Var MultiUser.InstallModePage.CurrentUser
+    
+    Var MultiUser.InstallModePage.ReturnValue
+  !endif
+
+!macroend
+
+!macro MULTIUSER_PAGEDECLARATION_INSTALLMODE
+
+  !insertmacro MUI_SET MULTIUSER_${MUI_PAGE_UNINSTALLER_PREFIX}INSTALLMODEPAGE ""
+  !insertmacro MULTIUSER_INSTALLMODEPAGE_INTERFACE
+
+  !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_TOP "$(MULTIUSER_INNERTEXT_INSTALLMODE_TOP)"
+  !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS "$(MULTIUSER_INNERTEXT_INSTALLMODE_ALLUSERS)"
+  !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER "$(MULTIUSER_INNERTEXT_INSTALLMODE_CURRENTUSER)"  
+
+  PageEx custom
+
+    PageCallbacks MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
+
+    Caption " "
+
+  PageExEnd
+
+  !insertmacro MULTIUSER_FUNCTION_INSTALLMODEPAGE MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
+
+  !undef MULTIUSER_INSTALLMODEPAGE_TEXT_TOP
+  !undef MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS
+  !undef MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER
+
+!macroend
+
+!macro MULTIUSER_PAGE_INSTALLMODE
+
+  ;Modern UI page for install mode
+
+  !verbose push
+  !verbose 3
+  
+  !ifndef MULTIUSER_EXECUTIONLEVEL_ALLUSERS
+    !error "A mixed-mode installation requires MULTIUSER_EXECUTIONLEVEL to be set to Admin, Power or Highest."
+  !endif
+  
+  !insertmacro MUI_PAGE_INIT
+  !insertmacro MULTIUSER_PAGEDECLARATION_INSTALLMODE
+  
+  !verbose pop
+
+!macroend
+
+!macro MULTIUSER_FUNCTION_INSTALLMODEPAGE PRE LEAVE
+
+  ;Page functions of Modern UI page
+
+  Function "${PRE}"
+  
+    ${ifnot} ${IsNT}
+      Abort
+    ${endif}
+  
+    ${if} $MultiUser.Privileges != "Power"
+      ${andif} $MultiUser.Privileges != "Admin"
+      Abort
+    ${endif}
+    
+    !insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE
+    !insertmacro MUI_HEADER_TEXT_PAGE $(MULTIUSER_TEXT_INSTALLMODE_TITLE) $(MULTIUSER_TEXT_INSTALLMODE_SUBTITLE)
+    
+    nsDialogs::Create 1018
+    Pop $MultiUser.InstallModePage
+
+    ${NSD_CreateLabel} 0u 0u 300u 20u "${MULTIUSER_INSTALLMODEPAGE_TEXT_TOP}"
+    Pop $MultiUser.InstallModePage.Text
+
+    ${NSD_CreateRadioButton} 20u 50u 280u 10u "${MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS}"
+    Pop $MultiUser.InstallModePage.AllUsers
+    
+    ${NSD_CreateRadioButton} 20u 70u 280u 10u "${MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER}"
+    Pop $MultiUser.InstallModePage.CurrentUser
+    
+    ${if} $MultiUser.InstallMode == "AllUsers"
+      SendMessage $MultiUser.InstallModePage.AllUsers ${BM_SETCHECK} ${BST_CHECKED} 0
+    ${else}
+      SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_SETCHECK} ${BST_CHECKED} 0
+    ${endif}
+    
+    !insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOW
+    nsDialogs::Show
+    
+  FunctionEnd
+
+  Function "${LEAVE}"
+     SendMessage $MultiUser.InstallModePage.AllUsers ${BM_GETCHECK} 0 0 $MultiUser.InstallModePage.ReturnValue
+     
+     ${if} $MultiUser.InstallModePage.ReturnValue = ${BST_CHECKED}
+        Call MultiUser.InstallMode.AllUsers
+     ${else}
+        Call MultiUser.InstallMode.CurrentUser
+     ${endif}
+  
+    !insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVE
+  FunctionEnd
+
+!macroend
+
+!endif
+
+!verbose pop
+!endif

+ 310 - 0
assets/nsis/Include/Sections.nsh

@@ -0,0 +1,310 @@
+; Sections.nsh
+;
+; Defines and macros for section control
+;
+; Include in your script using:
+; !include "Sections.nsh"
+
+;--------------------------------
+
+!ifndef SECTIONS_INCLUDED
+
+!define SECTIONS_INCLUDED
+
+;--------------------------------
+
+; Generic section defines
+
+# section or section group is selected
+!define SF_SELECTED   1
+# section group
+!define SF_SECGRP     2
+!define SF_SUBSEC     2  # deprecated
+# section group end marker
+!define SF_SECGRPEND  4
+!define SF_SUBSECEND  4  # deprecated
+# bold text (Section !blah)
+!define SF_BOLD       8
+# read only (SectionIn RO)
+!define SF_RO         16
+# expanded section group (SectionGroup /e blah)
+!define SF_EXPAND     32
+# section group is partially selected
+!define SF_PSELECTED  64  # internal
+# internal
+!define SF_TOGGLED    128 # internal
+!define SF_NAMECHG    256 # internal
+
+# mask to toggle off the selected flag
+!define SECTION_OFF   0xFFFFFFFE
+
+;--------------------------------
+
+; Select / unselect / reserve section
+
+!macro SelectSection SECTION
+
+  Push $0
+  Push $1
+    StrCpy $1 "${SECTION}"
+    SectionGetFlags $1 $0
+    IntOp $0 $0 | ${SF_SELECTED}
+    SectionSetFlags $1 $0
+  Pop $1
+  Pop $0
+
+!macroend
+
+!macro UnselectSection SECTION
+
+  Push $0
+  Push $1
+    StrCpy $1 "${SECTION}"
+    SectionGetFlags $1 $0
+    IntOp $0 $0 & ${SECTION_OFF}
+    SectionSetFlags $1 $0
+  Pop $1
+  Pop $0
+
+!macroend
+
+; If section selected, will unselect, if unselected, will select
+
+!macro ReverseSection SECTION
+
+  Push $0
+  Push $1
+    StrCpy $1 "${SECTION}"
+    SectionGetFlags $1 $0
+    IntOp $0 $0 ^ ${SF_SELECTED}
+    SectionSetFlags $1 $0
+  Pop $1
+  Pop $0
+
+!macroend
+
+;--------------------------------
+
+; Macros for mutually exclusive section selection
+; Written by Tim Gallagher
+;
+; See one-section.nsi for an example of usage
+
+; Starts the Radio Button Block
+; You should pass a variable that keeps the selected section
+; as the first parameter for this macro. This variable should
+; be initialized to the default section's index.
+;
+; As this macro uses $R0 and $R1 you can't use those two as the
+; varible which will keep the selected section.
+
+!macro StartRadioButtons var
+
+  !define StartRadioButtons_Var "${var}"
+
+  Push $R0
+  
+   SectionGetFlags "${StartRadioButtons_Var}" $R0
+   IntOp $R0 $R0 & ${SECTION_OFF}
+   SectionSetFlags "${StartRadioButtons_Var}" $R0
+   
+  Push $R1
+  
+    StrCpy $R1 "${StartRadioButtons_Var}"
+   
+!macroend
+
+; A radio button
+
+!macro RadioButton SECTION_NAME
+
+  SectionGetFlags ${SECTION_NAME} $R0
+  IntOp $R0 $R0 & ${SF_SELECTED}
+  IntCmp $R0 ${SF_SELECTED} 0 +2 +2
+  StrCpy "${StartRadioButtons_Var}" ${SECTION_NAME}
+
+!macroend
+
+; Ends the radio button block
+
+!macro EndRadioButtons
+  
+  StrCmp $R1 "${StartRadioButtons_Var}" 0 +4 ; selection hasn't changed
+    SectionGetFlags "${StartRadioButtons_Var}" $R0
+    IntOp $R0 $R0 | ${SF_SELECTED}
+    SectionSetFlags "${StartRadioButtons_Var}" $R0
+
+  Pop $R1
+  Pop $R0
+  
+  !undef StartRadioButtons_Var
+
+!macroend
+
+;--------------------------------
+
+; These are two macros you can use to set a Section in an InstType
+; or clear it from an InstType.
+;
+; Written by Robert Kehl
+;
+; For details, see http://nsis.sourceforge.net/wiki/SetSectionInInstType%2C_ClearSectionInInstType
+;
+; Use the defines below for the WANTED_INSTTYPE parameter.
+
+!define INSTTYPE_1 1
+!define INSTTYPE_2 2
+!define INSTTYPE_3 4
+!define INSTTYPE_4 8
+!define INSTTYPE_5 16
+!define INSTTYPE_6 32
+!define INSTTYPE_7 64
+!define INSTTYPE_8 128
+!define INSTTYPE_9 256
+!define INSTTYPE_10 512
+!define INSTTYPE_11 1024
+!define INSTTYPE_12 2048
+!define INSTTYPE_13 4096
+!define INSTTYPE_14 8192
+!define INSTTYPE_15 16384
+!define INSTTYPE_16 32768
+!define INSTTYPE_17 65536
+!define INSTTYPE_18 131072
+!define INSTTYPE_19 262144
+!define INSTTYPE_20 524288
+!define INSTTYPE_21 1048576
+!define INSTTYPE_22 2097152
+!define INSTTYPE_23 4194304
+!define INSTTYPE_24 8388608
+!define INSTTYPE_25 16777216
+!define INSTTYPE_26 33554432
+!define INSTTYPE_27 67108864
+!define INSTTYPE_28 134217728
+!define INSTTYPE_29 268435456
+!define INSTTYPE_30 536870912
+!define INSTTYPE_31 1073741824
+!define INSTTYPE_32 2147483648
+
+!macro SetSectionInInstType SECTION_NAME WANTED_INSTTYPE
+
+  Push $0
+  Push $1
+    StrCpy $1 "${SECTION_NAME}"
+    SectionGetInstTypes $1 $0
+    IntOp $0 $0 | ${WANTED_INSTTYPE}
+    SectionSetInstTypes $1 $0
+  Pop $1
+  Pop $0
+
+!macroend
+
+!macro ClearSectionInInstType SECTION_NAME WANTED_INSTTYPE
+
+  Push $0
+  Push $1
+  Push $2
+    StrCpy $2 "${SECTION_NAME}"
+    SectionGetInstTypes $2 $0
+    StrCpy $1 ${WANTED_INSTTYPE}
+    IntOp $1 $1 ~
+    IntOp $0 $0 & $1
+    SectionSetInstTypes $2 $0
+  Pop $2
+  Pop $1
+  Pop $0
+
+!macroend
+
+;--------------------------------
+
+; Set / clear / check bits in a section's flags
+; Written by derekrprice
+
+; Set one or more bits in a sections's flags
+
+!macro SetSectionFlag SECTION BITS
+
+  Push $R0
+  Push $R1
+    StrCpy $R1 "${SECTION}"
+    SectionGetFlags $R1 $R0
+    IntOp $R0 $R0 | "${BITS}"
+    SectionSetFlags $R1 $R0
+  Pop $R1
+  Pop $R0
+ 
+!macroend
+
+; Clear one or more bits in section's flags
+
+!macro ClearSectionFlag SECTION BITS
+
+  Push $R0
+  Push $R1
+  Push $R2
+    StrCpy $R2 "${SECTION}"
+    SectionGetFlags $R2 $R0
+    IntOp $R1 "${BITS}" ~
+    IntOp $R0 $R0 & $R1
+    SectionSetFlags $R2 $R0
+  Pop $R2
+  Pop $R1
+  Pop $R0
+
+!macroend
+
+; Check if one or more bits in section's flags are set
+; If they are, jump to JUMPIFSET
+; If not, jump to JUMPIFNOTSET
+
+!macro SectionFlagIsSet SECTION BITS JUMPIFSET JUMPIFNOTSET
+	Push $R0
+	SectionGetFlags "${SECTION}" $R0
+	IntOp $R0 $R0 & "${BITS}"
+	IntCmp $R0 "${BITS}" +3
+	Pop $R0
+	StrCmp "" "${JUMPIFNOTSET}" +3 "${JUMPIFNOTSET}"
+	Pop $R0
+	Goto "${JUMPIFSET}"
+!macroend
+
+;--------------------------------
+
+; Removes a section by unselecting and hiding it
+
+!macro RemoveSection SECTION
+
+  Push $R0
+  Push $R1
+    StrCpy $R1 `${SECTION}`
+    SectionGetFlags $R1 $R0
+    IntOp $R0 $R0 & ${SECTION_OFF}
+    SectionSetFlags $R1 $R0
+    SectionSetText $R1 ``
+  Pop $R1
+  Pop $R0
+
+!macroend
+
+; Undoes the RemoveSection action
+
+!macro UnremoveSection SECTION SECTION_TEXT
+
+  Push $R0
+  Push $R1
+  Push $R2
+    StrCpy $R1 `${SECTION}`
+    StrCpy $R2 `${SECTION_TEXT}`
+    SectionGetFlags $R1 $R0
+    IntOp $R0 $R0 | ${SF_SELECTED}
+    SectionSetFlags $R1 $R0
+    SectionSetText $R1 $R2
+  Pop $R2
+  Pop $R1
+  Pop $R0
+
+!macroend
+
+;--------------------------------
+
+!endif

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1760 - 0
assets/nsis/Include/StrFunc.nsh


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1211 - 0
assets/nsis/Include/TextFunc.nsh


+ 203 - 0
assets/nsis/Include/UpgradeDLL.nsh

@@ -0,0 +1,203 @@
+/*
+
+NOTE:
+-----
+This macro is provided for backwards compatibility with NSIS 2.0 scripts.
+It's recommended you update your scripts to use the new Library.nsh macros.
+
+
+Macro - Upgrade DLL File
+Written by Joost Verburg
+------------------------
+
+Parameters:
+LOCALFILE		Location of the new DLL file (on the compiler system)
+DESTFILE		Location of the DLL file that should be upgraded (on the user's system)
+TEMPBASEDIR		Directory on the user's system to store a temporary file when the system has
+				to be rebooted.
+				For Win9x/ME support, this should be on the same volume as DESTFILE.
+				The Windows temp directory could be located on any volume, so you cannot use
+				this directory.
+
+Define UPGRADEDLL_NOREGISTER if you want to upgrade a DLL that does not have to be registered.
+
+Notes:
+
+* If you want to support Windows 9x/ME, you can only use short filenames (8.3).
+
+* This macro uses the GetDLLVersionLocal command to retrieve the version of local libraries.
+  This command is only supported when compiling on a Windows system.
+
+------------------------
+
+Example:
+
+!insertmacro UpgradeDLL "dllname.dll" "$SYSDIR\dllname.dll" "$SYSDIR"
+
+*/
+
+!ifndef UPGRADEDLL_INCLUDED
+
+!define UPGRADEDLL_INCLUDED
+
+!macro __UpgradeDLL_Helper_AddRegToolEntry mode filename tempdir
+
+  Push $R0
+  Push $R1
+  Push $R2
+  Push $R3
+
+  ;------------------------
+  ;Copy the parameters
+
+  Push "${filename}"
+  Push "${tempdir}"
+
+  Pop $R2 ; temporary directory
+  Pop $R1 ; file name to register
+
+  ;------------------------
+  ;Advance counter
+
+  StrCpy $R0 0
+  ReadRegDWORD $R0 HKLM "Software\NSIS.Library.RegTool.v2\UpgradeDLLSession" "count"
+  IntOp $R0 $R0 + 1
+  WriteRegDWORD HKLM "Software\NSIS.Library.RegTool.v2\UpgradeDLLSession" "count" "$R0"
+
+  ;------------------------
+  ;Setup RegTool
+
+  ReadRegStr $R3 HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" "NSIS.Library.RegTool.v2"
+  StrCpy $R3 $R3 -4 1
+  IfFileExists $R3 +3
+
+    File /oname=$R2\NSIS.Library.RegTool.v2.$HWNDPARENT.exe "${NSISDIR}\Bin\RegTool.bin"
+    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
+      "NSIS.Library.RegTool.v2" '"$R2\NSIS.Library.RegTool.v2.$HWNDPARENT.exe" /S'
+
+  ;------------------------
+  ;Add RegTool entry
+
+  WriteRegStr HKLM "Software\NSIS.Library.RegTool.v2\UpgradeDLLSession" "$R0.file" "$R1"
+  WriteRegStr HKLM "Software\NSIS.Library.RegTool.v2\UpgradeDLLSession" "$R0.mode" "${mode}"
+
+  Pop $R3
+  Pop $R2
+  Pop $R1
+  Pop $R0
+
+!macroend
+
+!macro UpgradeDLL LOCALFILE DESTFILE TEMPBASEDIR
+
+  Push $R0
+  Push $R1
+  Push $R2
+  Push $R3
+  Push $R4
+  Push $R5
+
+  !define UPGRADEDLL_UNIQUE "${__FILE__}${__LINE__}"
+
+  SetOverwrite try
+
+  ;------------------------
+  ;Copy the macro parameters to a run-time to a variable, 
+  ;this allows the usage of variables as parameter
+
+  StrCpy $R4 "${DESTFILE}"
+  StrCpy $R5 "${TEMPBASEDIR}"
+
+  ;------------------------
+  ;Get version information
+
+  IfFileExists $R4 0 "upgradedll.copy_${UPGRADEDLL_UNIQUE}"
+
+  ClearErrors
+    GetDLLVersionLocal "${LOCALFILE}" $R0 $R1
+    GetDLLVersion $R4 $R2 $R3
+  IfErrors "upgradedll.upgrade_${UPGRADEDLL_UNIQUE}"
+
+  IntCmpU $R0 $R2 0 "upgradedll.done_${UPGRADEDLL_UNIQUE}" "upgradedll.upgrade_${UPGRADEDLL_UNIQUE}"
+  IntCmpU $R1 $R3 "upgradedll.done_${UPGRADEDLL_UNIQUE}" "upgradedll.done_${UPGRADEDLL_UNIQUE}" \
+    "upgradedll.upgrade_${UPGRADEDLL_UNIQUE}"
+
+  ;------------------------
+  ;Upgrade
+
+  "upgradedll.upgrade_${UPGRADEDLL_UNIQUE}:"
+    !ifndef UPGRADEDLL_NOREGISTER
+      ;Unregister the DLL
+      UnRegDLL $R4
+    !endif
+
+  ;------------------------
+  ;Copy
+
+  ClearErrors
+    StrCpy $R0 $R4
+    Call ":upgradedll.file_${UPGRADEDLL_UNIQUE}"
+  IfErrors 0 "upgradedll.noreboot_${UPGRADEDLL_UNIQUE}"
+
+  ;------------------------
+  ;Copy on reboot
+
+  GetTempFileName $R0 $R5
+    Call ":upgradedll.file_${UPGRADEDLL_UNIQUE}"
+  Rename /REBOOTOK $R0 $R4
+
+  ;------------------------
+  ;Register on reboot
+
+  !insertmacro __UpgradeDLL_Helper_AddRegToolEntry 'D' $R4 $R5
+
+  Goto "upgradedll.done_${UPGRADEDLL_UNIQUE}"
+
+  ;------------------------
+  ;DLL does not exist
+
+  "upgradedll.copy_${UPGRADEDLL_UNIQUE}:"
+    StrCpy $R0 $R4
+    Call ":upgradedll.file_${UPGRADEDLL_UNIQUE}"
+
+  ;------------------------
+  ;Register
+
+  "upgradedll.noreboot_${UPGRADEDLL_UNIQUE}:"
+    !ifndef UPGRADEDLL_NOREGISTER
+      RegDLL $R4
+    !endif
+
+  ;------------------------
+  ;Done
+
+  "upgradedll.done_${UPGRADEDLL_UNIQUE}:"
+
+  Pop $R5
+  Pop $R4
+  Pop $R3
+  Pop $R2
+  Pop $R1
+  Pop $R0
+
+  ;------------------------
+  ;End
+
+  Goto "upgradedll.end_${UPGRADEDLL_UNIQUE}"
+
+  ;------------------------
+  ;Extract
+
+  "upgradedll.file_${UPGRADEDLL_UNIQUE}:"
+    File /oname=$R0 "${LOCALFILE}"
+    Return
+
+  "upgradedll.end_${UPGRADEDLL_UNIQUE}:"
+
+  SetOverwrite lastused
+  
+  !undef UPGRADEDLL_UNIQUE
+
+!macroend
+
+!endif

+ 173 - 0
assets/nsis/Include/Util.nsh

@@ -0,0 +1,173 @@
+; ---------------------
+;       Util.nsh
+; ---------------------
+;
+; Voodoo macros to make end-user usage easier. This may be documented someday.
+
+!verbose push 3
+!ifndef ___UTIL__NSH___
+!define ___UTIL__NSH___
+
+# CallArtificialFunction, see WinVer.nsh and *Func.nsh for usage examples
+!macro CallArtificialFunctionHelper TYPE NAME
+  !verbose pop
+  Call :.${NAME}${TYPE}
+  !ifndef ${NAME}${TYPE}_DEFINED
+    !verbose push 2
+    Goto ${NAME}${TYPE}_DONE
+    !define ${NAME}${TYPE}_DEFINED
+    !verbose pop
+    .${NAME}${TYPE}:
+      !insertmacro ${NAME}
+      Return
+    ${NAME}${TYPE}_DONE:
+  !endif
+  !verbose push 2
+!macroend
+
+!macro CallArtificialFunction NAME
+  !verbose push 2
+  !ifdef __UNINSTALL__
+    !insertmacro CallArtificialFunctionHelper uninst ${NAME}
+  !else
+    !insertmacro CallArtificialFunctionHelper inst ${NAME}
+  !endif
+  !verbose pop
+!macroend
+!define CallArtificialFunction `!insertmacro CallArtificialFunction`
+
+!macro CallArtificialFunction2 NAME ; Retained for v2.4x..v3.0b0 compatibility
+  ${CallArtificialFunction} ${NAME}
+!macroend
+!define CallArtificialFunction2 `!insertmacro CallArtificialFunction`
+
+
+!define Int32Op '!insertmacro Int32Op '
+!define Int64Op '!insertmacro Int64Op '
+!define IntPtrOp '!insertmacro IntPtrOp '
+!macro Int32Op r a o b
+!if ${NSIS_PTR_SIZE} <= 4
+  IntOp `${r}` `${a}` `${o}` ${b}
+!else
+  !error "Int32Op not implemented"
+!endif
+!macroend
+!macro Int64Op r a o b
+!echo "Int64Op ${r}=${a}${o}${b}"
+!verbose push 2
+System::Int64Op `${a}` `${o}` ${b}
+Pop ${r}
+!verbose pop
+!macroend
+!macro IntPtrOp r a o b
+!if ${NSIS_PTR_SIZE} <= 4
+  ${Int32Op} `${r}` `${a}` `${o}` `${b}`
+!else
+  ${Int64Op} `${r}` `${a}` `${o}` `${b}`
+!endif
+!macroend
+
+!define Int32Cmp '!insertmacro Int32Cmp '
+!define Int64Cmp '!insertmacro Int64Cmp '
+!define IntPtrCmp '!insertmacro IntPtrCmp '
+!macro Int32Cmp a b jeek jles jgtr
+!if ${NSIS_PTR_SIZE} <= 4
+  IntCmp `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
+!else
+  !error "Int32Cmp not implemented"
+!endif
+!macroend
+!macro Int64Cmp a b jeek jles jgtr
+!ifmacrondef _LOGICLIB_TEMP
+!include LogicLib.nsh
+!endif
+!echo "Int64Cmp ${a}:${b} =${jeek}, <${jles}, >${jgtr}"
+!verbose push 2
+${IfThen} ${a} L= ${b} ${|} Goto ${jeek} ${|}
+!insertmacro _L< ${a} ${b} `${jles}` `${jgtr}`
+!verbose pop
+!macroend
+!macro IntPtrCmp a b jeek jles jgtr
+!if ${NSIS_PTR_SIZE} <= 4
+  ${Int32Cmp} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
+!else
+  ${Int64Cmp} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
+!endif
+!macroend
+
+!define Int32CmpU '!insertmacro Int32CmpU '
+!define Int64CmpU '!insertmacro Int64CmpU '
+!define IntPtrCmpU '!insertmacro IntPtrCmpU '
+!macro Int32CmpU a b jeek jles jgtr
+!if ${NSIS_PTR_SIZE} <= 4
+  IntCmpU `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
+!else
+  !error "Int32CmpU not implemented"
+!endif
+!macroend
+!macro Int64CmpUHelper
+; This macro performs "$_LOGICLIB_TEMP = a < b ? -1 : a > b ? 1 : 0" but System::Int64Op does not support unsigned operations so we have to perform multiple steps
+!ifmacrondef _LOGICLIB_TEMP
+!include LogicLib.nsh
+!endif
+!insertmacro _LOGICLIB_TEMP
+Exch $2 ; b
+Exch
+Exch $1 ; a
+; if (a == b) return 0;
+; if (a < 0)
+; {
+;   if (b >= 0) return 1
+; }
+; else
+; {
+;   if (b < 0) return -1
+; }
+; return a < b ? -1 : 1
+System::Int64Op $1 ^ $2 ; Using xor so $_LOGICLIB_TEMP ends up as 0 when they are equal
+Pop $_LOGICLIB_TEMP
+StrCmp $_LOGICLIB_TEMP 0 ret ; NOTE: Must use StrCmp, IntCmp fails on "0x8000000000000001 Z> 1"
+System::Int64Op $1 < 0
+Pop $_LOGICLIB_TEMP
+StrCmp $_LOGICLIB_TEMP 0 checkNegOther
+System::Int64Op $2 < 0 ; System::Int64Op does not support the >= operator so we invert the operation
+Pop $_LOGICLIB_TEMP
+StrCmp $_LOGICLIB_TEMP 0 retPos finalCmp
+retPos:
+StrCpy $_LOGICLIB_TEMP "1"
+Goto ret
+checkNegOther:
+System::Int64Op $2 < 0
+Pop $_LOGICLIB_TEMP
+StrCmp $_LOGICLIB_TEMP 0 finalCmp retNeg
+retNeg:
+StrCpy $_LOGICLIB_TEMP "-1"
+Goto ret
+finalCmp:
+System::Int64Op $1 < $2
+Pop $_LOGICLIB_TEMP
+StrCmp $_LOGICLIB_TEMP 0 retPos retNeg
+ret:
+Pop $1
+Pop $2
+!macroend
+!macro Int64CmpU a b jeek jles jgtr
+!echo "Int64CmpU ${a}:${b} =${jeek}, <${jles}, >${jgtr}"
+!verbose push 2
+Push `${a}`
+Push `${b}`
+!insertmacro CallArtificialFunction Int64CmpUHelper
+IntCmp $_LOGICLIB_TEMP 0 `${jeek}` `${jles}` `${jgtr}`
+!verbose pop
+!macroend
+!macro IntPtrCmpU a b jeek jles jgtr
+!if ${NSIS_PTR_SIZE} <= 4
+  ${Int32CmpU} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
+!else
+  ${Int64CmpU} `${a}` `${b}` `${jeek}` `${jles}` `${jgtr}`
+!endif
+!macroend
+
+
+!endif # !___UTIL__NSH___
+!verbose pop

+ 90 - 0
assets/nsis/Include/VB6RunTime.nsh

@@ -0,0 +1,90 @@
+/*
+
+VB6RunTime.nsh
+
+Setup of Visual Basic 6.0 run-time files, including the Oleaut32.dll security update
+
+Copyright 2008-2016 Joost Verburg
+
+To obtain the run-time files, download and extract
+http://nsis.sourceforge.net/vb6runtime.zip
+
+Script code for installation:
+
+!insertmacro InstallVB6RunTime FOLDER ALREADY_INSTALLED
+
+in which FOLDER is the location of the run-time files and ALREADY_INSTALLED is the
+name of a variable that is empty when the application is installed for the first time
+and non-empty otherwise
+
+Script code for uninstallation:
+
+!insertmacro UnInstallVB6RunTime
+
+Remarks:
+
+* You may have to install additional files for such Visual Basic application to work,
+  such as OCX files for user interface controls.
+  
+* Installation of the run-time files requires Administrator or Power User privileges.
+  Use the Multi-User header file to verify whether these privileges are available.
+
+* Add a Modern UI finish page or another check (see IfRebootFlag in the NSIS Users
+  Manual) to allow the user to restart the computer when necessary.
+
+*/
+
+!ifndef VB6_INCLUDED
+!define VB6_INCLUDED
+!verbose push
+!verbose 3
+
+!include Library.nsh
+!include WinVer.nsh
+
+!macro VB6RunTimeInstall FOLDER ALREADY_INSTALLED
+
+  !insertmacro InstallLib REGDLL "${ALREADY_INSTALLED}" REBOOT_PROTECTED "${FOLDER}\msvbvm60.dll" "$SYSDIR\msvbvm60.dll" "$SYSDIR"
+  
+  ;The files below will only be installed on Win9x/NT4
+  
+  !insertmacro InstallLib REGDLL "${ALREADY_INSTALLED}" REBOOT_PROTECTED    "${FOLDER}\olepro32.dll" "$SYSDIR\olepro32.dll" "$SYSDIR"
+  !insertmacro InstallLib REGDLL "${ALREADY_INSTALLED}" REBOOT_PROTECTED    "${FOLDER}\comcat.dll"   "$SYSDIR\comcat.dll"   "$SYSDIR"
+  !insertmacro InstallLib DLL    "${ALREADY_INSTALLED}" REBOOT_PROTECTED    "${FOLDER}\asycfilt.dll" "$SYSDIR\asycfilt.dll" "$SYSDIR"
+  !insertmacro InstallLib TLB    "${ALREADY_INSTALLED}" REBOOT_PROTECTED    "${FOLDER}\stdole2.tlb"  "$SYSDIR\stdole2.tlb"  "$SYSDIR"
+  
+  Push $R0
+  
+  ${if} ${IsNT}
+    ${if} ${IsWinNT4}
+      ReadRegStr $R0 HKLM "System\CurrentControlSet\Control" "ProductOptions"
+      ${if} $R0 == "Terminal Server"
+        !insertmacro InstallLib REGDLL "${ALREADY_INSTALLED}" REBOOT_NOTPROTECTED "${FOLDER}\NT4TS\oleaut32.dll" "$SYSDIR\oleaut32.dll" "$SYSDIR"
+      ${else}
+        !insertmacro InstallLib REGDLL "${ALREADY_INSTALLED}" REBOOT_NOTPROTECTED "${FOLDER}\NT4\oleaut32.dll" "$SYSDIR\oleaut32.dll" "$SYSDIR"
+      ${endif}
+    ${endif}
+  ${else}
+    ;No Oleaut32.dll with the security update has been released for Windows 9x.
+    ;The NT4 version is used because NT4 and Win9x used to share the same 2.40 version
+    ;and version 2.40.4519.0 is reported to work fine on Win9x.
+    !insertmacro InstallLib REGDLL "${ALREADY_INSTALLED}" REBOOT_NOTPROTECTED "${FOLDER}\NT4\oleaut32.dll" "$SYSDIR\oleaut32.dll" "$SYSDIR"
+  ${endif}
+  
+  Pop $R0
+
+!macroend
+
+!macro VB6RunTimeUnInstall
+
+   !insertmacro UnInstallLib REGDLL SHARED NOREMOVE "$SYSDIR\msvbvm60.dll"
+   !insertmacro UnInstallLib REGDLL SHARED NOREMOVE "$SYSDIR\oleaut32.dll"
+   !insertmacro UnInstallLib REGDLL SHARED NOREMOVE "$SYSDIR\olepro32.dll"
+   !insertmacro UnInstallLib REGDLL SHARED NOREMOVE "$SYSDIR\comcat.dll"
+   !insertmacro UnInstallLib DLL    SHARED NOREMOVE "$SYSDIR\asycfilt.dll"
+   !insertmacro UnInstallLib TLB    SHARED NOREMOVE "$SYSDIR\stdole2.tlb"
+
+!macroend
+
+!verbose pop
+!endif

+ 234 - 0
assets/nsis/Include/Win/COM.nsh

@@ -0,0 +1,234 @@
+/*
+-------------
+   COM.nsh
+-------------
+
+COM defines and helper macros
+
+; Example usage:
+!include LogicLib.nsh
+!include Win\COM.nsh
+!include Win\Propkey.nsh
+!insertmacro ComHlpr_CreateInProcInstance ${CLSID_ShellLink} ${IID_IShellLink} r0 ""
+${If} $0 P<> 0
+	${IShellLink::SetPath} $0 '("%COMSPEC%").r1'
+	${IShellLink::SetArguments} $0 '("/k echo HelloWorld").r2'
+	${If} $1 = 0
+	${AndIf} $2 = 0
+		${IUnknown::QueryInterface} $0 '("${IID_IPropertyStore}",.r1)'
+		${If} $1 P<> 0
+			System::Call '*${SYSSTRUCT_PROPERTYKEY}(${PKEY_AppUserModel_StartPinOption})p.r2'
+			System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_UI4},,&i4 ${APPUSERMODEL_STARTPINOPTION_NOPINONINSTALL})p.r3'
+			${IPropertyStore::SetValue} $1 '($2,$3)'
+
+			; Reuse the PROPERTYKEY & PROPVARIANT buffers to set another property
+			System::Call '*$2${SYSSTRUCT_PROPERTYKEY}(${PKEY_AppUserModel_ExcludeFromShowInNewInstall})'
+			System::Call '*$3${SYSSTRUCT_PROPVARIANT}(${VT_BOOL},,&i2 ${VARIANT_TRUE})'
+			${IPropertyStore::SetValue} $1 '($2,$3)'
+
+			System::Free $2
+			System::Free $3
+			${IPropertyStore::Commit} $1 ""
+			${IUnknown::Release} $1 ""
+		${EndIf}
+		${IUnknown::QueryInterface} $0 '("${IID_IPersistFile}",.r1)'
+		${If} $1 P<> 0
+			${IPersistFile::Save} $1 '("$SMPrograms\nsis_test.lnk",1)'
+			${IUnknown::Release} $1 ""
+		${EndIf}
+	${EndIf}
+	${IUnknown::Release} $0 ""
+${EndIf}
+
+*/
+
+
+!ifndef __WIN_COM__INC
+!define __WIN_COM__INC ${NSIS_CHAR_SIZE}
+!verbose push
+!verbose 3
+
+!define /ifndef CLSCTX_INPROC_SERVER 0x1
+!define /ifndef CLSCTX_INPROC_HANDLER 0x2
+!define /ifndef CLSCTX_LOCAL_SERVER 0x4
+!define /ifndef CLSCTX_REMOTE_SERVER 0x10
+!define /ifndef CLSCTX_ACTIVATE_32_BIT_SERVER 0x40000
+!define /ifndef CLSCTX_ACTIVATE_64_BIT_SERVER 0x80000
+!define /ifndef CLSCTX_ENABLE_CLOAKING 0x100000
+
+!define NSISCOMCALL "!insertmacro NSISCOMCALL "
+!macro NSISCOMCALL vtblidx decl ptr params
+!if ${NSIS_CHAR_SIZE} <> ${__WIN_COM__INC}
+; Warn if QueryInterface() for IID_IShellLink etc will return the wrong interface
+!warning "NSIS_CHAR_SIZE changed, existing defines and macros might not work correctly!"
+!endif
+System::Call `${ptr}->${vtblidx}${decl}${params}`
+!macroend
+!define NSISCOMIFACEDECL "!insertmacro NSISCOMIFACEDECL "
+!macro NSISCOMIFACEDECL iface method vtblidx decl
+!define ${iface}::${method} `${NSISCOMCALL} ${vtblidx} ${decl} `
+!macroend
+
+!macro ComHlpr_CreateInProcInstance clsid iid sysoutvarIFacePtr sysret
+System::Call 'OLE32::CoCreateInstance(g "${clsid}",i 0,i ${CLSCTX_INPROC_SERVER},g "${iid}",*p.${sysoutvarIFacePtr})i${sysret}'
+!macroend
+
+!macro ComHlpr_SafeRelease _p
+${If} ${_p} P<> 0
+	${IUnknown::Release} ${_p} ""
+${EndIf}
+!macroend
+!macro ComHlpr_SafeReleaseAndNull _p
+${If} ${_p} P<> 0
+	${IUnknown::Release} ${_p} ""
+	StrCpy ${_p} 0
+${EndIf}
+!macroend
+
+
+!ifndef IID_IUnknown
+!define IID_IUnknown {00000000-0000-0000-C000-000000000046}
+${NSISCOMIFACEDECL}IUnknown QueryInterface 0 (g,*p)i
+${NSISCOMIFACEDECL}IUnknown AddRef 1 ()i
+${NSISCOMIFACEDECL}IUnknown Release 2 ()i
+!endif
+
+!ifndef IID_IPersist
+!define IID_IPersist {0000010c-0000-0000-C000-000000000046}
+${NSISCOMIFACEDECL}IPersist GetClassID 3 (*g)i
+!endif
+
+!ifndef IID_IPersistFile
+!define IID_IPersistFile {0000010b-0000-0000-C000-000000000046}
+${NSISCOMIFACEDECL}IPersistFile IsDirty 4 ()i
+${NSISCOMIFACEDECL}IPersistFile Load 5 (w,i)i
+${NSISCOMIFACEDECL}IPersistFile Save 6 (w,i)i
+${NSISCOMIFACEDECL}IPersistFile SaveCompleted 7 (w)i
+${NSISCOMIFACEDECL}IPersistFile GetCurFile 8 (*w)i
+!endif
+
+!ifndef CLSID_ShellLink
+!define CLSID_ShellLink {00021401-0000-0000-c000-000000000046}
+!endif
+!ifndef IID_IShellLink
+!define IID_IShellLinkA {000214ee-0000-0000-c000-000000000046}
+!define IID_IShellLinkW {000214f9-0000-0000-c000-000000000046}
+!ifdef NSIS_UNICODE
+!define IID_IShellLink ${IID_IShellLinkW}
+!else
+!define IID_IShellLink ${IID_IShellLinkA}
+!endif
+${NSISCOMIFACEDECL}IShellLink GetPath 3 (t,i,p,i)i
+${NSISCOMIFACEDECL}IShellLink GetIDList 4 (*p)i
+${NSISCOMIFACEDECL}IShellLink SetIDList 5 (p)i
+${NSISCOMIFACEDECL}IShellLink GetDescription 6 (t,i)i
+${NSISCOMIFACEDECL}IShellLink SetDescription 7 (t)i
+${NSISCOMIFACEDECL}IShellLink GetWorkingDirectory 8 (t,i)i
+${NSISCOMIFACEDECL}IShellLink SetWorkingDirectory 9 (t)i
+${NSISCOMIFACEDECL}IShellLink GetArguments 10 (t,i)i
+${NSISCOMIFACEDECL}IShellLink SetArguments 11 (t)i
+${NSISCOMIFACEDECL}IShellLink GetHotkey 12 (*i0)i
+${NSISCOMIFACEDECL}IShellLink SetHotkey 13 (&i2)i
+${NSISCOMIFACEDECL}IShellLink GetShowCmd 14 (*i)i
+${NSISCOMIFACEDECL}IShellLink SetShowCmd 15 (i)i
+${NSISCOMIFACEDECL}IShellLink GetIconLocation 16 (t,i,*i)i
+${NSISCOMIFACEDECL}IShellLink SetIconLocation 17 (t,i)i
+${NSISCOMIFACEDECL}IShellLink SetRelativePath 18 (t,i)i
+${NSISCOMIFACEDECL}IShellLink Resolve 19 (p,i)i
+${NSISCOMIFACEDECL}IShellLink SetPath 20 (t)i
+!endif
+
+!ifndef IID_IShellLinkDataList
+!define IID_IShellLinkDataList {45e2b4ae-b1c3-11d0-b92f-00a0c90312e1}
+${NSISCOMIFACEDECL}IShellLinkDataList AddDataBlock 3 (p)i
+${NSISCOMIFACEDECL}IShellLinkDataList CopyDataBlock 4 (i,*p)i
+${NSISCOMIFACEDECL}IShellLinkDataList RemoveDataBlock 5 (i)i
+${NSISCOMIFACEDECL}IShellLinkDataList GetFlags 6 (*i)i
+${NSISCOMIFACEDECL}IShellLinkDataList SetFlags 7 (i)i
+!endif
+!define /ifndef EXP_SZ_LINK_SIG         0xA0000001
+!define /ifndef NT_CONSOLE_PROPS_SIG    0xA0000002
+!define /ifndef NT_FE_CONSOLE_PROPS_SIG 0xA0000004
+!define /ifndef EXP_SPECIAL_FOLDER_SIG  0xA0000005
+!define /ifndef EXP_DARWIN_ID_SIG       0xA0000006
+!define /ifndef EXP_SZ_ICON_SIG         0xA0000007
+!define /ifndef EXP_PROPERTYSTORAGE_SIG 0xA0000009
+;SHELL_LINK_DATA_FLAGS
+!define /ifndef SLDF_HAS_ID_LIST                           0x00000001
+!define /ifndef SLDF_HAS_LINK_INFO                         0x00000002
+!define /ifndef SLDF_HAS_NAME                              0x00000004
+!define /ifndef SLDF_HAS_RELPATH                           0x00000008
+!define /ifndef SLDF_HAS_WORKINGDIR                        0x00000010
+!define /ifndef SLDF_HAS_ARGS                              0x00000020
+!define /ifndef SLDF_HAS_ICONLOCATION                      0x00000040
+!define /ifndef SLDF_UNICODE                               0x00000080
+!define /ifndef SLDF_FORCE_NO_LINKINFO                     0x00000100
+!define /ifndef SLDF_HAS_EXP_SZ                            0x00000200
+!define /ifndef SLDF_RUN_IN_SEPARATE                       0x00000400
+!define /ifndef SLDF_HAS_LOGO3ID                           0x00000800
+!define /ifndef SLDF_HAS_DARWINID                          0x00001000
+!define /ifndef SLDF_RUNAS_USER                            0x00002000
+!define /ifndef SLDF_HAS_EXP_ICON_SZ                       0x00004000
+!define /ifndef SLDF_NO_PIDL_ALIAS                         0x00008000
+!define /ifndef SLDF_FORCE_UNCNAME                         0x00010000
+!define /ifndef SLDF_RUN_WITH_SHIMLAYER                    0x00020000
+!define /ifndef SLDF_FORCE_NO_LINKTRACK                    0x00040000 ;[Vista+]
+!define /ifndef SLDF_ENABLE_TARGET_METADATA                0x00080000
+!define /ifndef SLDF_DISABLE_LINK_PATH_TRACKING            0x00100000 ;[Seven+]
+!define /ifndef SLDF_DISABLE_KNOWNFOLDER_RELATIVE_TRACKING 0x00200000
+!define /ifndef SLDF_NO_KF_ALIAS                           0x00400000
+!define /ifndef SLDF_ALLOW_LINK_TO_LINK                    0x00800000
+!define /ifndef SLDF_UNALIAS_ON_SAVE                       0x01000000
+!define /ifndef SLDF_PREFER_ENVIRONMENT_PATH               0x02000000
+!define /ifndef SLDF_KEEP_LOCAL_IDLIST_FOR_UNC_TARGET      0x04000000
+!define /ifndef SLDF_PERSIST_VOLUME_ID_RELATIVE            0x08000000 ;[Eight+]
+
+!ifndef IID_IShellItem
+!define IID_IShellItem {43826d1e-e718-42ee-bc55-a1e261c37bfe}
+${NSISCOMIFACEDECL}IShellItem BindToHandler 3 (p,g,g,*p)i
+${NSISCOMIFACEDECL}IShellItem GetParent 4 (*p)i
+${NSISCOMIFACEDECL}IShellItem GetDisplayName 5 (i,*p)i
+${NSISCOMIFACEDECL}IShellItem GetAttributes 6 (i,*i)i
+${NSISCOMIFACEDECL}IShellItem Compare 7 (p,i,*i)i
+!endif
+
+!ifndef CLSID_StartMenuPin
+!define CLSID_StartMenuPin {a2a9545d-a0c2-42b4-9708-a0b2badd77c8}
+!endif
+!ifndef IID_IStartMenuPinnedList
+!define IID_IStartMenuPinnedList {4CD19ADA-25A5-4A32-B3B7-347BEE5BE36B}
+${NSISCOMIFACEDECL}IStartMenuPinnedList RemoveFromList 3 (p)i
+!endif
+
+!ifndef IID_IPropertyStore
+!define IID_IPropertyStore {886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}
+${NSISCOMIFACEDECL}IPropertyStore GetCount 3 (*i)i
+${NSISCOMIFACEDECL}IPropertyStore GetAt 4 (i,p)i
+${NSISCOMIFACEDECL}IPropertyStore GetValue 5 (p,p)i
+${NSISCOMIFACEDECL}IPropertyStore SetValue 6 (p,p)i
+${NSISCOMIFACEDECL}IPropertyStore Commit 7 ()i
+!endif
+
+!ifndef CLSID_ApplicationAssociationRegistration
+!define CLSID_ApplicationAssociationRegistration {591209c7-767b-42b2-9fba-44ee4615f2c7}
+!endif
+!ifndef IID_IApplicationAssociationRegistration
+!define IID_IApplicationAssociationRegistration {4e530b0a-e611-4c77-a3ac-9031d022281b} ;[Vista+]
+${NSISCOMIFACEDECL}IApplicationAssociationRegistration QueryCurrentDefault 3 (w,i,i,*p)i
+${NSISCOMIFACEDECL}IApplicationAssociationRegistration QueryAppIsDefault 4 (w,i,i,w,*i)i
+${NSISCOMIFACEDECL}IApplicationAssociationRegistration QueryAppIsDefaultAll 5 (i,w,*i)i
+${NSISCOMIFACEDECL}IApplicationAssociationRegistration SetAppAsDefault 6 (w,w,i)i
+${NSISCOMIFACEDECL}IApplicationAssociationRegistration SetAppAsDefaultAll 7 (w)i
+${NSISCOMIFACEDECL}IApplicationAssociationRegistration ClearUserAssociations 8 ()i
+!endif
+!ifndef CLSID_ApplicationAssociationRegistrationUI
+!define CLSID_ApplicationAssociationRegistrationUI {1968106d-f3b5-44cf-890e-116fcb9ecef1}
+!endif
+!ifndef IID_IApplicationAssociationRegistrationUI
+!define IID_IApplicationAssociationRegistrationUI {1f76a169-f994-40ac-8fc8-0959e8874710} ;[Vista+]
+${NSISCOMIFACEDECL}IApplicationAssociationRegistrationUI LaunchAdvancedAssociationUI 3 (w)i
+!endif
+
+
+!verbose pop
+!endif /* __WIN_COM__INC */

+ 51 - 0
assets/nsis/Include/Win/Propkey.nsh

@@ -0,0 +1,51 @@
+!ifndef __WIN_PROPKEY__INC
+!define __WIN_PROPKEY__INC
+!verbose push
+!verbose 3 
+
+
+/**************************************************
+WTypes.h
+**************************************************/
+;NOTE: This list is incomplete
+!define VT_EMPTY     0
+!define VT_NULL      1
+!define VT_I4        3
+!define VT_BSTR      8
+!define VT_BOOL      11
+!define VT_UI4       19
+!define VT_INT       22
+!define VT_UINT      23
+!define VT_HRESULT   25
+!define VT_PTR       26
+!define VT_SAFEARRAY 27
+!define VT_LPSTR     30
+!define VT_LPWSTR    31
+
+!define /ifndef VARIANT_TRUE -1
+!define /ifndef VARIANT_FALSE 0
+
+!define SYSSIZEOF_PROPERTYKEY 20
+!define SYSSTRUCT_PROPERTYKEY (&g16,&i4) ;System.dll is buggy when it comes to g and forces us to specify the size
+
+
+/**************************************************
+PropIdl.h
+**************************************************/
+!define SYSSIZEOF_PROPVARIANT 16
+!define SYSSTRUCT_PROPVARIANT (&i2,&i6,&i8)
+
+
+/**************************************************
+Propkey.h
+**************************************************/
+!define PKEY_AppUserModel_ID                          '"{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}",5'
+!define PKEY_AppUserModel_ExcludeFromShowInNewInstall '"{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}",8' ; VT_BOOL
+!define PKEY_AppUserModel_PreventPinning              '"{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}",9' ; VT_BOOL
+!define APPUSERMODEL_STARTPINOPTION_NOPINONINSTALL 1
+!define APPUSERMODEL_STARTPINOPTION_USERPINNED 2
+!define PKEY_AppUserModel_StartPinOption '"{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}",12' ; VT_UI4 [Eight+]
+
+
+!verbose pop
+!endif /* __WIN_PROPKEY__INC */

+ 68 - 0
assets/nsis/Include/Win/WinDef.nsh

@@ -0,0 +1,68 @@
+!ifndef __WIN_WINDEF__INC
+!define __WIN_WINDEF__INC
+!verbose push
+!verbose 3
+!ifndef __WIN_NOINC_WINDEF
+
+
+!define /ifndef MAX_PATH 260
+#define NULL 0
+
+
+!macro _Win_MINMAX _intcmp _j1 _j2 _outvar _a _b
+${_intcmp} "${_a}" "${_b}" ${_j1} ${_j1} ${_j2}
+StrCpy ${_outvar} "${_a}"
+goto +2
+StrCpy ${_outvar} "${_b}"
+!macroend
+!ifndef __WIN_MS_NOMINMAX & min & max & min_u & max_u
+!define min "!insertmacro _Win_MINMAX IntCmp +1 +3 "
+!define max "!insertmacro _Win_MINMAX IntCmp +3 +1 "
+!define min_u "!insertmacro _Win_MINMAX IntCmpU +1 +3 "
+!define max_u "!insertmacro _Win_MINMAX IntCmpU +3 +1 "
+!endif
+
+!macro _Win_LOBYTE _outvar _in
+IntOp ${_outvar} "${_in}" & 0xFF
+!macroend
+!define LOBYTE "!insertmacro _Win_LOBYTE "
+
+!macro _Win_HIBYTE _outvar _in
+IntOp ${_outvar} "${_in}" >> 8
+${LOBYTE} ${_outvar} ${_outvar}
+!macroend
+!define HIBYTE "!insertmacro _Win_HIBYTE "
+
+!macro _Win_LOWORD _outvar _in
+IntOp ${_outvar} "${_in}" & 0xFFFF
+!macroend
+!define LOWORD "!insertmacro _Win_LOWORD "
+
+!macro _Win_HIWORD _outvar _in
+IntOp ${_outvar} "${_in}" >> 16 ;sign extended :(
+${LOWORD} ${_outvar} ${_outvar} ;make sure we strip off the upper word
+!macroend
+!define HIWORD "!insertmacro _Win_HIWORD "
+
+!macro _Win_MAKEWORD _outvar _tmpvar _lo _hi
+${LOBYTE} ${_outvar} "${_hi}"
+${LOBYTE} ${_tmpvar} "${_lo}"
+IntOp ${_outvar} ${_outvar} << 8
+IntOp ${_outvar} ${_outvar} | ${_tmpvar}
+!macroend
+!define MAKEWORD "!insertmacro _Win_MAKEWORD "
+
+!macro _Win_MAKELONG32 _outvar _tmpvar _wlo _whi
+${LOWORD} ${_outvar} "${_wlo}"
+IntOp ${_tmpvar} "${_whi}" << 16
+IntOp ${_outvar} ${_outvar} | ${_tmpvar}
+!macroend
+!define MAKELONG "!insertmacro _Win_MAKELONG32 "
+!define MAKEWPARAM "${MAKELONG}"
+!define MAKELPARAM "${MAKELONG}"
+!define MAKELRESULT "${MAKELONG}"
+
+
+!endif /* __WIN_NOINC_WINDEF */
+!verbose pop
+!endif /* __WIN_WINDEF__INC */

+ 64 - 0
assets/nsis/Include/Win/WinError.nsh

@@ -0,0 +1,64 @@
+!ifndef __WIN_WINERROR__INC
+!define __WIN_WINERROR__INC
+!verbose push
+!verbose 3
+!ifndef __WIN_NOINC_WINERROR
+
+#define NO_ERROR 0
+!define ERROR_SUCCESS                 0
+!define ERROR_INVALID_FUNCTION        1    
+!define ERROR_FILE_NOT_FOUND          2
+!define ERROR_PATH_NOT_FOUND          3
+!define ERROR_TOO_MANY_OPEN_FILES     4
+!define ERROR_ACCESS_DENIED           5
+!define ERROR_INVALID_HANDLE          6
+!define ERROR_ARENA_TRASHED           7
+!define ERROR_NOT_ENOUGH_MEMORY       8    
+!define ERROR_INVALID_BLOCK           9
+!define ERROR_BAD_ENVIRONMENT         10
+!define ERROR_BAD_FORMAT              11
+!define ERROR_INVALID_ACCESS          12
+!define ERROR_INVALID_DATA            13
+!define ERROR_OUTOFMEMORY             14
+!define ERROR_INVALID_DRIVE           15
+!define ERROR_CURRENT_DIRECTORY       16
+!define ERROR_NOT_SAME_DEVICE         17
+!define ERROR_NO_MORE_FILES           18
+!define ERROR_WRITE_PROTECT           19
+!define ERROR_BAD_UNIT                20
+!define ERROR_NOT_READY               21
+!define ERROR_BAD_COMMAND             22
+!define ERROR_CRC                     23
+!define ERROR_BAD_LENGTH              24
+!define ERROR_SEEK                    25
+!define ERROR_NOT_DOS_DISK            26
+!define ERROR_SECTOR_NOT_FOUND        27
+!define ERROR_OUT_OF_PAPER            28
+!define ERROR_WRITE_FAULT             29
+!define ERROR_READ_FAULT              30
+!define ERROR_GEN_FAILURE             31
+!define ERROR_SHARING_VIOLATION       32
+!define ERROR_LOCK_VIOLATION          33
+!define ERROR_WRONG_DISK              34
+!define ERROR_SHARING_BUFFER_EXCEEDED 36
+!define ERROR_HANDLE_EOF              38
+!define ERROR_HANDLE_DISK_FULL        39
+!define ERROR_NOT_SUPPORTED           50
+
+!define SEVERITY_SUCCESS 0
+!define SEVERITY_ERROR   1
+!define E_UNEXPECTED   0x8000FFFF
+!define E_NOTIMPL      0x80004001
+!define E_OUTOFMEMORY  0x8007000E
+!define E_INVALIDARG   0x80070057
+!define E_NOINTERFACE  0x80004002
+!define E_POINTER      0x80004003
+!define E_HANDLE       0x80070006
+!define E_ABORT        0x80004004
+!define E_FAIL         0x80004005
+!define E_ACCESSDENIED 0x80070005
+!define E_PENDING      0x8000000A
+
+!endif /* __WIN_NOINC_WINERROR */
+!verbose pop
+!endif /* __WIN_WINERROR__INC */

+ 209 - 0
assets/nsis/Include/Win/WinNT.nsh

@@ -0,0 +1,209 @@
+!ifndef __WIN_WINNT__INC
+!define __WIN_WINNT__INC
+!verbose push
+!verbose 3
+!ifndef __WIN_NOINC_WINNT
+
+
+#define MINCHAR  0x80        
+#define MAXCHAR  0x7f        
+!define MINSHORT 0x8000      
+!define MAXSHORT 0x7fff      
+!define MINLONG  0x80000000  
+!define MAXLONG  0x7fffffff  
+!define MAXBYTE  0xff        
+!define MAXWORD  0xffff      
+!define MAXDWORD 0xffffffff  
+
+!ifndef WIN32_NO_STATUS 
+!define STATUS_WAIT_0                    0x00000000
+!define STATUS_ABANDONED_WAIT_0          0x00000080
+!define STATUS_USER_APC                  0x000000C0
+!define STATUS_TIMEOUT                   0x00000102
+!define STATUS_PENDING                   0x00000103
+!define DBG_EXCEPTION_HANDLED            0x00010001
+!define DBG_CONTINUE                     0x00010002
+!define STATUS_SEGMENT_NOTIFICATION      0x40000005
+!define DBG_TERMINATE_THREAD             0x40010003
+!define DBG_TERMINATE_PROCESS            0x40010004
+!define DBG_CONTROL_C                    0x40010005
+!define DBG_CONTROL_BREAK                0x40010008
+!define DBG_COMMAND_EXCEPTION            0x40010009
+!define STATUS_GUARD_PAGE_VIOLATION      0x80000001
+!define STATUS_DATATYPE_MISALIGNMENT     0x80000002
+!define STATUS_BREAKPOINT                0x80000003
+!define STATUS_SINGLE_STEP               0x80000004
+!define DBG_EXCEPTION_NOT_HANDLED        0x80010001
+!define STATUS_ACCESS_VIOLATION          0xC0000005
+!define STATUS_IN_PAGE_ERROR             0xC0000006
+!define STATUS_INVALID_HANDLE            0xC0000008
+!define STATUS_NO_MEMORY                 0xC0000017
+!define STATUS_ILLEGAL_INSTRUCTION       0xC000001D
+!define STATUS_NONCONTINUABLE_EXCEPTION  0xC0000025
+!define STATUS_INVALID_DISPOSITION       0xC0000026
+!define STATUS_ARRAY_BOUNDS_EXCEEDED     0xC000008C
+!define STATUS_FLOAT_DENORMAL_OPERAND    0xC000008D
+!define STATUS_FLOAT_DIVIDE_BY_ZERO      0xC000008E
+!define STATUS_FLOAT_INEXACT_RESULT      0xC000008F
+!define STATUS_FLOAT_INVALID_OPERATION   0xC0000090
+!define STATUS_FLOAT_OVERFLOW            0xC0000091
+!define STATUS_FLOAT_STACK_CHECK         0xC0000092
+!define STATUS_FLOAT_UNDERFLOW           0xC0000093
+!define STATUS_INTEGER_DIVIDE_BY_ZERO    0xC0000094
+!define STATUS_INTEGER_OVERFLOW          0xC0000095
+!define STATUS_PRIVILEGED_INSTRUCTION    0xC0000096
+!define STATUS_STACK_OVERFLOW            0xC00000FD
+!define STATUS_CONTROL_C_EXIT            0xC000013A
+!define STATUS_FLOAT_MULTIPLE_FAULTS     0xC00002B4
+!define STATUS_FLOAT_MULTIPLE_TRAPS      0xC00002B5
+!define STATUS_REG_NAT_CONSUMPTION       0xC00002C9
+!define STATUS_SXS_EARLY_DEACTIVATION    0xC015000F
+!define STATUS_SXS_INVALID_DEACTIVATION  0xC0150010
+!endif /*WIN32_NO_STATUS*/
+
+#define MAXIMUM_WAIT_OBJECTS 64  
+
+!define DELETE                   0x00010000
+!define READ_CONTROL             0x00020000
+!define WRITE_DAC                0x00040000
+!define WRITE_OWNER              0x00080000
+!define SYNCHRONIZE              0x00100000
+!define STANDARD_RIGHTS_REQUIRED 0x000F0000
+!define STANDARD_RIGHTS_READ     ${READ_CONTROL}
+!define STANDARD_RIGHTS_WRITE    ${READ_CONTROL}
+!define STANDARD_RIGHTS_EXECUTE  ${READ_CONTROL}
+!define STANDARD_RIGHTS_ALL      0x001F0000
+!define SPECIFIC_RIGHTS_ALL      0x0000FFFF
+!define ACCESS_SYSTEM_SECURITY   0x01000000
+!define MAXIMUM_ALLOWED          0x02000000
+!define GENERIC_READ             0x80000000
+!define GENERIC_WRITE            0x40000000
+!define GENERIC_EXECUTE          0x20000000
+!define GENERIC_ALL              0x10000000
+
+!define SE_PRIVILEGE_ENABLED_BY_DEFAULT 0x00000001
+!define SE_PRIVILEGE_ENABLED            0x00000002
+!define SE_PRIVILEGE_REMOVED            0x00000004
+!define SE_PRIVILEGE_USED_FOR_ACCESS    0x80000000
+
+!define SE_CREATE_TOKEN_NAME        "SeCreateTokenPrivilege"
+!define SE_ASSIGNPRIMARYTOKEN_NAME  "SeAssignPrimaryTokenPrivilege"
+!define SE_LOCK_MEMORY_NAME         "SeLockMemoryPrivilege"
+!define SE_INCREASE_QUOTA_NAME      "SeIncreaseQuotaPrivilege"
+!define SE_UNSOLICITED_INPUT_NAME   "SeUnsolicitedInputPrivilege"
+!define SE_MACHINE_ACCOUNT_NAME     "SeMachineAccountPrivilege"
+!define SE_TCB_NAME                 "SeTcbPrivilege"
+!define SE_SECURITY_NAME            "SeSecurityPrivilege"
+!define SE_TAKE_OWNERSHIP_NAME      "SeTakeOwnershipPrivilege"
+!define SE_LOAD_DRIVER_NAME         "SeLoadDriverPrivilege"
+!define SE_SYSTEM_PROFILE_NAME      "SeSystemProfilePrivilege"
+!define SE_SYSTEMTIME_NAME          "SeSystemtimePrivilege"
+!define SE_PROF_SINGLE_PROCESS_NAME "SeProfileSingleProcessPrivilege"
+!define SE_INC_BASE_PRIORITY_NAME   "SeIncreaseBasePriorityPrivilege"
+!define SE_CREATE_PAGEFILE_NAME     "SeCreatePagefilePrivilege"
+!define SE_CREATE_PERMANENT_NAME    "SeCreatePermanentPrivilege"
+!define SE_BACKUP_NAME              "SeBackupPrivilege"
+!define SE_RESTORE_NAME             "SeRestorePrivilege"
+!define SE_SHUTDOWN_NAME            "SeShutdownPrivilege"
+!define SE_DEBUG_NAME               "SeDebugPrivilege"
+!define SE_AUDIT_NAME               "SeAuditPrivilege"
+!define SE_SYSTEM_ENVIRONMENT_NAME  "SeSystemEnvironmentPrivilege"
+!define SE_CHANGE_NOTIFY_NAME       "SeChangeNotifyPrivilege"
+!define SE_REMOTE_SHUTDOWN_NAME     "SeRemoteShutdownPrivilege"
+!define SE_UNDOCK_NAME              "SeUndockPrivilege"
+!define SE_SYNC_AGENT_NAME          "SeSyncAgentPrivilege"
+!define SE_ENABLE_DELEGATION_NAME   "SeEnableDelegationPrivilege"
+!define SE_MANAGE_VOLUME_NAME       "SeManageVolumePrivilege"
+!define SE_IMPERSONATE_NAME         "SeImpersonatePrivilege"
+!define SE_CREATE_GLOBAL_NAME       "SeCreateGlobalPrivilege"
+
+!define TOKEN_ASSIGN_PRIMARY    0x0001
+!define TOKEN_DUPLICATE         0x0002
+!define TOKEN_IMPERSONATE       0x0004
+!define TOKEN_QUERY             0x0008
+!define TOKEN_QUERY_SOURCE      0x0010
+!define TOKEN_ADJUST_PRIVILEGES 0x0020
+!define TOKEN_ADJUST_GROUPS     0x0040
+!define TOKEN_ADJUST_DEFAULT    0x0080
+!define TOKEN_ADJUST_SESSIONID  0x0100
+!define TOKEN_ALL_ACCESS_P     0xF00FF
+!define /math TOKEN_ALL_ACCESS  ${TOKEN_ALL_ACCESS_P} | ${TOKEN_ADJUST_SESSIONID}
+!define /math TOKEN_READ        ${STANDARD_RIGHTS_READ} | ${TOKEN_QUERY}
+!define TOKEN_WRITE      0x200E0 ;(STANDARD_RIGHTS_WRITE|TOKEN_ADJUST_PRIVILEGES|TOKEN_ADJUST_GROUPS|TOKEN_ADJUST_DEFAULT)
+!define TOKEN_EXECUTE    ${STANDARD_RIGHTS_EXECUTE}
+
+!define PROCESS_TERMINATE         0x0001
+!define PROCESS_CREATE_THREAD     0x0002
+!define PROCESS_SET_SESSIONID     0x0004
+!define PROCESS_VM_OPERATION      0x0008
+!define PROCESS_VM_READ           0x0010
+!define PROCESS_VM_WRITE          0x0020
+!define PROCESS_DUP_HANDLE        0x0040
+!define PROCESS_CREATE_PROCESS    0x0080
+!define PROCESS_SET_QUOTA         0x0100
+!define PROCESS_SET_INFORMATION   0x0200
+!define PROCESS_QUERY_INFORMATION 0x0400
+!define PROCESS_SUSPEND_RESUME    0x0800
+!define PROCESS_ALL_ACCESS      0x1F0FFF ;(STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF)
+!define THREAD_TERMINATE               0x0001
+!define THREAD_SUSPEND_RESUME          0x0002
+!define THREAD_GET_CONTEXT             0x0008
+!define THREAD_SET_CONTEXT             0x0010
+!define THREAD_SET_INFORMATION         0x0020
+!define THREAD_QUERY_INFORMATION       0x0040
+!define THREAD_SET_THREAD_TOKEN        0x0080
+!define THREAD_IMPERSONATE             0x0100
+!define THREAD_DIRECT_IMPERSONATION    0x0200
+!define THREAD_ALL_ACCESS            0x1F03FF ;(STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3FF)
+!define JOB_OBJECT_ASSIGN_PROCESS           0x0001
+!define JOB_OBJECT_SET_ATTRIBUTES           0x0002
+!define JOB_OBJECT_QUERY                    0x0004
+!define JOB_OBJECT_TERMINATE                0x0008
+!define JOB_OBJECT_SET_SECURITY_ATTRIBUTES  0x0010
+!define JOB_OBJECT_ALL_ACCESS             0x1F001F ;(STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1F )
+!define EVENT_MODIFY_STATE      0x0002  
+!define EVENT_ALL_ACCESS 0x1F0003 ;(STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) 
+!define MUTANT_QUERY_STATE      0x0001
+!define MUTANT_ALL_ACCESS 0x1F0001 ;(STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|MUTANT_QUERY_STATE)
+
+!define FILE_SHARE_READ   0x00000001
+!define FILE_SHARE_WRITE  0x00000002
+!define FILE_SHARE_DELETE 0x00000004
+!define FILE_ATTRIBUTE_READONLY             0x00000001
+!define FILE_ATTRIBUTE_HIDDEN               0x00000002
+!define FILE_ATTRIBUTE_SYSTEM               0x00000004
+!define FILE_ATTRIBUTE_DIRECTORY            0x00000010
+!define FILE_ATTRIBUTE_ARCHIVE              0x00000020
+!define FILE_ATTRIBUTE_DEVICE               0x00000040
+!define FILE_ATTRIBUTE_NORMAL               0x00000080
+!define FILE_ATTRIBUTE_TEMPORARY            0x00000100
+!define FILE_ATTRIBUTE_SPARSE_FILE          0x00000200
+!define FILE_ATTRIBUTE_REPARSE_POINT        0x00000400
+!define FILE_ATTRIBUTE_COMPRESSED           0x00000800
+!define FILE_ATTRIBUTE_OFFLINE              0x00001000
+!define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
+!define FILE_ATTRIBUTE_ENCRYPTED            0x00004000
+
+!define DUPLICATE_CLOSE_SOURCE 0x00000001
+!define DUPLICATE_SAME_ACCESS  0x00000002
+
+!define /ifndef VER_PLATFORM_WIN32s         0
+!define /ifndef VER_PLATFORM_WIN32_WINDOWS  1
+!define /ifndef VER_PLATFORM_WIN32_NT       2
+
+!ifndef REG_SZ & NSIS_WINDOWS__NO_REGTYPES
+!define REG_NONE                 0
+!define REG_SZ                   1
+!define REG_EXPAND_SZ            2
+!define REG_BINARY               3
+!define REG_DWORD                4
+!define REG_DWORD_LITTLE_ENDIAN  4
+!define REG_DWORD_BIG_ENDIAN     5
+!define REG_LINK                 6
+!define REG_MULTI_SZ             7
+!endif
+
+
+!endif /* __WIN_NOINC_WINNT */
+!verbose pop
+!endif /* __WIN_WINNT__INC */

+ 199 - 0
assets/nsis/Include/Win/WinUser.nsh

@@ -0,0 +1,199 @@
+!ifndef __WIN_WINUSER__INC
+!define __WIN_WINUSER__INC
+!verbose push
+!verbose 3
+!ifndef __WIN_MS_NOUSER & __WIN_NOINC_WINUSER
+
+!ifndef __WIN_MS_NOVIRTUALKEYCODES
+!define VK_LBUTTON    0x01
+!define VK_RBUTTON    0x02
+!define VK_CANCEL     0x03
+!define VK_MBUTTON    0x04 /* NOT contiguous with L & RBUTTON */
+!define VK_XBUTTON1   0x05 /* NOT contiguous with L & RBUTTON */
+!define VK_XBUTTON2   0x06 /* NOT contiguous with L & RBUTTON */
+!define VK_BACK       0x08
+!define VK_TAB        0x09
+!define VK_CLEAR      0x0C
+!define VK_RETURN     0x0D
+!define VK_SHIFT      0x10
+!define VK_CONTROL    0x11
+!define VK_MENU       0x12
+!define VK_PAUSE      0x13
+!define VK_CAPITAL    0x14
+!define VK_ESCAPE     0x1B
+!define VK_CONVERT    0x1C
+!define VK_NONCONVERT 0x1D
+!define VK_ACCEPT     0x1E
+!define VK_MODECHANGE 0x1F
+!define VK_SPACE      0x20
+!define VK_PRIOR      0x21
+!define VK_NEXT       0x22
+!define VK_END        0x23
+!define VK_HOME       0x24
+!define VK_LEFT       0x25
+!define VK_UP         0x26
+!define VK_RIGHT      0x27
+!define VK_DOWN       0x28
+!define VK_SELECT     0x29
+!define VK_PRINT      0x2A
+!define VK_EXECUTE    0x2B
+!define VK_SNAPSHOT   0x2C
+!define VK_INSERT     0x2D
+!define VK_DELETE     0x2E
+!define VK_HELP       0x2F
+; VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
+; VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
+!define VK_LWIN           0x5B
+!define VK_RWIN           0x5C
+!define VK_APPS           0x5D
+!define VK_SLEEP          0x5F
+!define VK_NUMPAD0        0x60
+!define VK_NUMPAD1        0x61
+!define VK_NUMPAD2        0x62
+!define VK_NUMPAD3        0x63
+!define VK_NUMPAD4        0x64
+!define VK_NUMPAD5        0x65
+!define VK_NUMPAD6        0x66
+!define VK_NUMPAD7        0x67
+!define VK_NUMPAD8        0x68
+!define VK_NUMPAD9        0x69
+!define VK_MULTIPLY       0x6A
+!define VK_ADD            0x6B
+!define VK_SEPARATOR      0x6C
+!define VK_SUBTRACT       0x6D
+!define VK_DECIMAL        0x6E
+!define VK_DIVIDE         0x6F
+!define VK_F1             0x70
+!define VK_F2             0x71
+!define VK_F3             0x72
+!define VK_F4             0x73
+!define VK_F5             0x74
+!define VK_F6             0x75
+!define VK_F7             0x76
+!define VK_F8             0x77
+!define VK_F9             0x78
+!define VK_F10            0x79
+!define VK_F11            0x7A
+!define VK_F12            0x7B
+!define VK_NUMLOCK        0x90
+!define VK_SCROLL         0x91
+!define VK_OEM_NEC_EQUAL  0x92   ; '=' key on numpad
+!define VK_LSHIFT         0xA0
+!define VK_RSHIFT         0xA1
+!define VK_LCONTROL       0xA2
+!define VK_RCONTROL       0xA3
+!define VK_LMENU          0xA4
+!define VK_RMENU          0xA5
+!endif
+
+!ifndef __WIN_MS_NOWINOFFSETS
+!define /ifndef GWL_STYLE       -16
+!define /ifndef GWL_EXSTYLE     -20
+!define /ifndef GWLP_WNDPROC    -4
+!define /ifndef GWLP_HINSTANCE  -6
+!define /ifndef GWLP_HWNDPARENT -8
+!define /ifndef GWLP_USERDATA   -21
+!define /ifndef GWLP_ID         -12
+!define DWLP_MSGRESULT  0
+!define /math DWLP_DLGPROC ${DWLP_MSGRESULT} + ${NSIS_PTR_SIZE} ;DWLP_MSGRESULT + sizeof(LRESULT) 
+!define /math DWLP_USER    ${DWLP_DLGPROC} + ${NSIS_PTR_SIZE} ;DWLP_DLGPROC + sizeof(DLGPROC)
+!endif
+
+!ifndef __WIN_MS_NONCMESSAGES
+!define HTERROR       -2
+!define HTTRANSPARENT -1
+!define HTNOWHERE     0
+!define HTCLIENT      1
+!define HTCAPTION     2
+!define HTSYSMENU     3
+!define HTGROWBOX     4
+!define HTSIZE        ${HTGROWBOX}
+!define HTMENU        5
+!define HTHSCROLL     6
+!define HTVSCROLL     7
+!define HTMINBUTTON   8
+!define HTMAXBUTTON   9
+!define HTLEFT        10
+!define HTRIGHT       11
+!define HTTOP         12
+!define HTTOPLEFT     13
+!define HTTOPRIGHT    14
+!define HTBOTTOM      15
+!define HTBOTTOMLEFT  16
+!define HTBOTTOMRIGHT 17
+!define HTBORDER      18
+!define HTREDUCE      ${HTMINBUTTON}
+!define HTZOOM        ${HTMAXBUTTON}
+!define HTSIZEFIRST   ${HTLEFT}
+!define HTSIZELAST    ${HTBOTTOMRIGHT}
+!define HTOBJECT      19
+!define HTCLOSE       20
+!define HTHELP        21
+!endif
+
+!ifndef __WIN_MS_NOSYSCOMMANDS
+!define SC_SIZE         0xF000
+!define SC_MOVE         0xF010
+!define SC_MINIMIZE     0xF020
+!define SC_MAXIMIZE     0xF030
+!define SC_NEXTWINDOW   0xF040
+!define SC_PREVWINDOW   0xF050
+!define SC_CLOSE        0xF060
+!define SC_VSCROLL      0xF070
+!define SC_HSCROLL      0xF080
+!define SC_MOUSEMENU    0xF090
+!define SC_KEYMENU      0xF100
+!define SC_ARRANGE      0xF110
+!define SC_RESTORE      0xF120
+!define SC_TASKLIST     0xF130
+!define SC_SCREENSAVE   0xF140
+!define SC_HOTKEY       0xF150
+!define SC_DEFAULT      0xF160
+!define SC_MONITORPOWER 0xF170
+!define SC_CONTEXTHELP  0xF180
+!define SC_SEPARATOR    0xF00F
+!endif
+
+!define /ifndef IDC_ARROW       32512
+!define /ifndef IDC_IBEAM       32513
+!define /ifndef IDC_WAIT        32514
+!define /ifndef IDC_CROSS       32515
+!define /ifndef IDC_UPARROW     32516
+!define /ifndef IDC_SIZE        32640
+!define /ifndef IDC_ICON        32641
+!define /ifndef IDC_SIZENWSE    32642
+!define /ifndef IDC_SIZENESW    32643
+!define /ifndef IDC_SIZEWE      32644
+!define /ifndef IDC_SIZENS      32645
+!define /ifndef IDC_SIZEALL     32646
+!define /ifndef IDC_NO          32648 
+!define /ifndef IDC_HAND        32649
+!define /ifndef IDC_APPSTARTING 32650 
+!define /ifndef IDC_HELP        32651
+
+!define /ifndef IMAGE_BITMAP        0
+!define /ifndef IMAGE_ICON          1
+!define /ifndef IMAGE_CURSOR        2
+!define /ifndef IMAGE_ENHMETAFILE   3
+
+!define /ifndef LR_DEFAULTCOLOR     0x0000
+!define /ifndef LR_MONOCHROME       0x0001
+!define /ifndef LR_COLOR            0x0002
+!define /ifndef LR_COPYRETURNORG    0x0004
+!define /ifndef LR_COPYDELETEORG    0x0008
+!define /ifndef LR_LOADFROMFILE     0x0010
+!define /ifndef LR_LOADTRANSPARENT  0x0020
+!define /ifndef LR_DEFAULTSIZE      0x0040
+!define /ifndef LR_VGACOLOR         0x0080
+!define /ifndef LR_LOADMAP3DCOLORS  0x1000
+!define /ifndef LR_CREATEDIBSECTION 0x2000
+!define /ifndef LR_COPYFROMRESOURCE 0x4000
+!define /ifndef LR_SHARED           0x8000
+
+!define GA_PARENT    1
+!define GA_ROOT      2
+!define GA_ROOTOWNER 3
+
+!endif /* __WIN_MS_NOUSER & __WIN_NOINC_WINUSER */
+!verbose pop
+!endif /* __WIN_WINUSER__INC */

+ 231 - 0
assets/nsis/Include/WinCore.nsh

@@ -0,0 +1,231 @@
+/*
+
+WinCore.nsh & Win\*.nsh - Collection of common windows defines
+
+!define __WIN_NOINC_xxx to exclude a windows header file
+!define __WIN_MS_xxx to exclude specific things (The original #ifdef xxx checks can be found in the official Microsoft headers)
+
+*/
+
+!ifndef __WIN_WINDOWS__INC
+!define __WIN_WINDOWS__INC
+!verbose push
+!verbose 3
+
+
+
+!include Win\WinDef.nsh
+!include Win\WinError.nsh
+!include Win\WinNT.nsh
+!include Win\WinUser.nsh
+
+!ifndef __WIN_MS_NOWINMESSAGES
+!include WinMessages.nsh
+!endif
+
+
+
+
+
+/**************************************************
+WinBase.h
+**************************************************/
+!ifndef __WIN_NOINC_WINBASE
+!define /ifndef INVALID_HANDLE_VALUE -1
+!define /ifndef INVALID_FILE_SIZE 0xFFFFFFFF
+!define /ifndef INVALID_SET_FILE_POINTER -1
+!define /ifndef INVALID_FILE_ATTRIBUTES -1
+
+!define WAIT_FAILED 0xFFFFFFFF
+!define WAIT_OBJECT_0       0 ;((STATUS_WAIT_0 ) + 0 )
+
+!define WAIT_ABANDONED         0x80 ;((STATUS_ABANDONED_WAIT_0 ) + 0 )
+!define WAIT_ABANDONED_0       0x80 ;((STATUS_ABANDONED_WAIT_0 ) + 0 )
+
+!define DRIVE_UNKNOWN     0
+!define DRIVE_NO_ROOT_DIR 1
+!define DRIVE_REMOVABLE   2
+!define DRIVE_FIXED       3
+!define DRIVE_REMOTE      4
+!define DRIVE_CDROM       5
+!define DRIVE_RAMDISK     6
+
+!define FILE_TYPE_UNKNOWN   0x0000
+!define FILE_TYPE_DISK      0x0001
+!define FILE_TYPE_CHAR      0x0002
+!define FILE_TYPE_PIPE      0x0003
+!define FILE_TYPE_REMOTE    0x8000
+
+!define STD_INPUT_HANDLE   -10
+!define STD_OUTPUT_HANDLE  -11
+!define STD_ERROR_HANDLE   -12
+
+#define IGNORE              0       ; Ignore signal
+!define INFINITE            0xFFFFFFFF  ; Infinite timeout
+
+!endif /* __WIN_NOINC_WINBASE */
+
+
+
+
+
+/**************************************************
+WinGDI.h
+**************************************************/
+!ifndef __WIN_MS_NOGDI & __WIN_NOINC_WINGDI
+!define HORZRES       8 
+!define VERTRES       10
+!define BITSPIXEL     12
+!define LOGPIXELSX    88
+!define LOGPIXELSY    90
+!define COLORRES     108
+!define VREFRESH     116
+!define DESKTOPVERTRES 117
+!define DESKTOPHORZRES 118
+!endif /* __WIN_MS_NOGDI & __WIN_NOINC_WINGDI */
+
+
+
+
+
+/**************************************************
+WinReg.h
+**************************************************/
+!ifndef __WIN_NOINC_WINREG
+!ifndef __WIN_NOHKEY & HKEY_CLASSES_ROOT & HKEY_CURRENT_USER & HKEY_LOCAL_MACHINE & HKEY_USERS
+!define HKEY_CLASSES_ROOT        0x80000000
+!define HKEY_CURRENT_USER        0x80000001
+!define HKEY_LOCAL_MACHINE       0x80000002
+!define HKEY_USERS               0x80000003
+!define HKEY_PERFORMANCE_DATA    0x80000004
+!define HKEY_PERFORMANCE_TEXT    0x80000050
+!define HKEY_PERFORMANCE_NLSTEXT 0x80000060
+!define HKEY_CURRENT_CONFIG      0x80000005
+!define HKEY_DYN_DATA            0x80000006
+!ifndef __WIN_NOSHORTHKEY & HKCR & HKCU & HKLM
+!define HKCR ${HKEY_CLASSES_ROOT}
+!define HKCU ${HKEY_CURRENT_USER}
+!define HKLM ${HKEY_LOCAL_MACHINE}
+!endif
+!endif
+!endif /* __WIN_NOINC_WINREG */
+
+
+
+
+
+/**************************************************
+WindowsX.h
+**************************************************/
+!ifndef __WIN_NOINC_WINDOWSX
+!ifndef GET_X_LPARAM & GET_Y_LPARAM
+!macro _Win_GET_X_LPARAM _outvar _in
+IntOp ${_outvar} "${_in}" << 16   ;We can't just use LOWORD, we need to keep the sign,
+IntOp ${_outvar} ${_outvar} >> 16 ;so we let NSIS sign extend for us
+!macroend
+!define GET_X_LPARAM "!insertmacro _Win_GET_X_LPARAM "
+!macro _Win_GET_Y_LPARAM _outvar _in
+IntOp ${_outvar} "${_in}" >> 16
+!macroend
+!define GET_Y_LPARAM "!insertmacro _Win_GET_Y_LPARAM "
+!endif
+!endif /* __WIN_NOINC_WINDOWSX */
+
+
+
+
+
+/**************************************************
+ShlObj.h
+**************************************************/
+!ifndef __WIN_NOINC_SHLOBJ
+!ifndef __WIN_NOSHELLFOLDERCSIDL
+!define CSIDL_DESKTOP                 0x0000
+!define CSIDL_INTERNET                0x0001 ;Internet Explorer (icon on desktop)
+!define CSIDL_PROGRAMS                0x0002 ;Start Menu\Programs
+!define CSIDL_CONTROLS                0x0003 ;My Computer\Control Panel
+!define CSIDL_PRINTERS                0x0004 ;My Computer\Printers
+!define CSIDL_PERSONAL                0x0005 ;My Documents
+!define CSIDL_FAVORITES               0x0006 ;<user name>\Favorites
+!define CSIDL_STARTUP                 0x0007 ;Start Menu\Programs\Startup
+!define CSIDL_RECENT                  0x0008 ;<user name>\Recent
+!define CSIDL_SENDTO                  0x0009 ;<user name>\SendTo
+!define CSIDL_BITBUCKET               0x000a ;<desktop>\Recycle Bin
+!define CSIDL_STARTMENU               0x000b ;<user name>\Start Menu
+!define CSIDL_MYDOCUMENTS             0x000c ;logical "My Documents" desktop icon
+!define CSIDL_MYMUSIC                 0x000d ;"My Music" folder
+!define CSIDL_MYVIDEO                 0x000e ;"My Videos" folder
+!define CSIDL_DESKTOPDIRECTORY        0x0010 ;<user name>\Desktop
+!define CSIDL_DRIVES                  0x0011 ;My Computer
+!define CSIDL_NETWORK                 0x0012 ;Network Neighborhood
+!define CSIDL_NETHOOD                 0x0013 ;<user name>\nethood
+!define CSIDL_FONTS                   0x0014 ;windows\fonts
+!define CSIDL_TEMPLATES               0x0015
+!define CSIDL_COMMON_STARTMENU        0x0016 ;All Users\Start Menu
+!define CSIDL_COMMON_PROGRAMS         0x0017 ;All Users\Start Menu\Programs
+!define CSIDL_COMMON_STARTUP          0x0018 ;All Users\Startup
+!define CSIDL_COMMON_DESKTOPDIRECTORY 0x0019 ;All Users\Desktop
+!define CSIDL_APPDATA                 0x001a ;<user name>\Application Data
+!define CSIDL_PRINTHOOD               0x001b ;<user name>\PrintHood
+!define CSIDL_LOCAL_APPDATA           0x001c ;<user name>\Local Settings\Applicaiton Data (non roaming)
+!define CSIDL_ALTSTARTUP              0x001d ;non localized startup
+!define CSIDL_COMMON_ALTSTARTUP       0x001e ;non localized common startup
+!define CSIDL_COMMON_FAVORITES        0x001f
+!define CSIDL_INTERNET_CACHE          0x0020
+!define CSIDL_COOKIES                 0x0021
+!define CSIDL_HISTORY                 0x0022
+!define CSIDL_COMMON_APPDATA          0x0023 ;All Users\Application Data
+!define CSIDL_WINDOWS                 0x0024 ;GetWindowsDirectory
+!define CSIDL_SYSTEM                  0x0025 ;GetSystemDirectory
+!define CSIDL_PROGRAM_FILES           0x0026 ;C:\Program Files
+!define CSIDL_MYPICTURES              0x0027
+!define CSIDL_PROFILE                 0x0028 ;USERPROFILE
+!define CSIDL_SYSTEMX86               0x0029 ;x86 system directory on RISC
+!define CSIDL_PROGRAM_FILESX86        0x002a ;x86 C:\Program Files on RISC
+!define CSIDL_PROGRAM_FILES_COMMON    0x002b ;C:\Program Files\Common
+!define CSIDL_PROGRAM_FILES_COMMONX86 0x002c ;x86 Program Files\Common on RISC
+!define CSIDL_COMMON_TEMPLATES        0x002d ;All Users\Templates
+!define CSIDL_COMMON_DOCUMENTS        0x002e ;All Users\Documents
+!define CSIDL_COMMON_ADMINTOOLS       0x002f ;All Users\Start Menu\Programs\Administrative Tools
+!define CSIDL_ADMINTOOLS              0x0030 ;<user name>\Start Menu\Programs\Administrative Tools
+!define CSIDL_CONNECTIONS             0x0031 ;Network and Dial-up Connections
+!define CSIDL_COMMON_MUSIC            0x0035 ;All Users\My Music
+!define CSIDL_COMMON_PICTURES         0x0036 ;All Users\My Pictures
+!define CSIDL_COMMON_VIDEO            0x0037 ;All Users\My Video
+!define CSIDL_RESOURCES               0x0038 ;Resource Direcotry
+!define CSIDL_RESOURCES_LOCALIZED     0x0039 ;Localized Resource Direcotry
+!define CSIDL_COMMON_OEM_LINKS        0x003a ;Links to All Users OEM specific apps
+!define CSIDL_CDBURN_AREA             0x003b ;USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
+!define CSIDL_COMPUTERSNEARME         0x003d ;Computers Near Me (computered from Workgroup membership)
+!define CSIDL_FLAG_CREATE             0x8000 ;combine with CSIDL_ value to force folder creation in SHGetFolderPath()
+!define CSIDL_FLAG_DONT_VERIFY        0x4000 ;combine with CSIDL_ value to return an unverified folder path
+!define CSIDL_FLAG_NO_ALIAS           0x1000 ;combine with CSIDL_ value to insure non-alias versions of the pidl
+!define CSIDL_FLAG_PER_USER_INIT      0x0800 ;combine with CSIDL_ value to indicate per-user init (eg. upgrade)
+!define CSIDL_FLAG_MASK               0xFF00
+!endif /* __WIN_NOSHELLFOLDERCSIDL */
+!endif /* __WIN_NOINC_SHLOBJ */
+
+
+
+
+
+/**************************************************
+Shobjidl.h
+**************************************************/
+!ifndef __WIN_NOINC_SHOBJIDL
+; ASSOCIATIONLEVEL
+!define AL_MACHINE 0
+!define AL_EFFECTIVE 1
+!define AL_USER 2
+
+; ASSOCIATIONTYPE
+!define AT_FILEEXTENSION 0
+!define AT_URLPROTOCOL 1
+!define AT_STARTMENUCLIENT 2
+!define AT_MIMETYPE 3
+!endif /* __WIN_NOINC_SHOBJIDL */
+
+
+
+!verbose pop
+!endif /* __WIN_WINDOWS__INC */

+ 706 - 0
assets/nsis/Include/WinMessages.nsh

@@ -0,0 +1,706 @@
+/*
+_____________________________________________________________________________
+
+                       List of common Windows Messages
+_____________________________________________________________________________
+
+ 2005 Shengalts Aleksander aka Instructor (Shengalts@mail.ru)
+
+
+Usage example:
+---------------------------------------------------
+Name "Output"
+OutFile "Output.exe"
+
+!include "WinMessages.nsh"
+
+Section
+	FindWindow $0 '#32770' '' $HWNDPARENT
+	GetDlgItem $1 $0 1027
+	SendMessage $1 ${WM_SETTEXT} 0 'STR:MyText'
+SectionEnd
+---------------------------------------------------
+
+
+Prefix  Message category
+-------------------------
+SW      ShowWindow Commands
+CCM     Generic Common Control
+BM      Button control
+CB      Combo box control
+EM      Edit control
+LB      List box control
+WM      General window
+ABM     Application desktop toolbar
+DBT     Device
+DM      Default push button control
+HDM     Header control
+LVM     List view control
+SB      Status bar window
+SBM     Scroll bar control
+STM     Static control
+TCM     Tab control
+PBM     Progress bar
+-----------------------------------
+
+NOT included messages (WM_USER + X)
+-----------------------------------
+CBEM    Extended combo box control
+CDM     Common dialog box
+DL      Drag list box
+DTM     Date and time picker control
+HKM     Hot key control
+IPM     IP address control
+MCM     Month calendar control
+PGM     Pager control
+PSM     Property sheet
+RB      Rebar control
+TB      Toolbar
+TBM     Trackbar
+TTM     Tooltip control
+TVM     Tree-view control
+UDM     Up-down control
+-----------------------------------
+*/
+
+
+!ifndef WINMESSAGES_INCLUDED
+!define WINMESSAGES_INCLUDED
+!verbose push
+!verbose 3
+
+!define _NSIS_DEFAW '!insertmacro _NSIS_DEFAW '
+!macro _NSIS_DEFAW d
+!ifdef NSIS_UNICODE
+!define ${d} "${${d}W}"
+!else
+!define ${d} "${${d}A}"
+!endif
+!macroend
+
+!define HWND_BROADCAST      0xFFFF
+
+#ShowWindow Commands#
+!define SW_HIDE             0
+!define SW_SHOWNORMAL       1
+!define SW_NORMAL           1
+!define SW_SHOWMINIMIZED    2
+!define SW_SHOWMAXIMIZED    3
+!define SW_MAXIMIZE         3
+!define SW_SHOWNOACTIVATE   4
+!define SW_SHOW             5
+!define SW_MINIMIZE         6
+!define SW_SHOWMINNOACTIVE  7
+!define SW_SHOWNA           8
+!define SW_RESTORE          9
+!define SW_SHOWDEFAULT      10
+!define SW_FORCEMINIMIZE    11
+!define SW_MAX              11
+
+#Generic Common Control Messages#
+!define CCM_FIRST 0x2000
+!define /math CCM_SETBKCOLOR       ${CCM_FIRST} + 0x1 ; IE4
+!define /math CCM_SETUNICODEFORMAT ${CCM_FIRST} + 0x5 
+!define /math CCM_GETUNICODEFORMAT ${CCM_FIRST} + 0x6
+!define /math CCM_SETVERSION       ${CCM_FIRST} + 0x7 ; IE5
+!define /math CCM_GETVERSION       ${CCM_FIRST} + 0x8
+!define /math CCM_SETWINDOWTHEME   ${CCM_FIRST} + 0xB ; WinXP
+!define /math CCM_DPISCALE         ${CCM_FIRST} + 0xC
+
+!define CCS_TOP 1
+!define CCS_BOTTOM 3
+!define CCS_NODIVIDER 64
+!define CCS_LEFT 129
+!define CCS_RIGHT 131
+
+!define I_IMAGENONE -2
+
+#Button Control Messages#
+!define BM_CLICK           0x00F5
+!define BM_GETCHECK        0x00F0
+!define BM_GETIMAGE        0x00F6
+!define BM_GETSTATE        0x00F2
+!define BM_SETCHECK        0x00F1
+!define BM_SETIMAGE        0x00F7
+!define BM_SETSTATE        0x00F3
+!define BM_SETSTYLE        0x00F4
+!define BCM_SETSHIELD      0x160C ; WinVista + ComCtl32 v6
+
+!define BST_UNCHECKED      0
+!define BST_CHECKED        1
+!define BST_INDETERMINATE  2
+!define BST_PUSHED         4
+!define BST_FOCUS          8
+
+#Combo Box Messages#
+!define CB_ADDSTRING                0x0143
+!define CB_DELETESTRING             0x0144
+!define CB_DIR                      0x0145
+!define CB_FINDSTRING               0x014C
+!define CB_FINDSTRINGEXACT          0x0158
+!define CB_GETCOUNT                 0x0146
+!define CB_GETCURSEL                0x0147
+!define CB_GETDROPPEDCONTROLRECT    0x0152
+!define CB_GETDROPPEDSTATE          0x0157
+!define CB_GETDROPPEDWIDTH          0x015f
+!define CB_GETEDITSEL               0x0140
+!define CB_GETEXTENDEDUI            0x0156
+!define CB_GETHORIZONTALEXTENT      0x015d
+!define CB_GETITEMDATA              0x0150
+!define CB_GETITEMHEIGHT            0x0154
+!define CB_GETLBTEXT                0x0148
+!define CB_GETLBTEXTLEN             0x0149
+!define CB_GETLOCALE                0x015A
+!define CB_GETTOPINDEX              0x015b
+!define CB_INITSTORAGE              0x0161
+!define CB_INSERTSTRING             0x014A
+!define CB_LIMITTEXT                0x0141
+!define CB_MSGMAX                   0x015B  # 0x0162 0x0163
+!define CB_MULTIPLEADDSTRING        0x0163
+!define CB_RESETCONTENT             0x014B
+!define CB_SELECTSTRING             0x014D
+!define CB_SETCURSEL                0x014E
+!define CB_SETDROPPEDWIDTH          0x0160
+!define CB_SETEDITSEL               0x0142
+!define CB_SETEXTENDEDUI            0x0155
+!define CB_SETHORIZONTALEXTENT      0x015e
+!define CB_SETITEMDATA              0x0151
+!define CB_SETITEMHEIGHT            0x0153
+!define CB_SETLOCALE                0x0159
+!define CB_SETTOPINDEX              0x015c
+!define CB_SHOWDROPDOWN             0x014F
+
+!define CB_ERR                      -1
+
+#Edit Control Messages#
+!define EM_CANUNDO              0x00C6
+!define EM_CHARFROMPOS          0x00D7
+!define EM_EMPTYUNDOBUFFER      0x00CD
+!define EM_EXLIMITTEXT          0x0435
+!define EM_FMTLINES             0x00C8
+!define EM_GETFIRSTVISIBLELINE  0x00CE
+!define EM_GETHANDLE            0x00BD
+!define EM_GETIMESTATUS         0x00D9
+!define EM_GETLIMITTEXT         0x00D5
+!define EM_GETLINE              0x00C4
+!define EM_GETLINECOUNT         0x00BA
+!define EM_GETMARGINS           0x00D4
+!define EM_GETMODIFY            0x00B8
+!define EM_GETPASSWORDCHAR      0x00D2
+!define EM_GETRECT              0x00B2
+!define EM_GETSEL               0x00B0
+!define EM_GETTHUMB             0x00BE
+!define EM_GETWORDBREAKPROC     0x00D1
+!define EM_LIMITTEXT            0x00C5
+!define EM_LINEFROMCHAR         0x00C9
+!define EM_LINEINDEX            0x00BB
+!define EM_LINELENGTH           0x00C1
+!define EM_LINESCROLL           0x00B6
+!define EM_POSFROMCHAR          0x00D6
+!define EM_REPLACESEL           0x00C2
+!define EM_SCROLL               0x00B5
+!define EM_SCROLLCARET          0x00B7
+!define EM_SETHANDLE            0x00BC
+!define EM_SETIMESTATUS         0x00D8
+!define EM_SETLIMITTEXT         0x00C5  # Same as EM_LIMITTEXT
+!define EM_SETMARGINS           0x00D3
+!define EM_SETMODIFY            0x00B9
+!define EM_SETPASSWORDCHAR      0x00CC
+!define EM_SETREADONLY          0x00CF
+!define EM_SETRECT              0x00B3
+!define EM_SETRECTNP            0x00B4
+!define EM_SETSEL               0x00B1
+!define EM_SETTABSTOPS          0x00CB
+!define EM_SETWORDBREAKPROC     0x00D0
+!define EM_UNDO                 0x00C7
+
+#Listbox Messages#
+!define LB_ADDFILE              0x0196
+!define LB_ADDSTRING            0x0180
+!define LB_DELETESTRING         0x0182
+!define LB_DIR                  0x018D
+!define LB_FINDSTRING           0x018F
+!define LB_FINDSTRINGEXACT      0x01A2
+!define LB_GETANCHORINDEX       0x019D
+!define LB_GETCARETINDEX        0x019F
+!define LB_GETCOUNT             0x018B
+!define LB_GETCURSEL            0x0188
+!define LB_GETHORIZONTALEXTENT  0x0193
+!define LB_GETITEMDATA          0x0199
+!define LB_GETITEMHEIGHT        0x01A1
+!define LB_GETITEMRECT          0x0198
+!define LB_GETLOCALE            0x01A6
+!define LB_GETSEL               0x0187
+!define LB_GETSELCOUNT          0x0190
+!define LB_GETSELITEMS          0x0191
+!define LB_GETTEXT              0x0189
+!define LB_GETTEXTLEN           0x018A
+!define LB_GETTOPINDEX          0x018E
+!define LB_INITSTORAGE          0x01A8
+!define LB_INSERTSTRING         0x0181
+!define LB_ITEMFROMPOINT        0x01A9
+!define LB_MSGMAX               0x01A8  # 0x01B0 0x01B1
+!define LB_MULTIPLEADDSTRING    0x01B1
+!define LB_RESETCONTENT         0x0184
+!define LB_SELECTSTRING         0x018C
+!define LB_SELITEMRANGE         0x019B
+!define LB_SELITEMRANGEEX       0x0183
+!define LB_SETANCHORINDEX       0x019C
+!define LB_SETCARETINDEX        0x019E
+!define LB_SETCOLUMNWIDTH       0x0195
+!define LB_SETCOUNT             0x01A7
+!define LB_SETCURSEL            0x0186
+!define LB_SETHORIZONTALEXTENT  0x0194
+!define LB_SETITEMDATA          0x019A
+!define LB_SETITEMHEIGHT        0x01A0
+!define LB_SETLOCALE            0x01A5
+!define LB_SETSEL               0x0185
+!define LB_SETTABSTOPS          0x0192
+!define LB_SETTOPINDEX          0x0197
+
+!define LB_ERR                  -1
+
+#Window Messages#
+!define WM_ACTIVATE                     0x0006
+!define WM_ACTIVATEAPP                  0x001C
+!define WM_AFXFIRST                     0x0360
+!define WM_AFXLAST                      0x037F
+!define WM_APP                          0x8000
+!define WM_APPCOMMAND                   0x0319
+!define WM_ASKCBFORMATNAME              0x030C
+!define WM_CANCELJOURNAL                0x004B
+!define WM_CANCELMODE                   0x001F
+!define WM_CAPTURECHANGED               0x0215
+!define WM_CHANGECBCHAIN                0x030D
+!define WM_CHANGEUISTATE                0x0127
+!define WM_CHAR                         0x0102
+!define WM_CHARTOITEM                   0x002F
+!define WM_CHILDACTIVATE                0x0022
+!define WM_CLEAR                        0x0303
+!define WM_CLOSE                        0x0010
+!define WM_COMMAND                      0x0111
+!define WM_COMMNOTIFY                   0x0044  # no longer suported
+!define WM_COMPACTING                   0x0041
+!define WM_COMPAREITEM                  0x0039
+!define WM_CONTEXTMENU                  0x007B
+!define WM_CONVERTREQUESTEX             0x108
+!define WM_COPY                         0x0301
+!define WM_COPYDATA                     0x004A
+!define WM_CREATE                       0x0001
+!define WM_CTLCOLOR                     0x0019
+!define WM_CTLCOLORBTN                  0x0135
+!define WM_CTLCOLORDLG                  0x0136
+!define WM_CTLCOLOREDIT                 0x0133
+!define WM_CTLCOLORLISTBOX              0x0134
+!define WM_CTLCOLORMSGBOX               0x0132
+!define WM_CTLCOLORSCROLLBAR            0x0137
+!define WM_CTLCOLORSTATIC               0x0138
+!define WM_CUT                          0x0300
+!define WM_DDE_FIRST                    0x3E0
+!define WM_DEADCHAR                     0x0103
+!define WM_DELETEITEM                   0x002D
+!define WM_DESTROY                      0x0002
+!define WM_DESTROYCLIPBOARD             0x0307
+!define WM_DEVICECHANGE                 0x0219
+!define WM_DEVMODECHANGE                0x001B
+!define WM_DISPLAYCHANGE                0x007E
+!define WM_DRAWCLIPBOARD                0x0308
+!define WM_DRAWITEM                     0x002B
+!define WM_DROPFILES                    0x0233
+!define WM_ENABLE                       0x000A
+!define WM_ENDSESSION                   0x0016
+!define WM_ENTERIDLE                    0x0121
+!define WM_ENTERMENULOOP                0x0211
+!define WM_ENTERSIZEMOVE                0x0231
+!define WM_ERASEBKGND                   0x0014
+!define WM_EXITMENULOOP                 0x0212
+!define WM_EXITSIZEMOVE                 0x0232
+!define WM_FONTCHANGE                   0x001D
+!define WM_GETDLGCODE                   0x0087
+!define WM_GETFONT                      0x0031
+!define WM_GETHOTKEY                    0x0033
+!define WM_GETICON                      0x007F
+!define WM_GETMINMAXINFO                0x0024
+!define WM_GETOBJECT                    0x003D
+!define WM_GETTEXT                      0x000D
+!define WM_GETTEXTLENGTH                0x000E
+!define WM_HANDHELDFIRST                0x0358
+!define WM_HANDHELDLAST                 0x035F
+!define WM_HELP                         0x0053
+!define WM_HOTKEY                       0x0312
+!define WM_HSCROLL                      0x0114
+!define WM_HSCROLLCLIPBOARD             0x030E
+!define WM_ICONERASEBKGND               0x0027
+!define WM_IME_CHAR                     0x0286
+!define WM_IME_COMPOSITION              0x010F
+!define WM_IME_COMPOSITIONFULL          0x0284
+!define WM_IME_CONTROL                  0x0283
+!define WM_IME_ENDCOMPOSITION           0x010E
+!define WM_IME_KEYDOWN                  0x0290
+!define WM_IME_KEYLAST                  0x010F
+!define WM_IME_KEYUP                    0x0291
+!define WM_IME_NOTIFY                   0x0282
+!define WM_IME_REQUEST                  0x0288
+!define WM_IME_SELECT                   0x0285
+!define WM_IME_SETCONTEXT               0x0281
+!define WM_IME_STARTCOMPOSITION         0x010D
+!define WM_INITDIALOG                   0x0110
+!define WM_INITMENU                     0x0116
+!define WM_INITMENUPOPUP                0x0117
+!define WM_INPUT                        0x00FF
+!define WM_INPUTLANGCHANGE              0x0051
+!define WM_INPUTLANGCHANGEREQUEST       0x0050
+!define WM_KEYDOWN                      0x0100
+!define WM_KEYFIRST                     0x0100
+!define WM_KEYLAST                      0x0108
+!define WM_KEYUP                        0x0101
+!define WM_KILLFOCUS                    0x0008
+!define WM_LBUTTONDBLCLK                0x0203
+!define WM_LBUTTONDOWN                  0x0201
+!define WM_LBUTTONUP                    0x0202
+!define WM_MBUTTONDBLCLK                0x0209
+!define WM_MBUTTONDOWN                  0x0207
+!define WM_MBUTTONUP                    0x0208
+!define WM_MDIACTIVATE                  0x0222
+!define WM_MDICASCADE                   0x0227
+!define WM_MDICREATE                    0x0220
+!define WM_MDIDESTROY                   0x0221
+!define WM_MDIGETACTIVE                 0x0229
+!define WM_MDIICONARRANGE               0x0228
+!define WM_MDIMAXIMIZE                  0x0225
+!define WM_MDINEXT                      0x0224
+!define WM_MDIREFRESHMENU               0x0234
+!define WM_MDIRESTORE                   0x0223
+!define WM_MDISETMENU                   0x0230
+!define WM_MDITILE                      0x0226
+!define WM_MEASUREITEM                  0x002C
+!define WM_MENUCHAR                     0x0120
+!define WM_MENUCOMMAND                  0x0126
+!define WM_MENUDRAG                     0x0123
+!define WM_MENUGETOBJECT                0x0124
+!define WM_MENURBUTTONUP                0x0122
+!define WM_MENUSELECT                   0x011F
+!define WM_MOUSEACTIVATE                0x0021
+!define WM_MOUSEFIRST                   0x0200
+!define WM_MOUSEHOVER                   0x02A1
+!define WM_MOUSELAST                    0x0209  # 0x020A 0x020D
+!define WM_MOUSELEAVE                   0x02A3
+!define WM_MOUSEMOVE                    0x0200
+!define WM_MOUSEWHEEL                   0x020A
+!define WM_MOVE                         0x0003
+!define WM_MOVING                       0x0216
+!define WM_NCACTIVATE                   0x0086
+!define WM_NCCALCSIZE                   0x0083
+!define WM_NCCREATE                     0x0081
+!define WM_NCDESTROY                    0x0082
+!define WM_NCHITTEST                    0x0084
+!define WM_NCLBUTTONDBLCLK              0x00A3
+!define WM_NCLBUTTONDOWN                0x00A1
+!define WM_NCLBUTTONUP                  0x00A2
+!define WM_NCMBUTTONDBLCLK              0x00A9
+!define WM_NCMBUTTONDOWN                0x00A7
+!define WM_NCMBUTTONUP                  0x00A8
+!define WM_NCMOUSEHOVER                 0x02A0
+!define WM_NCMOUSELEAVE                 0x02A2
+!define WM_NCMOUSEMOVE                  0x00A0
+!define WM_NCPAINT                      0x0085
+!define WM_NCRBUTTONDBLCLK              0x00A6
+!define WM_NCRBUTTONDOWN                0x00A4
+!define WM_NCRBUTTONUP                  0x00A5
+!define WM_NCXBUTTONDBLCLK              0x00AD
+!define WM_NCXBUTTONDOWN                0x00AB
+!define WM_NCXBUTTONUP                  0x00AC
+!define WM_NEXTDLGCTL                   0x0028
+!define WM_NEXTMENU                     0x0213
+!define WM_NOTIFY                       0x004E
+!define WM_NOTIFYFORMAT                 0x0055
+!define WM_NULL                         0x0000
+!define WM_PAINT                        0x000F
+!define WM_PAINTCLIPBOARD               0x0309
+!define WM_PAINTICON                    0x0026
+!define WM_PALETTECHANGED               0x0311
+!define WM_PALETTEISCHANGING            0x0310
+!define WM_PARENTNOTIFY                 0x0210
+!define WM_PASTE                        0x0302
+!define WM_PENWINFIRST                  0x0380
+!define WM_PENWINLAST                   0x038F
+!define WM_POWER                        0x0048
+!define WM_POWERBROADCAST               0x0218
+!define WM_PRINT                        0x0317
+!define WM_PRINTCLIENT                  0x0318
+!define WM_QUERYDRAGICON                0x0037
+!define WM_QUERYENDSESSION              0x0011
+!define WM_QUERYNEWPALETTE              0x030F
+!define WM_QUERYOPEN                    0x0013
+!define WM_QUERYUISTATE                 0x0129
+!define WM_QUEUESYNC                    0x0023
+!define WM_QUIT                         0x0012
+!define WM_RBUTTONDBLCLK                0x0206
+!define WM_RBUTTONDOWN                  0x0204
+!define WM_RBUTTONUP                    0x0205
+!define WM_RASDIALEVENT                 0xCCCD
+!define WM_RENDERALLFORMATS             0x0306
+!define WM_RENDERFORMAT                 0x0305
+!define WM_SETCURSOR                    0x0020
+!define WM_SETFOCUS                     0x0007
+!define WM_SETFONT                      0x0030
+!define WM_SETHOTKEY                    0x0032
+!define WM_SETICON                      0x0080
+!define WM_SETREDRAW                    0x000B
+!define WM_SETTEXT                      0x000C
+!define WM_SETTINGCHANGE                0x001A  # Same as WM_WININICHANGE
+!define WM_SHOWWINDOW                   0x0018
+!define WM_SIZE                         0x0005
+!define WM_SIZECLIPBOARD                0x030B
+!define WM_SIZING                       0x0214
+!define WM_SPOOLERSTATUS                0x002A
+!define WM_STYLECHANGED                 0x007D
+!define WM_STYLECHANGING                0x007C
+!define WM_SYNCPAINT                    0x0088
+!define WM_SYSCHAR                      0x0106
+!define WM_SYSCOLORCHANGE               0x0015
+!define WM_SYSCOMMAND                   0x0112
+!define WM_SYSDEADCHAR                  0x0107
+!define WM_SYSKEYDOWN                   0x0104
+!define WM_SYSKEYUP                     0x0105
+!define WM_TABLET_FIRST                 0x02C0
+!define WM_TABLET_LAST                  0x02DF
+!define WM_THEMECHANGED                 0x031A
+!define WM_TCARD                        0x0052
+!define WM_TIMECHANGE                   0x001E
+!define WM_TIMER                        0x0113
+!define WM_UNDO                         0x0304
+!define WM_UNICHAR                      0x0109
+!define WM_UNINITMENUPOPUP              0x0125
+!define WM_UPDATEUISTATE                0x0128
+!define WM_USER                         0x400
+!define WM_USERCHANGED                  0x0054
+!define WM_VKEYTOITEM                   0x002E
+!define WM_VSCROLL                      0x0115
+!define WM_VSCROLLCLIPBOARD             0x030A
+!define WM_WINDOWPOSCHANGED             0x0047
+!define WM_WINDOWPOSCHANGING            0x0046
+!define WM_WININICHANGE                 0x001A
+!define WM_WTSSESSION_CHANGE            0x02B1
+!define WM_XBUTTONDBLCLK                0x020D
+!define WM_XBUTTONDOWN                  0x020B
+!define WM_XBUTTONUP                    0x020C
+
+
+#Application desktop toolbar#
+!define ABM_ACTIVATE         0x00000006  # lParam == TRUE/FALSE means activate/deactivate
+!define ABM_GETAUTOHIDEBAR   0x00000007
+!define ABM_GETSTATE         0x00000004
+!define ABM_GETTASKBARPOS    0x00000005
+!define ABM_NEW              0x00000000
+!define ABM_QUERYPOS         0x00000002
+!define ABM_REMOVE           0x00000001
+!define ABM_SETAUTOHIDEBAR   0x00000008  # This can fail, you MUST check the result
+!define ABM_SETPOS           0x00000003
+!define ABM_WINDOWPOSCHANGED 0x0000009
+
+#Device#
+!define DBT_APPYBEGIN                   0x0000
+!define DBT_APPYEND                     0x0001
+!define DBT_CONFIGCHANGECANCELED        0x0019
+!define DBT_CONFIGCHANGED               0x0018
+!define DBT_CONFIGMGAPI32               0x0022
+!define DBT_CONFIGMGPRIVATE             0x7FFF
+!define DBT_CUSTOMEVENT                 0x8006  # User-defined event
+!define DBT_DEVICEARRIVAL               0x8000  # System detected a new device
+!define DBT_DEVICEQUERYREMOVE           0x8001  # Wants to remove, may fail
+!define DBT_DEVICEQUERYREMOVEFAILED     0x8002  # Removal aborted
+!define DBT_DEVICEREMOVECOMPLETE        0x8004  # Device is gone
+!define DBT_DEVICEREMOVEPENDING         0x8003  # About to remove, still avail.
+!define DBT_DEVICETYPESPECIFIC          0x8005  # Type specific event
+!define DBT_DEVNODES_CHANGED            0x0007
+!define DBT_DEVTYP_DEVICEINTERFACE      0x00000005  # Device interface class
+!define DBT_DEVTYP_DEVNODE              0x00000001  # Devnode number
+!define DBT_DEVTYP_HANDLE               0x00000006  # File system handle
+!define DBT_DEVTYP_NET                  0x00000004  # Network resource
+!define DBT_DEVTYP_OEM                  0x00000000  # Oem-defined device type
+!define DBT_DEVTYP_PORT                 0x00000003  # Serial, parallel
+!define DBT_DEVTYP_VOLUME               0x00000002  # Logical volume
+!define DBT_LOW_DISK_SPACE              0x0048
+!define DBT_MONITORCHANGE               0x001B
+!define DBT_NO_DISK_SPACE               0x0047
+!define DBT_QUERYCHANGECONFIG           0x0017
+!define DBT_SHELLLOGGEDON               0x0020
+!define DBT_USERDEFINED                 0xFFFF
+!define DBT_VOLLOCKLOCKFAILED           0x8043
+!define DBT_VOLLOCKLOCKRELEASED         0x8045
+!define DBT_VOLLOCKLOCKTAKEN            0x8042
+!define DBT_VOLLOCKQUERYLOCK            0x8041
+!define DBT_VOLLOCKQUERYUNLOCK          0x8044
+!define DBT_VOLLOCKUNLOCKFAILED         0x8046
+!define DBT_VPOWERDAPI                  0x8100  # VPOWERD API for Win95
+!define DBT_VXDINITCOMPLETE             0x0023
+
+#Default push button control#
+!define DM_BITSPERPEL       0x00040000
+!define DM_COLLATE          0x00008000
+!define DM_COLOR            0x00000800
+!define DM_COPIES           0x00000100
+!define DM_DEFAULTSOURCE    0x00000200
+!define DM_DISPLAYFLAGS     0x00200000
+!define DM_DISPLAYFREQUENCY 0x00400000
+!define DM_DITHERTYPE       0x04000000
+!define DM_DUPLEX           0x00001000
+!define DM_FORMNAME         0x00010000
+!define DM_GRAYSCALE        0x00000001  # This flag is no longer valid
+!define DM_ICMINTENT        0x01000000
+!define DM_ICMMETHOD        0x00800000
+!define DM_INTERLACED       0x00000002  # This flag is no longer valid
+!define DM_LOGPIXELS        0x00020000
+!define DM_MEDIATYPE        0x02000000
+!define DM_NUP              0x00000040
+!define DM_ORIENTATION      0x00000001
+!define DM_PANNINGHEIGHT    0x10000000
+!define DM_PANNINGWIDTH     0x08000000
+!define DM_PAPERLENGTH      0x00000004
+!define DM_PAPERSIZE        0x00000002
+!define DM_PAPERWIDTH       0x00000008
+!define DM_PELSHEIGHT       0x00100000
+!define DM_PELSWIDTH        0x00080000
+!define DM_POSITION         0x00000020
+!define DM_PRINTQUALITY     0x00000400
+!define DM_SCALE            0x00000010
+!define DM_SPECVERSION      0x0320       # 0x0400 0x0401
+!define DM_TTOPTION         0x00004000
+!define DM_YRESOLUTION      0x00002000
+
+#Header control#
+!define HDM_FIRST           0x1200
+
+#List view control#
+!define LVS_SINGLESEL           4
+!define LVS_SHOWSELALWAYS       8
+!define LVS_SORTASCENDING    0x10
+!define LVS_SORTDESCENDING   0x20
+!define LVS_SHAREIMAGELISTS  0x40
+!define LVS_EDITLABELS      0x200
+!define LVS_NOSCROLL       0x2000
+!define LVS_NOCOLUMNHEADER 0x4000
+!define LVS_NOSORTHEADER   0x8000
+!define LVS_ICON      0
+!define LVS_REPORT    1
+!define LVS_SMALLICON 2
+!define LVS_LIST      3
+!define LVS_EX_CHECKBOXES         4
+!define LVS_EX_FULLROWSELECT   0x20
+!define LVS_EX_INFOTIP        0x400
+!define LVS_EX_LABELTIP      0x4000
+!define LVS_EX_DOUBLEBUFFER 0x10000
+!define LVIF_TEXT  1
+!define LVIF_IMAGE 2
+!define LVIF_PARAM 4
+!define LVIF_STATE 8
+!define LVIS_STATEIMAGEMASK 0xF000
+!define LVCF_FMT     1
+!define LVCF_WIDTH   2
+!define LVCF_TEXT    4
+!define LVCF_SUBITEM 8
+!define SYSSTRUCT_LVITEM_V1 (i,i,i,i,&i${NSIS_PTR_SIZE},t,i,i,p)
+!define SYSSTRUCT_LVITEM_V2 (i,i,i,i,&i${NSIS_PTR_SIZE},t,i,i,p,i)           ; IE3
+!define SYSSTRUCT_LVITEM_V3 (i,i,i,i,&i${NSIS_PTR_SIZE},t,i,i,p,i,i,i,i)     ; WinXP + ComCtl32 v6
+!define SYSSTRUCT_LVITEM_V4 (i,i,i,i,&i${NSIS_PTR_SIZE},t,i,i,p,i,i,i,i,i,i) ; WinVista + ComCtl32 v6
+!define LVSCW_AUTOSIZE -1
+!define LVSCW_AUTOSIZE_USEHEADER -2
+!define LVM_FIRST                          0x00001000
+!define /math LVM_GETIMAGELIST             ${LVM_FIRST} +  2
+!define /math LVM_SETIMAGELIST             ${LVM_FIRST} +  3
+!define /math LVM_GETITEMCOUNT             ${LVM_FIRST} +  4
+!define /math LVM_GETITEMA                 ${LVM_FIRST} +  5
+!define /math LVM_SETITEMA                 ${LVM_FIRST} +  6
+!define /math LVM_INSERTITEMA              ${LVM_FIRST} +  7
+!define /math LVM_DELETEITEM               ${LVM_FIRST} +  8
+!define /math LVM_DELETEALLITEMS           ${LVM_FIRST} +  9
+!define /math LVM_INSERTCOLUMNA            ${LVM_FIRST} + 27
+!define /math LVM_SETCOLUMNWIDTH           ${LVM_FIRST} + 30
+!define /math LVM_SETITEMSTATE             ${LVM_FIRST} + 43
+!define /math LVM_GETITEMSTATE             ${LVM_FIRST} + 44
+!define /math LVM_SETITEMTEXTA             ${LVM_FIRST} + 46
+!define /math LVM_SETITEMCOUNT             ${LVM_FIRST} + 47
+!define /math LVM_SORTITEMS                ${LVM_FIRST} + 48
+!define /math LVM_SETEXTENDEDLISTVIEWSTYLE ${LVM_FIRST} + 54
+!define /math LVM_GETEXTENDEDLISTVIEWSTYLE ${LVM_FIRST} + 55
+!define /math LVM_GETITEMW                 ${LVM_FIRST} + 75
+!define /math LVM_SETITEMW                 ${LVM_FIRST} + 76
+!define /math LVM_INSERTITEMW              ${LVM_FIRST} + 77
+!define /math LVM_INSERTCOLUMNW            ${LVM_FIRST} + 97
+!define /math LVM_SETITEMTEXTW             ${LVM_FIRST} + 116
+!define /math LVM_SETSELECTEDCOLUMN        ${LVM_FIRST} + 140
+${_NSIS_DEFAW} LVM_GETITEM
+${_NSIS_DEFAW} LVM_SETITEM
+${_NSIS_DEFAW} LVM_INSERTITEM
+${_NSIS_DEFAW} LVM_INSERTCOLUMN
+${_NSIS_DEFAW} LVM_SETITEMTEXT
+
+#Status bar window#
+!define SB_CONST_ALPHA      0x00000001
+!define SB_GRAD_RECT        0x00000010
+!define SB_GRAD_TRI         0x00000020
+!define SB_NONE             0x00000000
+!define SB_PIXEL_ALPHA      0x00000002
+!define SB_PREMULT_ALPHA    0x00000004
+!define SB_SIMPLEID         0x00ff
+
+#Scroll bar control#
+!define SBM_ENABLE_ARROWS           0x00E4  # Not in win3.1
+!define SBM_GETPOS                  0x00E1  # Not in win3.1
+!define SBM_GETRANGE                0x00E3  # Not in win3.1
+!define SBM_GETSCROLLINFO           0x00EA
+!define SBM_SETPOS                  0x00E0  # Not in win3.1
+!define SBM_SETRANGE                0x00E2  # Not in win3.1
+!define SBM_SETRANGEREDRAW          0x00E6  # Not in win3.1
+!define SBM_SETSCROLLINFO           0x00E9
+
+#Static control#
+!define STM_GETICON                 0x0171
+!define STM_GETIMAGE                0x0173
+!define STM_MSGMAX                  0x0174
+!define STM_ONLY_THIS_INTERFACE     0x00000001
+!define STM_ONLY_THIS_NAME          0x00000008
+!define STM_ONLY_THIS_PROTOCOL      0x00000002
+!define STM_ONLY_THIS_TYPE          0x00000004
+!define STM_SETICON                 0x0170
+!define STM_SETIMAGE                0x0172
+
+#Tab control#
+!define TCS_SCROLLOPPOSITE 0x0001
+!define TCIF_TEXT  1
+!define TCIF_PARAM 8
+!define SYSSTRUCT_TCITEM (i,i,&i${NSIS_PTR_SIZE},t,i,i,p)
+!define TCM_FIRST             0x1300
+!define /math TCM_INSERTITEMA ${TCM_FIRST} + 7
+!define /math TCM_GETCURSEL   ${TCM_FIRST} + 11
+!define /math TCM_ADJUSTRECT  ${TCM_FIRST} + 40
+!define /math TCM_INSERTITEMW ${TCM_FIRST} + 62
+!define TCN_SELCHANGE   -551
+!define TCN_SELCHANGING -552
+${_NSIS_DEFAW} TCM_INSERTITEM
+
+#Progress bar control#
+!define PBM_SETRANGE    0x401
+!define PBM_SETPOS      0x402
+!define PBM_DELTAPOS    0x403
+!define PBM_SETSTEP     0x404
+!define PBM_STEPIT      0x405
+!define PBM_SETRANGE32  0x406 ; IE3 + ComCtl32 v4.70
+!define PBM_GETRANGE    0x407
+!define PBM_GETPOS      0x408
+!define PBM_SETBARCOLOR 0x409 ; IE4 + ComCtl32 v4.71
+!define PBM_SETBKCOLOR  ${CCM_SETBKCOLOR}
+!define PBM_SETMARQUEE  0x40A ; WinXP + ComCtl32 v6
+!define PBM_GETSTEP     0x40D ; WinVista
+!define PBM_GETBKCOLOR  0x40E
+!define PBM_GETBARCOLOR 0x40F
+!define PBM_SETSTATE    0x410
+!define PBM_GETSTATE    0x411
+
+!define PBST_NORMAL 1
+!define PBST_ERROR  2
+!define PBST_PAUSED 3
+
+!verbose pop
+!endif

+ 509 - 0
assets/nsis/Include/WinVer.nsh

@@ -0,0 +1,509 @@
+; ---------------------
+;      WinVer.nsh
+; ---------------------
+;
+; LogicLib extensions for handling Windows versions and service packs.
+;
+; IsNT checks if the installer is running on Windows NT family (NT4, 2000, XP, etc.)
+;
+;   ${If} ${IsNT}
+;     DetailPrint "Running on NT. Installing Unicode enabled application."
+;   ${Else}
+;     DetailPrint "Not running on NT. Installing ANSI application."
+;   ${EndIf}
+;
+; IsServerOS checks if the installer is running on a server version of Windows (NT4, 2003, 2008, etc.)
+;
+; AtLeastWin<version> checks if the installer is running on Windows version at least as specified.
+; IsWin<version> checks if the installer is running on Windows version exactly as specified.
+; AtMostWin<version> checks if the installer is running on Windows version at most as specified.
+;
+; <version> can be replaced with the following values:
+;
+;   95
+;   98
+;   ME
+;
+;   NT4
+;   2000
+;   XP
+;   2003
+;   Vista
+;   2008
+;   7
+;   2008R2
+;   8
+;   2012
+;   8.1
+;   2012R2
+;   10
+;
+;   Note: Windows 8.1 and later will be detected as Windows 8 unless ManifestSupportedOS is set correctly!
+;
+; AtLeastServicePack checks if the installer is running on Windows service pack version at least as specified.
+; IsServicePack checks if the installer is running on Windows service pack version exactly as specified.
+; AtMostServicePack checks if the installer is running on Windows service version pack at most as specified.
+;
+; Usage examples:
+;
+;   ${If} ${IsNT}
+;   DetailPrint "Running on NT family."
+;   DetailPrint "Surely not running on 95, 98 or ME."
+;   ${AndIf} ${AtLeastWinNT4}
+;     DetailPrint "Running on NT4 or better. Could even be 2003."
+;   ${EndIf}
+;
+;   ${If} ${AtLeastWinXP}
+;     DetailPrint "Running on XP or better."
+;   ${EndIf}
+;
+;   ${If} ${IsWin2000}
+;     DetailPrint "Running on 2000."
+;   ${EndIf}
+;
+;   ${If} ${IsWin2000}
+;   ${AndIf} ${AtLeastServicePack} 3
+;   ${OrIf} ${AtLeastWinXP}
+;     DetailPrint "Running Win2000 SP3 or above"
+;   ${EndIf}
+;
+;   ${If} ${AtMostWinXP}
+;     DetailPrint "Running on XP or older. Surely not running on Vista. Maybe 98, or even 95."
+;   ${EndIf}
+;
+; Warning:
+;
+;   Windows 95 and NT both use the same version number. To avoid getting NT4 misidentified
+;   as Windows 95 and vice-versa or 98 as a version higher than NT4, always use IsNT to
+;   check if running on the NT family.
+;
+;     ${If} ${AtLeastWin95}
+;     ${And} ${AtMostWinME}
+;       DetailPrint "Running 95, 98 or ME."
+;       DetailPrint "Actually, maybe it's NT4?"
+;       ${If} ${IsNT}
+;         DetailPrint "Yes, it's NT4! oops..."
+;       ${Else}
+;         DetailPrint "Nope, not NT4. phew..."
+;       ${EndIf}
+;     ${EndIf}
+;
+;
+; Other useful extensions are:
+;
+;    * IsWin2003R2
+;    * IsStarterEdition
+;    * OSHasMediaCenter
+;    * OSHasTabletSupport
+;
+
+!verbose push
+!verbose 3
+
+!ifndef ___WINVER__NSH___
+!define ___WINVER__NSH___
+
+!include LogicLib.nsh
+!include Util.nsh
+
+# masks for our variables
+
+!define _WINVER_VERXBIT  0x00000001
+!define _WINVER_MASKVMAJ 0x7F000000
+!define _WINVER_MASKVMIN 0x00FF0000
+
+!define _WINVER_NTBIT    0x80000000
+!define _WINVER_NTMASK   0x7FFFFFFF
+!define _WINVER_NTSRVBIT 0x40000000
+!define _WINVER_MASKVBLD 0x0000FFFF
+!define _WINVER_MASKSP   0x000F0000
+
+# possible variable values for different versions
+
+!define WINVER_95_NT     0x04000000 ;4.00.0950
+!define WINVER_95        0x04000000 ;4.00.0950
+!define WINVER_98_NT     0x040a0000 ;4.10.1998
+!define WINVER_98        0x040a0000 ;4.10.1998
+;define WINVER_98SE      0x040a0000 ;4.10.2222
+!define WINVER_ME_NT     0x045a0000 ;4.90.3000
+!define WINVER_ME        0x045a0000 ;4.90.3000
+;define WINVER_NT3.51               ;3.51.1057
+!define WINVER_NT4_NT    0x84000000 ;4.00.1381
+!define WINVER_NT4       0x04000000 ;4.00.1381
+!define WINVER_2000_NT   0x85000000 ;5.00.2195
+!define WINVER_2000      0x05000000 ;5.00.2195
+!define WINVER_XP_NT     0x85010000 ;5.01.2600
+!define WINVER_XP        0x05010000 ;5.01.2600
+;define WINVER_XP64                 ;5.02.3790
+!define WINVER_2003_NT   0x85020000 ;5.02.3790
+!define WINVER_2003      0x05020000 ;5.02.3790
+!define WINVER_VISTA_NT  0x86000000 ;6.00.6000
+!define WINVER_VISTA     0x06000000 ;6.00.6000
+!define WINVER_2008_NT   0x86000001 ;6.00.6001
+!define WINVER_2008      0x06000001 ;6.00.6001
+!define WINVER_7_NT      0x86010000 ;6.01.7600
+!define WINVER_7         0x06010000 ;6.01.7600
+!define WINVER_2008R2_NT 0x86010001 ;6.01.7600
+!define WINVER_2008R2    0x06010001 ;6.01.7600
+!define WINVER_8_NT      0x86020000 ;6.02.9200
+!define WINVER_8         0x06020000 ;6.02.9200
+!define WINVER_2012_NT   0x86020001 ;6.02.9200
+!define WINVER_2012      0x06020001 ;6.02.9200
+!define WINVER_8.1_NT    0x86030000 ;6.03.9600
+!define WINVER_8.1       0x06030000 ;6.03.9600
+!define WINVER_2012R2_NT 0x86030001 ;6.03.9600
+!define WINVER_2012R2    0x06030001 ;6.03.9600
+!define WINVER_10_NT     0x8A000000 ;10.0.10240
+!define WINVER_10        0x0A000000 ;10.0.10240
+
+
+# use this to make all nt > 9x
+
+!ifdef WINVER_NT4_OVER_W95
+  !define /redef /math WINVER_NT4 ${WINVER_NT4} | ${_WINVER_VERXBIT}
+!endif
+
+# some definitions from header files
+
+!define OSVERSIONINFOW_SIZE   276
+!define OSVERSIONINFOEXW_SIZE 284
+!define OSVERSIONINFOA_SIZE   148
+!define OSVERSIONINFOEXA_SIZE 156
+!define /ifndef VER_PLATFORM_WIN32_NT 2
+!define /ifndef VER_NT_WORKSTATION    1
+
+!define SM_TABLETPC    86
+!define SM_MEDIACENTER 87
+!define SM_STARTER     88
+!define SM_SERVERR2    89
+
+# variable declaration
+
+!macro __WinVer_DeclareVars
+
+  !ifndef __WINVER_VARS_DECLARED
+
+    !define __WINVER_VARS_DECLARED
+
+    Var /GLOBAL __WINVERV
+    Var /GLOBAL __WINVERSP
+
+  !endif
+
+!macroend
+
+# lazy initialization macro
+
+!ifmacrondef __WinVer_Call_GetVersionEx
+
+  !macro __WinVer_Call_GetVersionEx STRUCT_SIZE
+
+    System::Call '*$0(i ${STRUCT_SIZE})'
+    System::Call kernel32::GetVersionEx(pr0)i.r3
+
+  !macroend
+
+!endif
+
+!macro __WinVer_InitVars
+  # variables
+  !insertmacro __WinVer_DeclareVars
+
+  # only calculate version once
+  StrCmp $__WINVERV "" _winver_noveryet
+    Return
+  _winver_noveryet:
+
+  # push used registers on the stack
+  Push $0
+  Push $1 ;maj
+  Push $2 ;min
+  Push $3 ;bld
+  Push $R0 ;temp
+
+  # a plugin call will lock the Unicode mode, it is now safe to set the struct size
+  !ifdef NSIS_UNICODE
+  !define /redef OSVERSIONINFO_SIZE ${OSVERSIONINFOW_SIZE}
+  !define /redef OSVERSIONINFOEX_SIZE ${OSVERSIONINFOEXW_SIZE}
+  !else
+  !define /redef OSVERSIONINFO_SIZE ${OSVERSIONINFOA_SIZE}
+  !define /redef OSVERSIONINFOEX_SIZE ${OSVERSIONINFOEXA_SIZE}
+  !endif
+
+  # allocate memory
+  System::Call '*(&i${OSVERSIONINFOEX_SIZE})p.r0'
+
+  # use OSVERSIONINFOEX
+  !insertmacro __WinVer_Call_GetVersionEx ${OSVERSIONINFOEX_SIZE}
+
+  IntCmp $3 0 "" _winver_ex _winver_ex
+    # OSVERSIONINFOEX not allowed (Win9x or NT4 w/SP < 6), use OSVERSIONINFO
+    !insertmacro __WinVer_Call_GetVersionEx ${OSVERSIONINFO_SIZE}
+  _winver_ex:
+
+  # get results from struct
+  System::Call '*$0(i.s,i.r1,i.r2,i.r3,i.s,&t128.s,&i2.s,&i2,&i2,&i1.s,&i1)'
+
+  # free struct
+  System::Free $0
+
+  # win9x has major and minor info in high word of dwBuildNumber - remove it
+  IntOp $3 $3 & 0xFFFF
+
+  # get dwOSVersionInfoSize
+  Pop $R0
+
+  # get dwPlatformId
+  Pop $0
+
+  # NT?
+  IntCmp $0 ${VER_PLATFORM_WIN32_NT} "" _winver_notnt _winver_notnt
+    IntOp $__WINVERSP $__WINVERSP | ${_WINVER_NTBIT}
+    IntOp $__WINVERV  $__WINVERV  | ${_WINVER_NTBIT}
+  _winver_notnt:
+
+  # get service pack information
+  IntCmp $0 ${VER_PLATFORM_WIN32_NT} _winver_nt "" _winver_nt  # win9x
+
+    # get szCSDVersion
+    Pop $0
+
+    # copy second char
+    StrCpy $0 $0 1 1
+
+    # discard invalid wServicePackMajor and wProductType
+    Pop $R0
+    Pop $R0
+
+    # switch
+    StrCmp $0 'A' "" +3
+      StrCpy $0 1
+      Goto _winver_sp_done
+    StrCmp $0 'B' "" +3
+      StrCpy $0 2
+      Goto _winver_sp_done
+    StrCmp $0 'C' "" +3
+      StrCpy $0 3
+      Goto _winver_sp_done
+    StrCpy $0 0
+    Goto _winver_sp_done
+
+  _winver_nt: # nt
+
+    IntCmp $R0 ${OSVERSIONINFOEX_SIZE} "" _winver_sp_noex _winver_sp_noex
+
+      # discard szCSDVersion
+      Pop $0
+
+      # get wProductType
+      Exch
+      Pop $0
+
+      # is server?
+      IntCmp $0 ${VER_NT_WORKSTATION} _winver_noserver
+        IntOp $__WINVERSP $__WINVERSP | ${_WINVER_NTSRVBIT}
+      _winver_noserver:
+
+      # get wServicePackMajor
+      Pop $0
+
+      # done with sp
+      Goto _winver_sp_done
+
+    _winver_sp_noex: # OSVERSIONINFO, not OSVERSIONINFOEX
+
+      ####  TODO
+      ## For IsServerOS to support < NT4SP6, we need to check the registry
+      ## here to see if we are a server and/or DC
+
+      # get szCSDVersion
+      Pop $0
+
+      # discard invalid wServicePackMajor and wProductType
+      Pop $R0
+      Pop $R0
+
+      # get service pack number from text
+      StrCpy $R0 $0 13
+      StrCmp $R0 "Service Pack " "" +3
+        StrCpy $0 $0 "" 13 # cut "Service Pack "
+        Goto +2
+        StrCpy $0 0 # no service pack
+
+!ifdef WINVER_NT4_OVER_W95
+      IntOp $__WINVERV $__WINVERV | ${_WINVER_VERXBIT}
+!endif
+
+  _winver_sp_done:
+
+  # store service pack
+  IntOp $0 $0 << 16
+  IntOp $__WINVERSP $__WINVERSP | $0
+
+  ### now for the version
+
+  # is server?
+  IntOp $0 $__WINVERSP & ${_WINVER_NTSRVBIT}
+
+  # windows xp x64?
+  IntCmp $0 0 "" _winver_not_xp_x64 _winver_not_xp_x64 # not server
+  IntCmp $1 5 "" _winver_not_xp_x64 _winver_not_xp_x64 # maj 5
+  IntCmp $2 2 "" _winver_not_xp_x64 _winver_not_xp_x64 # min 2
+    # change XP x64 from 5.2 to 5.1 so it's still XP
+    StrCpy $2 1
+  _winver_not_xp_x64:
+
+  # server 2008?
+  IntCmp $0 0 _winver_not_ntserver # server
+  IntCmp 6 $1 "" "" _winver_not_ntserver # maj 6
+    # extra bit so Server 2008 comes after Vista SP1 that has the same minor version, same for Win7 vs 2008R2
+    IntOp $__WINVERV $__WINVERV | ${_WINVER_VERXBIT}
+  _winver_not_ntserver:
+
+  # pack version
+  IntOp $1 $1 << 24 # VerMajor
+  IntOp $__WINVERV $__WINVERV | $1
+  IntOp $0 $2 << 16
+  IntOp $__WINVERV $__WINVERV | $0 # VerMinor
+  IntOp $__WINVERSP $__WINVERSP | $3 # VerBuild
+
+  # restore registers
+  Pop $R0
+  Pop $3
+  Pop $2
+  Pop $1
+  Pop $0
+
+!macroend
+
+# version comparison LogicLib macros
+
+!macro _WinVerAtLeast _a _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  ${CallArtificialFunction} __WinVer_InitVars
+  IntOp $_LOGICLIB_TEMP $__WINVERV & ${_WINVER_NTMASK}
+  !insertmacro _>= $_LOGICLIB_TEMP `${_b}` `${_t}` `${_f}`
+!macroend
+!macro _WinVerIs _a _b _t _f
+  ${CallArtificialFunction} __WinVer_InitVars
+  !insertmacro _= $__WINVERV `${_b}` `${_t}` `${_f}`
+!macroend
+!macro _WinVerAtMost _a _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  ${CallArtificialFunction} __WinVer_InitVars
+  IntOp $_LOGICLIB_TEMP $__WINVERV & ${_WINVER_NTMASK}
+  !insertmacro _<= $_LOGICLIB_TEMP `${_b}` `${_t}` `${_f}`
+!macroend
+
+!macro __WinVer_DefineOSTest Test OS Suffix
+  !define ${Test}Win${OS} `"" WinVer${Test} ${WINVER_${OS}${Suffix}}`
+!macroend
+
+!macro __WinVer_DefineOSTests Test Suffix
+  !insertmacro __WinVer_DefineOSTest ${Test} 95     '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 98     '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} ME     '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} NT4    '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 2000   '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} XP     '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 2003   '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} VISTA  '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 2008   '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 7      '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 2008R2 '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 8      '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 2012   '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 8.1    '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 2012R2 '${Suffix}'
+  !insertmacro __WinVer_DefineOSTest ${Test} 10     '${Suffix}'
+!macroend
+
+!insertmacro __WinVer_DefineOSTests AtLeast ""
+!insertmacro __WinVer_DefineOSTests Is _NT
+!insertmacro __WinVer_DefineOSTests AtMost ""
+
+# version feature LogicLib macros
+
+!macro _IsNT _a _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  ${CallArtificialFunction} __WinVer_InitVars
+  IntOp $_LOGICLIB_TEMP $__WINVERSP & ${_WINVER_NTBIT}
+  !insertmacro _!= $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
+!macroend
+!define IsNT `"" IsNT ""`
+
+!macro _IsServerOS _a _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  ${CallArtificialFunction} __WinVer_InitVars
+  IntOp $_LOGICLIB_TEMP $__WINVERSP & ${_WINVER_NTSRVBIT}
+  !insertmacro _!= $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
+!macroend
+!define IsServerOS `"" IsServerOS ""`
+
+# service pack macros
+
+!macro _WinVer_GetServicePackLevel OUTVAR
+  ${CallArtificialFunction} __WinVer_InitVars
+  IntOp ${OUTVAR} $__WINVERSP & ${_WINVER_MASKSP}
+  IntOp ${OUTVAR} ${OUTVAR} >> 16
+!macroend
+!define WinVerGetServicePackLevel '!insertmacro _WinVer_GetServicePackLevel '
+
+!macro _AtLeastServicePack _a _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  ${WinVerGetServicePackLevel} $_LOGICLIB_TEMP
+  !insertmacro _>= $_LOGICLIB_TEMP `${_b}` `${_t}` `${_f}`
+!macroend
+!define AtLeastServicePack `"" AtLeastServicePack`
+
+!macro _AtMostServicePack _a _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  ${WinVerGetServicePackLevel} $_LOGICLIB_TEMP
+  !insertmacro _<= $_LOGICLIB_TEMP `${_b}` `${_t}` `${_f}`
+!macroend
+!define AtMostServicePack `"" AtMostServicePack`
+
+!macro _IsServicePack _a _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  ${WinVerGetServicePackLevel} $_LOGICLIB_TEMP
+  !insertmacro _= $_LOGICLIB_TEMP `${_b}` `${_t}` `${_f}`
+!macroend
+!define IsServicePack `"" IsServicePack`
+
+# special feature LogicLib macros
+
+!macro _WinVer_SysMetricCheck m _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  System::Call user32::GetSystemMetrics(i${m})i.s
+  pop $_LOGICLIB_TEMP
+  !insertmacro _!= $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
+!macroend
+
+!define IsWin2003R2        `${SM_SERVERR2}    WinVer_SysMetricCheck ""`
+!define IsStarterEdition   `${SM_STARTER}     WinVer_SysMetricCheck ""`
+!define OSHasMediaCenter   `${SM_MEDIACENTER} WinVer_SysMetricCheck ""`
+!define OSHasTabletSupport `${SM_TABLETPC}    WinVer_SysMetricCheck ""`
+
+# version retrieval macros
+
+!macro __WinVer_GetVer var rshift mask outvar
+  ${CallArtificialFunction} __WinVer_InitVars
+  !if "${mask}" != ""
+    IntOp ${outvar} ${var} & ${mask}
+    !if "${rshift}" != ""
+      IntOp ${outvar} ${outvar} >> ${rshift}
+    !endif
+  !else
+    IntOp ${outvar} ${var} >> ${rshift}
+  !endif
+!macroend
+
+!define WinVerGetMajor '!insertmacro __WinVer_GetVer $__WINVERV  24 ${_WINVER_MASKVMAJ}'
+!define WinVerGetMinor '!insertmacro __WinVer_GetVer $__WINVERV  16 ${_WINVER_MASKVMIN}'
+!define WinVerGetBuild '!insertmacro __WinVer_GetVer $__WINVERSP "" ${_WINVER_MASKVBLD}'
+
+# done
+
+!endif # !___WINVER__NSH___
+
+!verbose pop

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1800 - 0
assets/nsis/Include/WordFunc.nsh


+ 61 - 0
assets/nsis/Include/x64.nsh

@@ -0,0 +1,61 @@
+; ---------------------
+;       x64.nsh
+; ---------------------
+;
+; A few simple macros to handle installations on x64 machines.
+;
+; RunningX64 checks if the installer is running on a 64-bit OS.
+; IsWow64 checks if the installer is a 32-bit application running on a 64-bit OS.
+;
+;   ${If} ${RunningX64}
+;     MessageBox MB_OK "running on x64"
+;   ${EndIf}
+;
+; DisableX64FSRedirection disables file system redirection.
+; EnableX64FSRedirection enables file system redirection.
+;
+;   SetOutPath $SYSDIR
+;   ${DisableX64FSRedirection}
+;   File some.dll # extracts to C:\Windows\System32
+;   ${EnableX64FSRedirection}
+;   File some.dll # extracts to C:\Windows\SysWOW64
+;
+
+!ifndef ___X64__NSH___
+!define ___X64__NSH___
+
+!include LogicLib.nsh
+
+
+!define IsWow64 `"" IsWow64 ""`
+!macro _IsWow64 _a _b _t _f
+  !insertmacro _LOGICLIB_TEMP
+  System::Call kernel32::GetCurrentProcess()p.s
+  System::Call kernel32::IsWow64Process(ps,*i0s)
+  Pop $_LOGICLIB_TEMP
+  !insertmacro _!= $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
+!macroend
+
+
+!define RunningX64 `"" RunningX64 ""`
+!macro _RunningX64 _a _b _t _f 
+  !if ${NSIS_PTR_SIZE} > 4
+    !insertmacro LogicLib_JumpToBranch `${_t}` `${_f}`
+  !else
+    !insertmacro _IsWow64 `${_a}` `${_b}` `${_t}` `${_f}`
+  !endif
+!macroend
+
+
+!define DisableX64FSRedirection "!insertmacro DisableX64FSRedirection"
+!macro DisableX64FSRedirection
+  System::Call kernel32::Wow64EnableWow64FsRedirection(i0)
+!macroend
+
+!define EnableX64FSRedirection "!insertmacro EnableX64FSRedirection"
+!macro EnableX64FSRedirection
+  System::Call kernel32::Wow64EnableWow64FsRedirection(i1)
+!macroend
+
+
+!endif # !___X64__NSH___

BIN
assets/nsis/Menu/images/header.gif


BIN
assets/nsis/Menu/images/line.gif


BIN
assets/nsis/Menu/images/site.gif


+ 64 - 0
assets/nsis/Menu/index.html

@@ -0,0 +1,64 @@
+<html>
+<head><title>NSIS Menu</title></head>
+<body link="#0C6E97">
+	<div><img src="images/header.gif" width="598" height="45"></div>
+	<table border="0">
+		<tr>
+			<td width="20">
+			</td>
+			<td width="190" valign="top">
+				<p>
+					<font size="+1" color="#333333"><b>Compiler</b></font><br>
+					<a href="BIN:makensisw">Compile NSI scripts</a><br>
+					<a href="BIN:zip2exe">Installer based on ZIP file</a><br>
+					<br>
+					<br>
+					<br>
+				</p>
+				<p>
+					<font size="+1" color="#333333"><b>Developer Center</b></font><br>
+					Many more examples, tutorials, plug-ins and NSIS-related software are available
+					at the on-line <a href="WEB:http://nsis.sourceforge.net/Developer_Center">Developer Center</a>.
+				</p>
+				</td>
+			<td width="150" valign="top">
+				<p>
+					<font size="+1" color="#333333"><b>Documentation</b></font><br>
+					<a href="DOC:NSIS.chm">NSIS Users Manual</a><br>
+					<a href="DOC:Examples">Example scripts</a><br>
+					<a href="DOC:Docs/Modern UI 2/Readme.html">Modern UI 2</a><br>
+					<a href="DOC:Docs/MultiUser/Readme.html">Multi-User Header File</a><br>
+					<a href="DOC:Docs/StrFunc/StrFunc.txt">StrFunc Header File</a></p>
+				<p>
+					<font size="+1" color="#333333"><b>On-line help</b></font><br>
+					<a href="WEB:http://forums.winamp.com/forumdisplay.php?s=&forumid=65">Forum</a><br>
+					<a href="WEB:http://nsis.sourceforge.net/FAQ">FAQ</a><br>
+					<a href="WEB:irc://irc.landoleet.org/nsis">IRC Channel</a><br>
+					<a href="WEB:http://sourceforge.net/tracker/?group_id=22049&atid=373085">Bug Tracker</a><br>
+			</td>
+			<td valign="top">
+				<p>
+					<font size="+1" color="#333333"><b>Plug-ins</b></font><br>
+					<a href="DOC:Docs/AdvSplash/advsplash.txt">AdvSplash</a> - splash with fade in/out<br>
+					<a href="DOC:Docs/Banner/Readme.txt">Banner</a> - banner with custom text<br>
+					<a href="DOC:Docs/BgImage/BgImage.txt">BgImage</a> - background image<br>
+					<a href="DOC:Docs/Dialer/Dialer.txt">Dialer</a> - internet connection<br>
+					<a href="DOC:Docs/Math/Math.txt">Math</a> - math operations<br>
+					<a href="DOC:Docs/nsDialogs/Readme.html">nsDialogs</a> - custom wizard pages<br>
+					<a href="DOC:Docs/nsExec/nsExec.txt">nsExec</a> - launch command line tools<br>
+					<a href="DOC:Docs/NSISdl/ReadMe.txt">NSISdl</a> - download files<br>
+					<a href="DOC:Docs/Splash/splash.txt">Splash</a> - splash screen<br>
+					<a href="DOC:Docs/StartMenu/Readme.txt">StartMenu</a> - Start Menu folder selection<br>
+					<a href="DOC:Docs/System/System.html">System</a> - Windows API calls<br>
+					<a href="DOC:Docs/VPatch/Readme.html">VPatch</a> - update existing files</p>
+			</td>
+		</tr>
+	</table>
+	<p>
+		<img src="images/line.gif" width="598" height="3">
+	</p>
+	<div align="right">
+		<a href="WEB:http://nsis.sourceforge.net/"><img src="images/site.gif" width="200" height="25"></a>
+	</div>
+</body>
+</html>

+ 22 - 0
assets/nsis/Menu/notinstalled.html

@@ -0,0 +1,22 @@
+<html>
+<head><title>NSIS Menu</title></head>
+<body link="#0C6E97">
+    <div><img src="images/header.gif" width="598" height="45"></div>
+    <table border="0">
+        <tr>
+            <td width="20">
+            </td>
+            <td>
+                <p>
+                    <font size="+1" color="#0C6E97"><b>Feature not installed</b></font></p>
+                <p>
+                    The feature you selected is not installed.</p>
+                <p>
+                    If you want to use this feature, run NSIS Setup again to install it.</p>
+                <p>
+                    <a href="index.html">&lt;- Back</a></p>
+            </td>
+        </tr>
+    </table>
+</body>
+</html>

BIN
assets/nsis/NSIS.chm


BIN
assets/nsis/NSIS.exe


BIN
assets/nsis/Plugins/x86-ansi/TypeLib.dll


BIN
assets/nsis/Plugins/x86-unicode/TypeLib.dll


BIN
assets/nsis/Stubs/bzip2-x86-ansi


BIN
assets/nsis/Stubs/bzip2-x86-unicode


BIN
assets/nsis/Stubs/bzip2_solid-x86-ansi


BIN
assets/nsis/Stubs/bzip2_solid-x86-unicode


BIN
assets/nsis/Stubs/lzma-x86-ansi


BIN
assets/nsis/Stubs/lzma-x86-unicode


BIN
assets/nsis/Stubs/lzma_solid-x86-ansi


BIN
assets/nsis/Stubs/lzma_solid-x86-unicode


BIN
assets/nsis/Stubs/uninst


BIN
assets/nsis/Stubs/zlib-x86-ansi


BIN
assets/nsis/Stubs/zlib-x86-unicode


BIN
assets/nsis/Stubs/zlib_solid-x86-ansi


BIN
assets/nsis/Stubs/zlib_solid-x86-unicode


BIN
assets/nsis/makensis.exe


BIN
assets/nsis/makensisw.exe


+ 62 - 0
assets/nsis/nsisconf.nsh

@@ -0,0 +1,62 @@
+;------------------------
+;DEFAULT NSIS CONFIG FILE
+;------------------------
+
+;This header file will be included when compiling any NSIS installer,
+;you can use it to add script code to every installer you compile.
+
+;This file is treated as if it is in the directory of your script.
+;When using relative paths, the files have to be in your build directory.
+
+;------------------------
+;EXAMPLES
+;------------------------
+
+;Compress installer exehead with an executable compressor (such as UPX / Petite).
+
+;Paths should be absolute to allow building from any location.
+;Note that your executable compressor should not compress the first icon.
+
+;!packhdr temp.dat '"C:\Program Files\upx\upx" -9 -q temp.dat'
+;!packhdr temp.dat '"C:\Program Files\petite\petite" -9 -b0 -r** -p0 -y temp.dat'
+
+;------------------------
+
+;Set default compressor
+
+;SetCompressor bzip2
+
+;------------------------
+
+;Change the default icons
+
+;Icon "${NSISDIR}\Contrib\Graphics\Icons\arrow-install.ico"
+;UninstallIcon "${NSISDIR}\Contrib\Graphics\Icons\arrow-uninstall.ico"
+
+;------------------------
+
+;Define symbols
+
+;!define COMPANYNAME "bla"
+
+;------------------------
+;MODERN UI
+;------------------------
+
+;The Modern UI will insert the MUI_NSISCONF macro just before processing the settings.
+;Here you can set default settings for the Modern UI.
+
+;------------------------
+
+!define MUI_INSERT_NSISCONF
+
+!macro MUI_NSISCONF
+
+  ;Example: Change the default Modern UI icons
+  
+  ;!ifndef MUI_ICON & MUI_UNICON
+  ;  !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\arrow-install.ico"
+  ;  !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\arrow-uninstall.ico"
+  ;!endif
+  
+!macroend

+ 3 - 1
assets/project/package.json

@@ -12,11 +12,13 @@
   "build": {
     "nwVersion": "lts",
     "targets": [
-      "zip"
+      "zip",
+      "nsis"
     ],
     "win": {
       "versionStrings": {
         "ProductName": "Project",
+        "CompanyName": "nwjs-builder-phoenix",
         "LegalCopyright": "copyright"
       }
     },

+ 47 - 0
src/lib/Builder.ts

@@ -12,6 +12,7 @@ import { Downloader } from './Downloader';
 import { FFmpegDownloader } from './FFmpegDownloader';
 import { extractGeneric, compress } from './archive';
 import { BuildConfig } from './BuildConfig';
+import { NsisComposer, nsisBuild } from './nsis-gen';
 import { mergeOptions, findExecutable, findFFmpeg, findRuntimeRoot, findExcludableDependencies, tmpName, tmpFile, tmpDir, cpAsync } from './util';
 
 interface IBuilderOptions {
@@ -415,6 +416,47 @@ export class Builder {
 
     }
 
+    protected async buildNsisTarget(platform: string, arch: string, targetDir: string, pkg: any, config: BuildConfig) {
+
+        if(platform != 'win') {
+            console.info(`Skip building nsis target for ${ platform }.`);
+            return;
+        }
+
+        const targetNsis = resolve(dirname(targetDir), `${ basename(targetDir) }-Setup.exe`);
+
+        const data = await (new NsisComposer({
+
+            // Basic.
+            appName: config.win.versionStrings.ProductName,
+            companyName: config.win.versionStrings.CompanyName,
+            description: config.win.versionStrings.FileDescription,
+            version: config.win.productVersion,
+            copyright: config.win.versionStrings.LegalCopyright,
+
+            // Compression.
+            compression: 'lzma',
+            solid: true,
+
+            // Files.
+            srcDir: targetDir,
+
+            // Output.
+            output: targetNsis,
+
+        })).make();
+
+        const script = await tmpName();
+        await writeFileAsync(script, data);
+
+        await nsisBuild(script, {
+            mute: false,
+        });
+
+        await removeAsync(script);
+
+    }
+
     protected async buildTask(platform: string, arch: string, pkg: any, config: BuildConfig) {
 
         const downloader = new Downloader({
@@ -453,6 +495,11 @@ export class Builder {
                 await this.buildArchiveTarget(target, targetDir);
                 break;
             case 'nsis':
+                if(!this.options.mute) {
+                    console.info(`Building nsis target...`);
+                }
+                await this.buildNsisTarget(platform, arch, targetDir, pkg, config);
+                break;
             default:
                 throw new Error('ERROR_UNKNOWN_TARGET');
             }

+ 1 - 0
src/lib/WinConfig.ts

@@ -5,6 +5,7 @@ export class WinConfig {
     public fileVersion: string = '';
     public versionStrings: {
         ProductName?: undefined,
+        CompanyName?: undefined,
         FileDescription?: undefined,
         LegalCopyright?: undefined,
     } = {};

+ 182 - 0
src/lib/nsis-gen/NsisComposer.ts

@@ -0,0 +1,182 @@
+
+import { relative, resolve, win32 } from 'path';
+
+import { readdirAsync, lstatAsync } from 'fs-extra-promise';
+
+const globby = require('globby');
+
+interface INsisComposerOptions {
+
+    // Basic.
+    appName: string;
+    companyName: string;
+    description: string;
+    version: string;
+    copyright: string;
+
+    // Compression.
+    compression: 'zlib' | 'bzip2' | 'lzma';
+    solid: boolean;
+
+    // Files.
+    srcDir: string;
+
+    // Output.
+    output: string;
+
+}
+
+export class NsisComposer {
+
+    public static DIVIDER = '################################################################################';
+
+    protected fixedVersion: string;
+
+    constructor(protected options: INsisComposerOptions) {
+
+        this.fixedVersion = this.fixVersion(this.options.version);
+
+    }
+
+    public async make(): Promise<string> {
+
+        return `${ NsisComposer.DIVIDER }
+#
+# Generated by nsis-gen.
+#
+${ NsisComposer.DIVIDER }
+
+${ await this.makeGeneralSection() }
+${ await this.makeResourcesSection() }
+${ await this.makeInstallSection() }
+${ await this.makeUninstallSection() }
+`;
+
+    }
+
+    protected async makeGeneralSection(): Promise<string> {
+
+        return `${ NsisComposer.DIVIDER }
+#
+# General
+#
+${ NsisComposer.DIVIDER }
+
+Name "${ this.options.appName }"
+Caption "${ this.options.appName }"
+BrandingText "${ this.options.appName }"
+OutFile "${ win32.normalize(resolve(this.options.output)) }"
+InstallDir "$PROGRAMFILES\\${ this.options.appName }"
+SetCompressor ${ this.options.solid ? '/SOLID' : '' } ${ this.options.compression }
+XPStyle on
+`;
+
+    }
+
+    protected async makeResourcesSection(): Promise<string> {
+
+        return `${ NsisComposer.DIVIDER }
+#
+# Resources
+#
+${ NsisComposer.DIVIDER }
+
+VIProductVersion "${ this.fixedVersion }"
+VIAddVersionKey "ProductName" "${ this.options.appName }"
+VIAddVersionKey "CompanyName" "${ this.options.companyName }"
+VIAddVersionKey "FileDescription" "${ this.options.description }"
+VIAddVersionKey "FileVersion" "${ this.fixedVersion }"
+VIAddVersionKey "LegalCopyright" "${ this.options.copyright }"
+`;
+
+    }
+
+    protected async makeInstallSection(): Promise<string> {
+
+        return `${ NsisComposer.DIVIDER }
+#
+# Main
+#
+${ NsisComposer.DIVIDER }
+
+Section -Install
+
+SetShellVarContext current
+SetOverwrite ifnewer
+
+${ await this.makeInstallerFiles() }
+
+WriteUninstaller "$INSTDIR\\uninstall.exe"
+
+SectionEnd
+`;
+
+    }
+
+    protected async makeUninstallSection(): Promise<string> {
+
+        return `${ NsisComposer.DIVIDER }
+#
+# Uninstall
+#
+${ NsisComposer.DIVIDER }
+
+Section Uninstall
+
+RMDir /r "$INSTDIR\\*.*"
+RMDir "$INSTDIR"
+
+SectionEnd
+`;
+
+    }
+
+    protected async makeInstallerFiles(): Promise<string> {
+
+        const out: string[] = [];
+        await this.readdirLines(resolve(this.options.srcDir), resolve(this.options.srcDir), out);
+
+        return out.join('\n');
+
+    }
+
+    protected fixVersion(version: string) {
+        // Fix "invalid VIProductVersion format, should be X.X.X.X" for semver.
+        return /^\d+\.\d+\.\d+$/.test(this.options.version) ? `${ this.options.version }.0` : this.options.version;
+    }
+
+    protected async readdirLines(dir: string, baseDir: string, out: string[]) {
+
+        const lines = [];
+        const pendingFiles = [];
+
+        const files = await readdirAsync(dir);
+
+        if(files.length > 0) {
+            const path = win32.normalize(relative(baseDir, dir));
+            lines.push(`SetOutPath "$INSTDIR${ path == '.' ? '' : `\\${ path }` }"`);
+        }
+
+        for(const file of files) {
+
+            const path = resolve(dir, file);
+            const stat = await lstatAsync(path);
+
+            if(stat.isFile()) {
+                lines.push(`File "${ win32.normalize(path) }"`);
+            }
+            else if(stat.isDirectory()) {
+                pendingFiles.push(path);
+            }
+
+        }
+
+        for(const file of pendingFiles) {
+            await this.readdirLines(resolve(dir, file), resolve(baseDir), lines);
+        }
+
+        out.push(...lines);
+
+    }
+
+}

+ 45 - 0
src/lib/nsis-gen/index.ts

@@ -0,0 +1,45 @@
+
+import { dirname, resolve, win32 } from 'path';
+import { spawn } from 'child_process';
+
+export * from './NsisComposer';
+
+const DIR_ASSETS = resolve(dirname(module.filename), '../../../assets/');
+const DIR_NSIS = resolve(DIR_ASSETS, 'nsis');
+
+interface INsisBuildOptions {
+    mute: boolean;
+}
+
+export async function nsisBuild(script: string, options: INsisBuildOptions = {
+    mute: false,
+}) {
+
+    const args = [ win32.normalize(resolve(DIR_NSIS, 'makensis.exe')), win32.normalize(resolve(script)) ];
+    if(process.platform != 'win32') {
+        args.unshift('wine');
+    }
+
+    const child = spawn(args.shift(), args);
+
+    await new Promise((resolve, reject) => {
+
+        child.on('error', reject);
+        child.on('close', (code, signal) => {
+
+            if(code != 0) {
+                return reject(new Error(`ERROR_EXIT_CODE code = ${ code }`));
+            }
+
+            resolve({ code, signal });
+
+        });
+
+        if(!options.mute) {
+            child.stdout.pipe(process.stdout);
+            child.stderr.pipe(process.stderr);
+        }
+
+    });
+
+}

+ 3 - 42
test/Builder.js

@@ -6,62 +6,23 @@ import { spawnAsync } from '../dist/lib/util';
 
 const dir = './assets/project/';
 
-test.serial('commandline', async (t) => {
-
-    const platform = (() => {
-        switch(process.platform) {
-        case 'win32':
-            return '--win';
-        case 'darwin':
-            return '--mac';
-        case 'linux':
-            return '--linux';
-        default:
-            throw new Error('ERROR_UNKNOWN_PLATFORM');
-        }
-    })();
-
-    const mirror = process.env.CI ? '' : '--mirror https://npm.taobao.org/mirrors/nwjs/';
-
-    const { code, signal } = await spawnAsync('node', `./dist/bin/build.js ${ platform } --x64 ${ mirror } ${ dir }`.split(' '), {
-        stdio: 'inherit',
-    });
-    t.is(code, 0);
-
-});
-
-test.serial('commandline --config', async (t) => {
-
-    const platform = (() => {
-        switch(process.platform) {
-        case 'win32':
-            return '--win';
-        case 'darwin':
-            return '--mac';
-        case 'linux':
-            return '--linux';
-        default:
-            throw new Error('ERROR_UNKNOWN_PLATFORM');
-        }
-    })();
+test('commandline', async (t) => {
 
     const mirror = process.env.CI ? '' : '--mirror https://npm.taobao.org/mirrors/nwjs/';
 
-    const { code, signal } = await spawnAsync('node', `./dist/bin/build.js ${ platform } --x64 ${ mirror } --config ${ dir }/package.json ${ dir }`.split(' '), {
+    const { code, signal } = await spawnAsync('node', `./dist/bin/build.js --mac --x64 ${ mirror } --config ${ dir }/package.json ${ dir }`.split(' '), {
         stdio: 'inherit',
     });
     t.is(code, 0);
 
 });
 
-(process.env.CI ? test.skip.serial : test.serial)('module', async (t) => {
+test('module', async (t) => {
 
     const mirror = process.env.CI ? undefined : 'https://npm.taobao.org/mirrors/nwjs/';
 
     const builder = new Builder({
         win: true,
-        mac: true,
-        linux: true,
         x64: true,
         mirror,
     }, dir);

+ 1 - 13
test/Runner.js

@@ -6,19 +6,7 @@ import { spawnAsync } from '../dist/lib/util';
 
 const dir = './assets/project/';
 
-// FIXME: When run with other tests, the code will be 0.
-test.serial('commandline --mirror', async (t) => {
-
-    const mirror = process.env.CI ? '' : '--mirror https://npm.taobao.org/mirrors/nwjs/';
-
-    const { code, signal } = await spawnAsync('node', `./dist/bin/run.js ${ mirror } ${ dir } 233`.split(' '), {
-        stdio: 'inherit',
-    });
-    t.is(code, 233);
-
-});
-
-test.serial('commandline with environment variables', async (t) => {
+test.serial('commandline', async (t) => {
 
     const { code, signal } = await spawnAsync('node', `./dist/bin/run.js ${ dir } 233`.split(' '), {
         stdio: 'inherit',

+ 46 - 0
test/nsis-gen.js

@@ -0,0 +1,46 @@
+
+import { test } from 'ava';
+
+import { writeFileAsync, removeAsync } from 'fs-extra-promise';
+
+import { NsisComposer, nsisBuild } from '../dist/lib/nsis-gen';
+import { tmpName, tmpFile, tmpDir } from '../dist/lib/util';
+
+test('build', async (t) => {
+
+    const output = await tmpName();
+
+    const data = await (new NsisComposer({
+
+        // Basic.
+        appName: 'Project',
+        companyName: 'evshiron',
+        description: 'description',
+        version: '0.1.0.0',
+        copyright: 'copyright',
+
+        // Compression.
+        compression: 'lzma',
+        solid: true,
+
+        // Styles.
+        xpStyle: true,
+
+        // Files.
+        srcDir: './src/',
+
+        // Output.
+        output,
+
+    }))
+    .make();
+
+    const script = await tmpName();
+
+    await writeFileAsync(script, data);
+    await nsisBuild(script);
+
+    await removeAsync(output);
+    await removeAsync(script);
+
+});