├── .github └── FUNDING.yml ├── VimeoSetup ├── App │ └── place setup files to this folder ├── vimeo.ico ├── VCRuntimeDLL │ ├── msvcp140.dll │ ├── ucrtbase.dll │ ├── concrt140.dll │ ├── concrt140d.dll │ ├── msvcp140_1.dll │ ├── msvcp140_2.dll │ ├── msvcp140d.dll │ ├── ucrtbased.dll │ ├── msvcp140_1d.dll │ ├── msvcp140_2d.dll │ ├── vccorlib140.dll │ ├── vccorlib140d.dll │ ├── vcruntime140.dll │ └── vcruntime140d.dll ├── build-setup.bat ├── build-setup [debug].bat └── vimeo-template.nsi ├── Screenshot ├── 1.png ├── 2.png └── 3.png ├── NSIS-UI-Plugin ├── resource.h ├── NSIS-UI-Plugin.rc ├── Qt-UI │ ├── Qt-FramelessWindow │ │ ├── FramelessMainWindow.cpp │ │ └── FramelessMainWindow.h │ ├── SetupPage-Qt.h │ └── SetupPage-Qt.cpp ├── Resources │ ├── DefaultTheme │ │ ├── DefaultTheme.qrc │ │ ├── minimize.svg │ │ ├── minimize_hover.svg │ │ ├── close.svg │ │ ├── close_hover.svg │ │ ├── openfolder.svg │ │ ├── openfolder_hover.svg │ │ ├── main.css │ │ ├── button_bk.svg │ │ └── qt.svg │ └── MainPage.ui ├── NSIS-UI-Plugin.sln ├── stdafx.cpp ├── InstallEvent.h ├── stdafx.h ├── SetupPageInterface.h ├── dllmain.cpp ├── DriverInfo.h ├── PluginContext.h ├── NSIS-UI-Plugin.vcxproj.filters ├── PluginContext.cpp ├── PluginCommon.h ├── NSISUIPlugin.cpp ├── NSIS-UI-Plugin.vcxproj └── DriverInfo.cpp ├── .gitignore ├── LICENSE ├── README_ch.md ├── README.md └── NsisScriptGenerate.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /VimeoSetup/App/place setup files to this folder: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Screenshot/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/Screenshot/1.png -------------------------------------------------------------------------------- /Screenshot/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/Screenshot/2.png -------------------------------------------------------------------------------- /Screenshot/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/Screenshot/3.png -------------------------------------------------------------------------------- /VimeoSetup/vimeo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/vimeo.ico -------------------------------------------------------------------------------- /NSIS-UI-Plugin/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/NSIS-UI-Plugin/resource.h -------------------------------------------------------------------------------- /NSIS-UI-Plugin/NSIS-UI-Plugin.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/NSIS-UI-Plugin/NSIS-UI-Plugin.rc -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/msvcp140.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/ucrtbase.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/ucrtbase.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/concrt140.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/concrt140d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/concrt140d.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/msvcp140_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/msvcp140_1.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/msvcp140_2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/msvcp140_2.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/msvcp140d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/msvcp140d.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/ucrtbased.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/ucrtbased.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/msvcp140_1d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/msvcp140_1d.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/msvcp140_2d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/msvcp140_2d.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/vccorlib140.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/vccorlib140d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/vccorlib140d.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/vcruntime140.dll -------------------------------------------------------------------------------- /VimeoSetup/VCRuntimeDLL/vcruntime140d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/VimeoSetup/VCRuntimeDLL/vcruntime140d.dll -------------------------------------------------------------------------------- /VimeoSetup/build-setup.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | python.exe ..\NsisScriptGenerate.py "%~dp0vimeo-template.nsi" "%~dp0App" 3 | "%NSIS_DIR%\makensisw.exe" "%~dp0\vimeo.nsi" 4 | 5 | PAUSE -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Qt-UI/Qt-FramelessWindow/FramelessMainWindow.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winsoft666/NSIS-UI-Plugin/HEAD/NSIS-UI-Plugin/Qt-UI/Qt-FramelessWindow/FramelessMainWindow.cpp -------------------------------------------------------------------------------- /VimeoSetup/build-setup [debug].bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | python.exe ..\NsisScriptGenerate.py "%~dp0vimeo-template.nsi" "%~dp0App" 3 | "%NSIS_DIR%\makensisw.exe" /DDEBUG=1 "%~dp0\vimeo.nsi" 4 | 5 | PAUSE -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/DefaultTheme.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main.css 4 | qt.svg 5 | close.svg 6 | minimize.svg 7 | close_hover.svg 8 | minimize_hover.svg 9 | button_bk.svg 10 | openfolder.svg 11 | openfolder_hover.svg 12 | 13 | 14 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/minimize.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/minimize_hover.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/close_hover.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 winsoft666 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/openfolder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/NSIS-UI-Plugin.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.902 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NSIS-UI-Plugin", "NSIS-UI-Plugin.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x86 = Debug|x86 11 | Release|x86 = Release|x86 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.ActiveCfg = Debug|Win32 15 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.Build.0 = Debug|Win32 16 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.ActiveCfg = Release|Win32 17 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {3A45B80A-084E-4E86-BF77-1A551F13B787} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/openfolder_hover.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Qt-UI/Qt-FramelessWindow/FramelessMainWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class FramelessMainWindow : public QMainWindow { 5 | Q_OBJECT 6 | public: 7 | enum class Direction { 8 | UP = 0, 9 | DOWN = 1, 10 | LEFT, 11 | RIGHT, 12 | LEFTTOP, 13 | LEFTBOTTOM, 14 | RIGHTBOTTOM, 15 | RIGHTTOP, 16 | NONE 17 | }; 18 | 19 | static void setAllWidgetMouseTracking(QWidget *widget); 20 | static void loadStyleSheetFile(const QString &sheetName, QWidget *widget); 21 | 22 | FramelessMainWindow(bool translucentBackground, QWidget *parent = Q_NULLPTR); 23 | virtual ~FramelessMainWindow(); 24 | virtual void setTitlebar(QVector titleBar); 25 | virtual void setResizeable(bool b); 26 | virtual bool resizeable() const; 27 | protected: 28 | bool eventFilter(QObject *target, QEvent *event) override; 29 | void mouseDoubleClickEvent(QMouseEvent *event) override; 30 | void mousePressEvent(QMouseEvent *event) override; 31 | void mouseMoveEvent(QMouseEvent *event) override; 32 | void mouseReleaseEvent(QMouseEvent *event) override; 33 | void resizeEvent(QResizeEvent *event) override; 34 | virtual void region(const QPoint &cursorGlobalPoint); 35 | protected: 36 | bool m_bLeftPressed; 37 | bool m_bEnableResize; 38 | Direction m_Direction; 39 | const int m_iResizeRegionPadding; 40 | QPoint m_DragPos; 41 | QVector m_titlebarWidget; 42 | }; 43 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: Microsoft YaHei; 3 | } 4 | 5 | QWidget#widgetTitle { 6 | border-top-right-radius: 8px; 7 | border-top-left-radius: 8px; 8 | background-color: rgb(79, 133, 233); 9 | } 10 | 11 | 12 | 13 | QWidget#centralWidget { 14 | background-color: rgb(255,255,255); 15 | border-radius: 8px; 16 | border: 1px solid rgb(79, 133, 233); 17 | /* 18 | [see also]: 19 | border-top-left-radius 20 | border-top-right-radius 21 | border-bottom-left-radius 22 | border-bottom-right-radius 23 | */ 24 | } 25 | 26 | QWidget#tabWidget::pane { 27 | /*border: none;*/ 28 | /*border-bottom-left-radius: 8px; 29 | border-bottom-right-radius: 8px;*/ 30 | } 31 | 32 | 33 | QSvgWidget#widgetLogo { 34 | image: url(:/DefaultTheme/qt.svg); 35 | } 36 | 37 | #labelTitle { 38 | color: rgb(255,255,255); 39 | } 40 | 41 | #pushButtonMin { 42 | border: none; 43 | image: url(:/DefaultTheme/minimize.svg); 44 | } 45 | 46 | #pushButtonMin:hover { 47 | border: none; 48 | image: url(:/DefaultTheme/minimize_hover.svg); 49 | } 50 | 51 | #pushButtonClose { 52 | border: none; 53 | image: url(:/DefaultTheme/close.svg); 54 | } 55 | 56 | #pushButtonClose:hover { 57 | border: none; 58 | image: url(:/DefaultTheme/close_hover.svg); 59 | } 60 | 61 | #pushButtonStartInstall, #pushButtonToFinishedPage, #pushButtonFinish { 62 | border: none; 63 | border-radius: 4px; 64 | color: #e6e6e6; 65 | background-color: #1296db; 66 | } 67 | 68 | #pushButtonStartInstall:hover, #pushButtonToFinishedPage:hover, #pushButtonFinish:hover { 69 | border: none; 70 | border-radius: 4px; 71 | color: #ffffff; 72 | background-color: #1296db; 73 | } 74 | 75 | #pushButtonSelectInstallDir { 76 | border: none; 77 | image: url(:/DefaultTheme/openfolder.svg); 78 | } 79 | 80 | #pushButtonSelectInstallDir:hover { 81 | border: none; 82 | image: url(:/DefaultTheme/openfolder_hover.svg); 83 | } -------------------------------------------------------------------------------- /NSIS-UI-Plugin/stdafx.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #include "stdafx.h" -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/button_bk.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README_ch.md: -------------------------------------------------------------------------------- 1 | [>>> English Version](README.md) 2 | 3 | # 介绍 4 | 提供一种创建漂亮地、现代化地Windows平台安装界面的方式。 5 | 默认使用Qt作为界面库,理论上你也可以使用任何界面库来创建安装界面,如[DuiLib](https://github.com/winsoft666/duilib2)等。 6 | 7 | --- 8 | 9 | # 依赖项 10 | 11 | **1. NSIS** 12 | 13 | 从[https://nsis.sourceforge.io/Download](https://nsis.sourceforge.io/Download) 下载NSIS并安装,新增系统环境变量`NSIS_DIR`为NSIS安装目录。 14 | 15 | **2. Python** 16 | 17 | 之所以需要安装Python,主要是为了执行`NsisScriptGenerate.py`脚本。 18 | 19 | 将`Python.exe`所在目录添加到`Path`环境变量。 20 | 21 | **3. Qt** 22 | 23 | 因为插件默认使用Qt作为界面库,所以需要安装Qt。 24 | 25 | Qt安装包会默认将安装目录添加`QTDIR`环境变量,如果没有自动添加,则需要手动添加。 26 | 27 | **4. Visual Studio** 28 | 29 | 安装 Visual Studio,并安装 Qt VS Tool 插件及配置 Qt 版本和路径。 30 | 31 | --- 32 | 33 | # 开始使用 34 | 35 | **编译NSIS-UI-Plugin** 36 | 37 | 安装完上面依赖项之后,打开`NSIS-UI-Plugin\NSIS-UI-Plugin.vcxproj`工程,在项目属性页中设置 Qt 版本。 38 | 39 | 然后编译该项目,Visual Studio 的生成后事件会自动将目标文件(Debug版:`nsQtPluginD.dll` Release版:`nsPlugin.dll`)拷贝到NSIS插件目录(`NSIS_DIR\Plugins\x86-unicode`)。 40 | 41 | 如果拷贝失败,可能是权限问题导致,需要以管理员权限运行 Visual Studio 后再次编译。 42 | 43 | **生成安装包** 44 | 45 | `VimeoSetup`是一个关于如何在NSIS中使用该插件的示例工程: 46 | 47 | ```txt 48 | App -- 放置需要打包到安装包中的文件 49 | VCRuntimeDLL -- 放置VC++运行时库文件(Debug版和Release版),Qt界面库默认采用MD模式编译,运行时需要依赖VC++运行时库 50 | vimeo-template.nsi -- NSIS模板文件,文件名的`-template`后缀固定的,NsisScriptGenerate.py会根据该模板生成vimeo.nsi 51 | build-setup [debug].bat -- 生成Debug版的安装包,即使用Debug版的Qt和NSIS-UI-Plugin 52 | build-setup [debug].bat -- 生成Release版的安装包 53 | ``` 54 | 55 | 将需要打包的文件放置到`App`目录,然后运行`build-setup.bat`生成安装包。 56 | 57 | >`NsisScriptGenerate.py`脚本功能:因为NSIS没有提供获取文件释放进度的功能,所以`NsisScriptGenerate.py`遍历`App`目录,采用`File`命令挨个添加文件,并调用插件接口`SetInstallStepDescription`通知安装详情。 58 | 59 | --- 60 | 61 | # 截图 62 | 63 | 仅用作示例,你可以使用任意界面库创建任意的界面。 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | # 赞助 72 | 73 | 感谢您能使用本项目,如果这个项目能对您产生帮助,对我而言也是一件非常开心的事情。 74 | 75 | **可以前往我的 Github [主页](https://github.com/winsoft666) 进行赞助。** 76 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/InstallEvent.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #pragma once 24 | 25 | #define INSTALL_EVENT_UI_PREPARED TEXT("UI_PREPARED") 26 | #define INSTALL_EVENT_START_EXTRACT_FILES TEXT("START_EXTRACT_FILES") 27 | #define INSTALL_EVENT_USER_CANCEL TEXT("USER_CANCEL") 28 | #define INSTALL_EVENT_BEFORE_FINISHED TEXT("BEFORE_FINISHED") -------------------------------------------------------------------------------- /NSIS-UI-Plugin/stdafx.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | // Support Chinese 30 | # pragma execution_character_set("utf-8") 31 | 32 | #if (defined _UNICODE || defined UNICODE) 33 | typedef std::wstring tstring; 34 | #else 35 | typedef std::string tstring; 36 | #endif 37 | 38 | #include "PluginCommon.h" 39 | #include "PluginContext.h" 40 | #include "InstallEvent.h" 41 | #include "SetupPageInterface.h" 42 | 43 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/SetupPageInterface.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #pragma once 24 | 25 | class SetupPageInterface { 26 | public: 27 | virtual void SetTitle(const tstring& title) = 0; 28 | virtual void SetRequiredSpaceKb(long kb) = 0; 29 | virtual void SetInstallDirectory(const tstring &dir) = 0; 30 | virtual tstring GetInstallDirectory() = 0; 31 | virtual void SetInstallStepDescription(const tstring &description, int progressValue = -1) = 0; 32 | virtual bool IsCreateDesktopShortcutEnabled() = 0; 33 | virtual bool IsAutoStartupOnBootEnabled() = 0; 34 | virtual void NsisExtractFilesFinished() = 0; 35 | }; -------------------------------------------------------------------------------- /NSIS-UI-Plugin/dllmain.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | 24 | #include "stdafx.h" 25 | 26 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { 27 | switch (ul_reason_for_call) { 28 | case DLL_PROCESS_ATTACH: { 29 | PluginContext::Instance()->SetPluginHandle(hModule); 30 | break; 31 | } 32 | case DLL_THREAD_ATTACH: { 33 | break; 34 | } 35 | case DLL_THREAD_DETACH: { 36 | break; 37 | } 38 | case DLL_PROCESS_DETACH: { 39 | PluginContext::Instance()->SetPluginHandle(NULL); 40 | break; 41 | } 42 | } 43 | return TRUE; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/DriverInfo.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #ifndef DRIVER_INFO_H_ 24 | #define DRIVER_INFO_H_ 25 | #pragma once 26 | 27 | #include 28 | 29 | enum { DRIVE_HOST = 7 }; 30 | 31 | class DriveInfo { 32 | public: 33 | static float GetFreeMB(int nDrive); // in MB 34 | static float GetTotalMB(int nDrive); // in MB 35 | 36 | static std::wstring GetVolume(int nDrive); 37 | static std::wstring GetRoot(int nDrive); 38 | static std::wstring GetFullName(int nDrive); 39 | static wchar_t GetLetter(int nDrive); 40 | static int GetType(int nDrive); 41 | static int GetPathType(const wchar_t *szPathName); 42 | static bool IsDriveAvailable(int nDrive); 43 | static void FormatName(std::wstring &sFileName); 44 | static int GetDrive(const wchar_t *szPathName); 45 | static bool IsMappedPath(const wchar_t *szPathName); 46 | static int IsRemotePath(const wchar_t *szPathName, bool bAllowFileCheck = true); 47 | static bool IsRemovablePath(const wchar_t *szPathName); 48 | static bool IsFixedPath(const wchar_t *szPathName); 49 | static int IsReadonlyPath(const wchar_t *szPathName); // -1 = no such path, else TRUE/FALSE 50 | static unsigned long GetSerialNumber(int nDrive); 51 | static bool IsUNCPath(const wchar_t *szPathName); 52 | }; 53 | 54 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [>>> 中文版](README_ch.md) 2 | 3 | # NSIS-UI-Plugin 4 | Create beautiful, modern UI setup for windows. 5 | 6 | Using Qt as default UI library, you can use any UI library in theory, such as [DuiLib](https://github.com/winsoft666/duilib2). 7 | 8 | --- 9 | 10 | # Dependencies 11 | 12 | **1. NSIS** 13 | 14 | Download [NSIS](https://nsis.sourceforge.io/Download) and install, then add `NSIS_DIR` system environment variable as NSIS install directory. 15 | 16 | **2. Python** 17 | 18 | Install Python just for execute `NsisScriptGenerate.py` script. 19 | 20 | After installed, add the direcotry where `Python.exe` is located to `Path` system environment variable. 21 | 22 | **3. Qt** 23 | 24 | NSIS-UI-Plugin use Qt as UI library by default. 25 | 26 | The Qt installer will add the `QtDIR` system environment variable as Qt install directory. If it not be added automatically, you need to add it manually. 27 | 28 | **4. Visual Studio** 29 | 30 | Install Visual Studio and "Qt VS Tool" plugin, configure Qt version and install directory. 31 | 32 | --- 33 | 34 | # Getting Started 35 | 36 | **Compile NSIS-UI-Plugin** 37 | 38 | After installing the above dependencies, then open `NSIS-UI-Plugin\NSIS-UI-Plugin.vcxproj` project, setting Qt version in project property page. 39 | 40 | Compile project, Visual Studio's *After Build Event* will copy target file(Debug: `nsQtPluginD.dll` Release: `nsPlugin.dll`) to NSIS plugin directory(`NSIS_DIR\Plugins\x86-unicode`). 41 | 42 | If the copy fails, it may be caused by permission issues. You need to run Visual Studio with administrator rights and compile again. 43 | 44 | **Generate Setup** 45 | 46 | `VimeoSetup` directory is sample about how to use NSIS-UI-Plugin. 47 | 48 | ```txt 49 | App -- Place the files that need to be packaged into the installer 50 | VCRuntimeDLL -- Place VC++ runtime files(Debug/Release), Qt compiled with MD mode by default. 51 | vimeo-template.nsi -- NSIS template script file,`-template` suffix is fixed, can't change. NsisScriptGenerate.py will generate vimeo.nsi based on this template. 52 | build-setup [debug].bat -- Generate Debug mode setup, that means using debug version Qt/NSIS-UI-Plugin. 53 | build-setup [debug].bat -- Generate Release mode setup 54 | ``` 55 | 56 | Place the files you need to packaged into the `App` directory, then run `build-setup.bat` to generate the installer. 57 | 58 | 59 | >`NsisScriptGenerate.py`: 60 | Since NSIS has no way to get file extract progress/details, so I write `NsisScriptGenerate.py`, enumerate `App` folder, add each file by `File` command, call `SetInstallStepDescription` interface to notify installing details. 61 | 62 | --- 63 | 64 | # Screenshot 65 | 66 | For example only, you can use any UI library to create any UI by yourself. 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | # Sponsor 75 | Thank you for using this project. It would be a great pleasure for me if this project can be of help to you. 76 | 77 | **You can go to my Github [homepage](https://github.com/winsoft666) to make a donation.** -------------------------------------------------------------------------------- /NSIS-UI-Plugin/PluginContext.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #pragma once 24 | #include "SetupPageInterface.h" 25 | 26 | class PluginContext { 27 | public: 28 | static PluginContext *Instance(); 29 | ~PluginContext(); 30 | void SetExtraParameters(ExtraParameters *param); 31 | ExtraParameters* GetExtraParameters(); 32 | 33 | void SetPluginHandle(HMODULE h); 34 | HMODULE pluginHandle() const; 35 | 36 | void SetParentHwnd(HWND h); 37 | HWND parentHwnd() const; 38 | 39 | HANDLE GetExitEvent(); 40 | 41 | void SetSetupPage(SetupPageInterface* page); 42 | SetupPageInterface* GetSetupPage(); 43 | 44 | void BindInstallEvent(const tstring &eventName, long nsisFuncAddress); 45 | void BindButtonClickedEvent(const tstring &buttonName, long nsisFuncAddress); 46 | 47 | bool ExecuteNsisFunction(long funcAddress); 48 | 49 | bool ExecuteInstallEventFunction(const tstring &installEvent); 50 | bool ExecuteButtonClickedEventFunction(const tstring &buttonName); 51 | 52 | private: 53 | PluginContext(); 54 | 55 | HANDLE m_exitEvent; 56 | 57 | HMODULE m_pluginHandle; 58 | HWND m_parentHwnd; 59 | SetupPageInterface* m_setupPage; 60 | ExtraParameters *m_pluginParms; 61 | std::map m_installEventBindMap; 62 | std::map m_buttonClickedEventBindMap; 63 | }; 64 | -------------------------------------------------------------------------------- /NsisScriptGenerate.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | g_extract_file_cmd_total = 0 5 | g_create_dir_cmd_total = 0 6 | g_cur_script_index = 0 7 | g_insert_nsis_script_list = [] 8 | g_root_dir = "" 9 | 10 | 11 | def nsis_cmd_num_statistics(dir): 12 | global g_extract_file_cmd_total 13 | global g_create_dir_cmd_total 14 | if not os.path.isdir(dir): 15 | return 16 | 17 | files = os.listdir(dir) 18 | for fi in files: 19 | fi_d = os.path.join(dir, fi) 20 | if os.path.isdir(fi_d): 21 | g_create_dir_cmd_total += 1 22 | nsis_cmd_num_statistics(fi_d) 23 | else: 24 | g_extract_file_cmd_total += 1 25 | 26 | 27 | def generate_nsis_script(dir): 28 | global g_cur_script_index 29 | 30 | if not os.path.isdir(dir): 31 | return 32 | 33 | for fi in os.listdir(dir): 34 | full_path = os.path.join(dir, fi) 35 | 36 | if os.path.isdir(full_path): 37 | sub_dir = full_path[len(g_root_dir):] 38 | g_cur_script_index += 1 39 | g_insert_nsis_script_list.append(' CreateDirectory "$INSTDIR{0}"'.format(sub_dir)) 40 | g_insert_nsis_script_list.append(' {0}::SetInstallStepDescription "Create Directory: {1}" {2}' 41 | .format('${UI_PLUGIN_NAME}', '$INSTDIR' + sub_dir, 42 | g_cur_script_index * 100 / (g_extract_file_cmd_total + g_create_dir_cmd_total))) 43 | generate_nsis_script(full_path) 44 | else: 45 | g_cur_script_index += 1 46 | g_insert_nsis_script_list.append(' SetOutPath "$INSTDIR{0}"'.format(dir[len(g_root_dir):])) 47 | g_insert_nsis_script_list.append(' File "{0}"'.format( full_path)) 48 | g_insert_nsis_script_list.append(' {0}::SetInstallStepDescription "Extract File: $INSTDIR{1}" {2}' 49 | .format('${UI_PLUGIN_NAME}', full_path[len(g_root_dir):], g_cur_script_index * 100 / (g_extract_file_cmd_total + g_create_dir_cmd_total))) 50 | 51 | 52 | def do_main(nsis_script_template_path): 53 | global g_root_dir 54 | if g_root_dir[len(g_root_dir) - 1] == '\\': 55 | g_root_dir = g_root_dir[:len(g_root_dir) - 1] 56 | nsis_cmd_num_statistics(g_root_dir) 57 | print("file total: " + str(g_extract_file_cmd_total) + ", dir total: " + str(g_create_dir_cmd_total)) 58 | 59 | generate_nsis_script(g_root_dir) 60 | g_insert_nsis_script_list.append(' ${UI_PLUGIN_NAME}::SetInstallStepDescription "Finished" 100') 61 | 62 | f = open(nsis_script_template_path, "r") 63 | all_nsis_script_lines = [] 64 | cur_line_index = -1 65 | insert_line_index = -1 66 | for s in f.readlines(): 67 | all_nsis_script_lines.append(s) 68 | cur_line_index += 1 69 | if s.find('Function ___ExtractFiles') != -1: 70 | insert_line_index = cur_line_index + 1 71 | f.close() 72 | 73 | if insert_line_index == -1: 74 | return 75 | 76 | for s in g_insert_nsis_script_list: 77 | all_nsis_script_lines.insert(insert_line_index, s) 78 | insert_line_index += 1 79 | 80 | nsis_script_path = nsis_script_template_path[:len(nsis_script_template_path) - len('-template.nsi')] 81 | nsis_script_path += '.nsi' 82 | f = open(nsis_script_path, "w") 83 | all_script = '\n'.join(all_nsis_script_lines) 84 | f.write(all_script) 85 | f.close() 86 | 87 | if __name__ == '__main__': 88 | nsis_script_template_path = sys.argv[1] 89 | g_root_dir = sys.argv[2] 90 | do_main(nsis_script_template_path) -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Qt-UI/SetupPage-Qt.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | 24 | #pragma once 25 | #include 26 | #include 27 | #include 28 | #include "ui_MainPage.h" 29 | #include "Qt-FramelessWindow/FramelessMainWindow.h" 30 | #include 31 | 32 | inline QString tstringToQString(const tstring &str) { 33 | QString strResult; 34 | #if (defined _UNICODE || defined UNICODE) 35 | strResult = QString::fromStdWString(str); 36 | #else 37 | strResult = QString::fromStdString(str); 38 | #endif 39 | return strResult; 40 | } 41 | 42 | inline tstring QStringTotstring(const QString &str) { 43 | #if (defined _UNICODE || defined UNICODE) 44 | return str.toStdWString(); 45 | #else 46 | return str.toStdString(); 47 | #endif 48 | } 49 | 50 | class SetupPage_Qt : 51 | public FramelessMainWindow 52 | , public SetupPageInterface { 53 | Q_OBJECT 54 | 55 | public: 56 | SetupPage_Qt(QWidget *parent = Q_NULLPTR); 57 | 58 | void SetTitle(const tstring &title) override; 59 | void SetRequiredSpaceKb(long kb) override; 60 | void SetInstallDirectory(const tstring &dir) override; 61 | tstring GetInstallDirectory() override; 62 | void SetInstallStepDescription(const tstring &description, int progressValue = -1) override; 63 | void NsisExtractFilesFinished() override; 64 | bool IsCreateDesktopShortcutEnabled() override; 65 | bool IsAutoStartupOnBootEnabled() override; 66 | private: 67 | void updateDriverInfo(); 68 | void exitSetup(); 69 | private: 70 | Ui::MainPage ui; 71 | long m_requiredSpaceKb; 72 | std::future m_addListItemAsync; 73 | QMutex m_waitingAddItemsMutex; 74 | QStringList m_waitingAddItems; 75 | }; 76 | 77 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/NSIS-UI-Plugin.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Source Files 6 | 7 | 8 | Source Files 9 | 10 | 11 | Source Files 12 | 13 | 14 | Source Files 15 | 16 | 17 | Source Files 18 | 19 | 20 | Qt UI 21 | 22 | 23 | Qt UI\Qt-FramelessWindow 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | 50 | 51 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 52 | qrc;* 53 | false 54 | 55 | 56 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 57 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 58 | true 59 | 60 | 61 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 62 | h;hh;hpp;hxx;hm;inl;inc;xsd 63 | true 64 | 65 | 66 | {1ea0ff3b-f918-4e8e-bd21-2d6ae8503cd0} 67 | 68 | 69 | {da7da05f-87d6-4dd6-8d65-50d4425b1178} 70 | 71 | 72 | {4eea09d2-cd05-4c97-a2b3-ec721277cc7e} 73 | 74 | 75 | 76 | 77 | Resource Files 78 | 79 | 80 | 81 | 82 | Resource Files\DefaultTheme 83 | 84 | 85 | 86 | 87 | Resource Files\DefaultTheme 88 | 89 | 90 | 91 | 92 | Resource Files 93 | 94 | 95 | 96 | 97 | Qt UI 98 | 99 | 100 | Qt UI\Qt-FramelessWindow 101 | 102 | 103 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/PluginContext.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #include "stdafx.h" 24 | #include "PluginContext.h" 25 | 26 | PluginContext::PluginContext() : 27 | m_parentHwnd(NULL) 28 | , m_setupPage(NULL) 29 | , m_pluginParms(NULL) 30 | , m_pluginHandle(NULL) { 31 | m_exitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 32 | } 33 | 34 | PluginContext *PluginContext::Instance() { 35 | static PluginContext *context = NULL; 36 | if (!context) { 37 | context = new PluginContext(); 38 | } 39 | return context; 40 | } 41 | 42 | 43 | PluginContext::~PluginContext() { 44 | if (m_exitEvent) { 45 | CloseHandle(m_exitEvent); 46 | m_exitEvent = NULL; 47 | } 48 | } 49 | 50 | void PluginContext::SetExtraParameters(ExtraParameters *param) { 51 | m_pluginParms = param; 52 | } 53 | 54 | ExtraParameters *PluginContext::GetExtraParameters() { 55 | return m_pluginParms; 56 | } 57 | 58 | void PluginContext::SetPluginHandle(HMODULE h) { 59 | m_pluginHandle = h; 60 | } 61 | 62 | HMODULE PluginContext::pluginHandle() const { 63 | return m_pluginHandle; 64 | } 65 | 66 | void PluginContext::SetParentHwnd(HWND h) { 67 | m_parentHwnd = h; 68 | } 69 | 70 | HWND PluginContext::parentHwnd() const { 71 | return m_parentHwnd; 72 | } 73 | 74 | HANDLE PluginContext::GetExitEvent() { 75 | return m_exitEvent; 76 | } 77 | 78 | void PluginContext::SetSetupPage(SetupPageInterface* page) { 79 | m_setupPage = page; 80 | } 81 | 82 | SetupPageInterface* PluginContext::GetSetupPage() { 83 | return m_setupPage; 84 | } 85 | 86 | void PluginContext::BindInstallEvent(const tstring &eventName, long nsisFuncAddress) { 87 | m_installEventBindMap[eventName] = nsisFuncAddress; 88 | } 89 | 90 | void PluginContext::BindButtonClickedEvent(const tstring &eventName, long nsisFuncAddress) { 91 | m_buttonClickedEventBindMap[eventName] = nsisFuncAddress; 92 | } 93 | 94 | bool PluginContext::ExecuteNsisFunction(long funcAddress) { 95 | if (m_pluginParms) { 96 | m_pluginParms->ExecuteCodeSegment(funcAddress, NULL); 97 | return true; 98 | } 99 | return false; 100 | } 101 | 102 | bool PluginContext::ExecuteInstallEventFunction(const tstring &installEvent) { 103 | if (m_pluginParms && m_installEventBindMap.find(installEvent) != m_installEventBindMap.end()) { 104 | m_pluginParms->ExecuteCodeSegment(m_installEventBindMap[installEvent] - 1, NULL); 105 | return true; 106 | } 107 | return false; 108 | } 109 | 110 | bool PluginContext::ExecuteButtonClickedEventFunction(const tstring &buttonName) { 111 | if (m_pluginParms && m_buttonClickedEventBindMap.find(buttonName) != m_buttonClickedEventBindMap.end()) { 112 | m_pluginParms->ExecuteCodeSegment(m_buttonClickedEventBindMap[buttonName] - 1, NULL); 113 | return true; 114 | } 115 | return false; 116 | } 117 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/PluginCommon.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | 24 | #ifndef _PLUGIN_COMMON_H_ 25 | #define _PLUGIN_COMMON_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #define PLUGIN_BUF_LEN 1024 32 | 33 | #define NSISAPI extern "C" __declspec(dllexport) void __cdecl 34 | 35 | 36 | #define EXDLL_INIT() { \ 37 | g_stringsize=stringSize; \ 38 | g_stacktop=stacktop; \ 39 | g_variables=variables; } 40 | 41 | 42 | 43 | typedef struct _stack_t { 44 | struct _stack_t *next; 45 | TCHAR text[1]; 46 | } stack_t; 47 | 48 | 49 | static unsigned int g_stringsize; 50 | static stack_t **g_stacktop; 51 | static TCHAR *g_variables; 52 | 53 | enum { 54 | INST_0, // $0 55 | INST_1, // $1 56 | INST_2, // $2 57 | INST_3, // $3 58 | INST_4, // $4 59 | INST_5, // $5 60 | INST_6, // $6 61 | INST_7, // $7 62 | INST_8, // $8 63 | INST_9, // $9 64 | INST_R0, // $R0 65 | INST_R1, // $R1 66 | INST_R2, // $R2 67 | INST_R3, // $R3 68 | INST_R4, // $R4 69 | INST_R5, // $R5 70 | INST_R6, // $R6 71 | INST_R7, // $R7 72 | INST_R8, // $R8 73 | INST_R9, // $R9 74 | INST_CMDLINE, // $CMDLINE 75 | INST_INSTDIR, // $INSTDIR 76 | INST_OUTDIR, // $OUTDIR 77 | INST_EXEDIR, // $EXEDIR 78 | INST_LANG, // $LANGUAGE 79 | __INST_LAST 80 | }; 81 | 82 | 83 | static int __stdcall popstring(TCHAR *str) { 84 | stack_t *th; 85 | if (!g_stacktop || !*g_stacktop) return 1; 86 | th = (*g_stacktop); 87 | _tcscpy(str, th->text); 88 | *g_stacktop = th->next; 89 | GlobalFree((HGLOBAL)th); 90 | return 0; 91 | } 92 | 93 | 94 | static void __stdcall pushstring(const TCHAR *str) { 95 | stack_t *th; 96 | if (!g_stacktop) return; 97 | th = (stack_t *)GlobalAlloc(GPTR, sizeof(stack_t) + g_stringsize); 98 | lstrcpyn(th->text, str, g_stringsize); 99 | th->next = *g_stacktop; 100 | *g_stacktop = th; 101 | } 102 | 103 | static long __stdcall popint() { 104 | TCHAR buf[512] = {0}; 105 | popstring(buf); 106 | return _ttol(buf); 107 | } 108 | 109 | static void __stdcall pushint(long value) { 110 | TCHAR buf[512] = {0}; 111 | StringCchPrintf(buf, 512, TEXT("%ld"), value); 112 | pushstring(buf); 113 | } 114 | 115 | 116 | static TCHAR *__stdcall getuservariable(int varnum) { 117 | if (varnum < 0 || varnum >= __INST_LAST) return NULL; 118 | return g_variables + varnum * g_stringsize; 119 | } 120 | 121 | static void __stdcall setuservariable(int varnum, TCHAR *var) { 122 | if (var != NULL && varnum >= 0 && varnum < __INST_LAST) 123 | lstrcpy(g_variables + varnum * g_stringsize, var); 124 | } 125 | 126 | 127 | enum NSPIM { 128 | NSPIM_UNLOAD, // This is the last message a plugin gets, do final cleanup 129 | NSPIM_GUIUNLOAD, // Called after .onGUIEnd 130 | }; 131 | 132 | typedef UINT_PTR (*NSISPLUGINCALLBACK)(enum NSPIM); 133 | 134 | // extra_parameters data structures containing other interesting stuff 135 | // but the stack, variables and HWND passed on to plug-ins. 136 | typedef struct { 137 | int autoclose; 138 | int all_user_var; 139 | int exec_error; 140 | int abort; 141 | int exec_reboot; // NSIS_SUPPORT_REBOOT 142 | int reboot_called; // NSIS_SUPPORT_REBOOT 143 | int XXX_cur_insttype; // depreacted 144 | int plugin_api_version; // see NSISPIAPIVER_CURR 145 | // used to be XXX_insttype_changed 146 | int silent; // NSIS_CONFIG_SILENT_SUPPORT 147 | int instdir_error; 148 | int rtl; 149 | int errlvl; 150 | int alter_reg_view; 151 | int status_update; 152 | } exec_flags_t; 153 | 154 | #ifndef NSISCALL 155 | #define NSISCALL __stdcall 156 | #endif 157 | 158 | typedef struct { 159 | exec_flags_t *exec_flags; 160 | int (NSISCALL *ExecuteCodeSegment)(int, HWND); 161 | void (NSISCALL *validate_filename)(TCHAR *); 162 | int (NSISCALL *RegisterPluginCallback)(HMODULE, NSISPLUGINCALLBACK); // returns 0 on success, 1 if already registered and < 0 on errors 163 | } ExtraParameters; 164 | 165 | 166 | 167 | 168 | 169 | #endif //_PLUGIN_COMMON_H_ 170 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/DefaultTheme/qt.svg: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 24 | image/svg+xml 25 | 27 | 28 | 29 | 30 | 32 | 39 | 40 | 60 | 63 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | 93 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Qt-UI/SetupPage-Qt.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #include "stdafx.h" 24 | #include "SetupPage-Qt.h" 25 | #include "../DriverInfo.h" 26 | 27 | SetupPage_Qt::SetupPage_Qt(QWidget *parent) 28 | : FramelessMainWindow(true, parent) 29 | , m_requiredSpaceKb(0) { 30 | ui.setupUi(this); 31 | 32 | ui.tabWidget->setCurrentIndex(0); 33 | ui.progressBarInstall->setMinimum(0); 34 | ui.progressBarInstall->setMaximum(100); 35 | ui.pushButtonToFinishedPage->setEnabled(false); 36 | 37 | FramelessMainWindow::setAllWidgetMouseTracking(this); 38 | setResizeable(false); 39 | setTitlebar({ ui.widgetTitle}); 40 | 41 | FramelessMainWindow::loadStyleSheetFile(":/DefaultTheme/main.css", this); 42 | 43 | ui.tabWidget->tabBar()->hide(); 44 | 45 | connect(ui.pushButtonMin, &QPushButton::clicked, [this]() { 46 | this->showMinimized(); 47 | }); 48 | 49 | connect(ui.pushButtonClose, &QPushButton::clicked, [this]() { 50 | PluginContext::Instance()->ExecuteInstallEventFunction(INSTALL_EVENT_USER_CANCEL); 51 | 52 | exitSetup(); 53 | }); 54 | 55 | connect(ui.pushButtonSelectInstallDir, &QPushButton::clicked, [this]() { 56 | QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), "/", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); 57 | dir = QDir::toNativeSeparators(dir); 58 | ui.lineEditInstallDir->setText(dir); 59 | updateDriverInfo(); 60 | }); 61 | 62 | connect(ui.pushButtonStartInstall, &QPushButton::clicked, this, [this]() { 63 | QString strDir = ui.lineEditInstallDir->text(); 64 | if (strDir.length() == 0) 65 | return; 66 | 67 | QDir dir(strDir); 68 | if (!dir.exists()) { 69 | if (!dir.mkdir(strDir)) { 70 | return; 71 | } 72 | } 73 | 74 | PluginContext::Instance()->ExecuteInstallEventFunction(INSTALL_EVENT_START_EXTRACT_FILES); 75 | 76 | ui.tabWidget->setCurrentIndex(1); 77 | }); 78 | 79 | connect(ui.pushButtonToFinishedPage, &QPushButton::clicked, [this]() { 80 | ui.tabWidget->setCurrentIndex(2); 81 | }); 82 | 83 | connect(ui.pushButtonFinish, &QPushButton::clicked, [this]() { 84 | PluginContext::Instance()->ExecuteInstallEventFunction(INSTALL_EVENT_BEFORE_FINISHED); 85 | 86 | exitSetup(); 87 | }); 88 | 89 | m_addListItemAsync = std::async(std::launch::async, [this]() { 90 | HANDLE exitEvent = PluginContext::Instance()->GetExitEvent(); 91 | while (WaitForSingleObject(exitEvent, 100) != WAIT_OBJECT_0) { 92 | m_waitingAddItemsMutex.lock(); 93 | if (m_waitingAddItems.size() > 0) { 94 | QMetaObject::invokeMethod(this, [this]() { 95 | ui.listWidgetInstallDetails->addItems(m_waitingAddItems); 96 | ui.listWidgetInstallDetails->scrollToBottom(); 97 | }, Qt::BlockingQueuedConnection); 98 | m_waitingAddItems.clear(); 99 | } 100 | m_waitingAddItemsMutex.unlock(); 101 | } 102 | }); 103 | 104 | PluginContext::Instance()->ExecuteInstallEventFunction(INSTALL_EVENT_UI_PREPARED); 105 | } 106 | 107 | 108 | void SetupPage_Qt::SetTitle(const tstring &title) { 109 | this->setWindowTitle(tstringToQString(title)); 110 | } 111 | 112 | 113 | void SetupPage_Qt::SetRequiredSpaceKb(long kb) { 114 | m_requiredSpaceKb = kb; 115 | updateDriverInfo(); 116 | } 117 | 118 | void SetupPage_Qt::SetInstallDirectory(const tstring &dir) { 119 | ui.lineEditInstallDir->setText(tstringToQString(dir)); 120 | updateDriverInfo(); 121 | } 122 | 123 | tstring SetupPage_Qt::GetInstallDirectory() { 124 | QString strDir = ui.lineEditInstallDir->text(); 125 | return QStringTotstring(strDir); 126 | } 127 | 128 | void SetupPage_Qt::SetInstallStepDescription(const tstring &description, int progressValue /* = -1 */) { 129 | QMetaObject::invokeMethod(this, [this, progressValue]() { 130 | if (progressValue >= 0 && progressValue <= 100) { 131 | ui.progressBarInstall->setValue(progressValue); 132 | } 133 | }, Qt::QueuedConnection); 134 | 135 | m_waitingAddItemsMutex.lock(); 136 | m_waitingAddItems.push_back(tstringToQString(description)); 137 | m_waitingAddItemsMutex.unlock(); 138 | } 139 | 140 | 141 | void SetupPage_Qt::NsisExtractFilesFinished() { 142 | QMetaObject::invokeMethod(this, [this]() { 143 | ui.pushButtonToFinishedPage->setEnabled(true); 144 | }, Qt::QueuedConnection); 145 | } 146 | 147 | bool SetupPage_Qt::IsCreateDesktopShortcutEnabled() { 148 | return ui.checkBoxDesktopShortcut->isChecked(); 149 | } 150 | 151 | 152 | bool SetupPage_Qt::IsAutoStartupOnBootEnabled() { 153 | return ui.checkBoxAutoStartupOnBoot->isChecked(); 154 | } 155 | 156 | void SetupPage_Qt::updateDriverInfo() { 157 | int driver = DriveInfo::GetDrive(ui.lineEditInstallDir->text().toStdWString().c_str()); 158 | if (driver > 0) { 159 | float driverTotalMb = DriveInfo::GetTotalMB(driver); 160 | float driverFreeMb = DriveInfo::GetFreeMB(driver); 161 | 162 | QString strDiskInfo = QString("Required: %1MB Free: %2MB Total: %3MB").arg(m_requiredSpaceKb / 1024).arg(driverFreeMb).arg(driverTotalMb); 163 | ui.labelDiskInfo->setText(strDiskInfo); 164 | } 165 | } 166 | 167 | void SetupPage_Qt::exitSetup() { 168 | HANDLE exitEvent = PluginContext::Instance()->GetExitEvent(); 169 | if (exitEvent) 170 | SetEvent(exitEvent); 171 | if (m_addListItemAsync.valid()) 172 | m_addListItemAsync.wait(); 173 | this->close(); 174 | } 175 | 176 | 177 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/NSISUIPlugin.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | #include "stdafx.h" 24 | #include "Qt-UI/SetupPage-Qt.h" 25 | 26 | 27 | #define NSMETHOD_INIT() do {\ 28 | PluginContext::Instance()->SetExtraParameters(extra); \ 29 | PluginContext::Instance()->SetParentHwnd(hwndParent); \ 30 | if(extra) { \ 31 | extra->RegisterPluginCallback(PluginContext::Instance()->pluginHandle(), PluginCallback); } \ 32 | EXDLL_INIT(); } while(false) 33 | 34 | static UINT_PTR PluginCallback(enum NSPIM msg) { 35 | return 0; 36 | } 37 | 38 | NSISAPI ShowSetupUI(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 39 | NSMETHOD_INIT(); 40 | 41 | TCHAR szTitle[MAX_PATH] = { 0 }; 42 | popstring(szTitle); 43 | 44 | TCHAR szDefaultInstallDir[MAX_PATH] = { 0 }; 45 | popstring(szDefaultInstallDir); 46 | 47 | TCHAR szNsisPluginDir[MAX_PATH] = { 0 }; 48 | popstring(szNsisPluginDir); 49 | 50 | // Start show Qt UI 51 | // 52 | if (_tcslen(szNsisPluginDir) > 0) { 53 | QApplication::addLibraryPath(tstringToQString(szNsisPluginDir)); 54 | } 55 | 56 | 57 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) 58 | QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 59 | #endif 60 | int argc = 1; 61 | char currentPath[MAX_PATH] = { 0 }; 62 | GetModuleFileNameA(NULL, currentPath, MAX_PATH); 63 | char *argv[2] = { {currentPath}, {} }; 64 | QApplication app(argc, argv); 65 | SetupPage_Qt *mainPage = new SetupPage_Qt(); 66 | mainPage->setWindowTitle(tstringToQString(szTitle)); 67 | mainPage->SetInstallDirectory(szDefaultInstallDir); 68 | PluginContext::Instance()->SetSetupPage(mainPage); 69 | mainPage->show(); 70 | app.exec(); 71 | } 72 | 73 | NSISAPI OutputDebugInfo(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 74 | NSMETHOD_INIT(); 75 | 76 | TCHAR szInfo[1024] = { 0 }; 77 | popstring(szInfo); 78 | 79 | TCHAR szAllInfo[1124] = { 0 }; 80 | StringCchPrintf(szAllInfo, 1124, TEXT("[NSIS-UI-Plugin] %s\r\n"), szInfo); 81 | OutputDebugString(szAllInfo); 82 | } 83 | 84 | NSISAPI BindInstallEventToNsisFunc(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 85 | NSMETHOD_INIT(); 86 | 87 | TCHAR szEventName[MAX_PATH] = { 0 }; 88 | popstring(szEventName); 89 | long callbackFuncAddress = popint(); 90 | 91 | PluginContext::Instance()->BindInstallEvent(szEventName, callbackFuncAddress); 92 | } 93 | 94 | NSISAPI BindButtonClickedEventToNsisFunc(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 95 | NSMETHOD_INIT(); 96 | 97 | TCHAR szControlName[MAX_PATH] = { 0 }; 98 | popstring(szControlName); 99 | 100 | long callbackFuncAddress = popint(); 101 | 102 | PluginContext::Instance()->BindButtonClickedEvent(szControlName, callbackFuncAddress); 103 | } 104 | 105 | NSISAPI NsisExtractFilesFinished(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 106 | NSMETHOD_INIT(); 107 | 108 | if (PluginContext::Instance()->GetSetupPage()) { 109 | PluginContext::Instance()->GetSetupPage()->NsisExtractFilesFinished(); 110 | } 111 | } 112 | 113 | 114 | NSISAPI SetInstallDirectory(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 115 | NSMETHOD_INIT(); 116 | TCHAR szDir[MAX_PATH] = { 0 }; 117 | popstring(szDir); 118 | 119 | if (PluginContext::Instance()->GetSetupPage()) { 120 | PluginContext::Instance()->GetSetupPage()->SetInstallDirectory(szDir); 121 | } 122 | } 123 | 124 | NSISAPI GetInstallDirectory(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 125 | NSMETHOD_INIT(); 126 | tstring strDir; 127 | if (PluginContext::Instance()->GetSetupPage()) { 128 | strDir = PluginContext::Instance()->GetSetupPage()->GetInstallDirectory(); 129 | } 130 | pushstring(strDir.c_str()); 131 | } 132 | 133 | 134 | NSISAPI SetInstallStepDescription(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 135 | NSMETHOD_INIT(); 136 | TCHAR szDescription[MAX_PATH] = { 0 }; 137 | long percent = -1; 138 | 139 | popstring(szDescription); 140 | percent = popint(); 141 | 142 | if (PluginContext::Instance()->GetSetupPage()) { 143 | PluginContext::Instance()->GetSetupPage()->SetInstallStepDescription(szDescription, percent); 144 | } 145 | } 146 | 147 | NSISAPI IsCreateDesktopShortcutEnabled(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 148 | NSMETHOD_INIT(); 149 | long enabled = 0; 150 | 151 | if (PluginContext::Instance()->GetSetupPage()) { 152 | enabled = PluginContext::Instance()->GetSetupPage()->IsCreateDesktopShortcutEnabled() ? 1 : 0; 153 | } 154 | pushint(enabled); 155 | } 156 | 157 | NSISAPI IsAutoStartupOnBootEnabled(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 158 | NSMETHOD_INIT(); 159 | long enabled = 0; 160 | 161 | if (PluginContext::Instance()->GetSetupPage()) { 162 | enabled = PluginContext::Instance()->GetSetupPage()->IsAutoStartupOnBootEnabled() ? 1 : 0; 163 | } 164 | pushint(enabled); 165 | } 166 | 167 | NSISAPI BackgroundRun(HWND hwndParent, int stringSize, TCHAR *variables, stack_t **stacktop, ExtraParameters *extra) { 168 | NSMETHOD_INIT(); 169 | long nsisFuncAddress = popint(); 170 | 171 | std::thread t = std::thread([nsisFuncAddress]() { 172 | PluginContext::Instance()->ExecuteNsisFunction(nsisFuncAddress - 1); 173 | }); 174 | t.detach(); 175 | } -------------------------------------------------------------------------------- /NSIS-UI-Plugin/NSIS-UI-Plugin.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {B12702AD-ABFB-343A-A199-8E24837244A3} 15 | QtVS_v301 16 | 10.0.17763.0 17 | NSIS-UI-Plugin 18 | 19 | 20 | 21 | DynamicLibrary 22 | v141 23 | Unicode 24 | 25 | 26 | DynamicLibrary 27 | v141 28 | Unicode 29 | 30 | 31 | 32 | $(MSBuildProjectDirectory)\QtMsBuild 33 | 34 | 35 | $(SolutionDir)$(Platform)\$(Configuration)\ 36 | $(ProjectName) 37 | 38 | 39 | $(SolutionDir)$(Platform)\$(Configuration)\ 40 | $(ProjectName) 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 5.13.1_x86 59 | core;gui;svg;widgets 60 | 61 | 62 | 5.13.1_x86 63 | core;gui;svg;widgets 64 | 65 | 66 | 67 | 68 | 69 | 70 | stdafx.h 71 | 72 | 73 | true 74 | Disabled 75 | ProgramDatabase 76 | MultiThreadedDebugDLL 77 | true 78 | Use 79 | stdafx.h 80 | $(IntDir)$(TargetName).pch 81 | NSISQTPLUGIN_LIB;%(PreprocessorDefinitions) 82 | 83 | 84 | Windows 85 | $(OutDir)\$(ProjectName).dll 86 | true 87 | 88 | 89 | copy "$(TargetPath)" "$(NSIS_DIR)\Plugins\x86-unicode\nsQtPluginD.dll" /y 90 | 91 | 92 | 93 | 94 | stdafx.h 95 | 96 | 97 | true 98 | 99 | MultiThreadedDLL 100 | true 101 | Use 102 | stdafx.h 103 | $(IntDir)$(TargetName).pch 104 | NSISQTPLUGIN_LIB;%(PreprocessorDefinitions) 105 | 106 | 107 | Windows 108 | $(OutDir)\$(ProjectName).dll 109 | false 110 | 111 | 112 | copy "$(TargetPath)" "$(NSIS_DIR)\Plugins\x86-unicode\nsQtPlugin.dll" /y 113 | 114 | 115 | 116 | 117 | NotUsing 118 | NotUsing 119 | 120 | 121 | 122 | 123 | 124 | NotUsing 125 | NotUsing 126 | 127 | 128 | 129 | Create 130 | Create 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/DriverInfo.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************************************************************************************* 2 | #@@ *@ *@@%#@@# &@ #@%@@, @( &@ .@. @@@@@@@% @ @( &@ .@@@%&@@& &@ @@# %@ 3 | #@/@ *@ *@ @% &@ %@ @/ @( &@ .@. @, ,@ @ @( &@ @@ @* &@ @,&@ %@ 4 | #@ @( *@ ,@ &@ #@ @( &@ .@. @, @* @ @( &@ @& &@ @, *@ %@ 5 | #@ &@ *@ @@@, &@ *@@% @( &@ .@. @, &@ @ @( &@ @, &@ @, @( %@ 6 | #@ ,@ *@ .@@. &@ (@@ @( &@ .@. @@@@@@% @ @( &@ @, @@@@@& &@ @, @@ %@ 7 | #@ @/ *@ *@ &@ &@ @( @@ .@. @, @ @( @@ @& && &@ @, (@. %@ 8 | #@ @@,@ @@ (@ &@ @# &@ (@ (@. .@. @, @ (@ (@. @@ && &@ @, @%%@ 9 | #@ *@@ (@@%#&@& &@ %@@#%@@( @@@%&@@( .@. @, @@@@@@@@ @@@%&@@( @@@%&@@@ &@ @, %@@ 10 | 11 | * Copyright (C) 2018 - 2020, winsoft666, . 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 14 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 16 | * 17 | * Expect bugs 18 | * 19 | * Please use and enjoy. 20 | * Please let me know of any bugs/improvements that you have found/implemented and I will fix/incorporate them into this file. 21 | ********************************************************************************************************************************************************/ 22 | 23 | 24 | #include "DriverInfo.h" 25 | #include 26 | #ifndef WIN32_LEAN_AND_MEAN 27 | #define WIN32_LEAN_AND_MEAN 28 | #endif 29 | #include 30 | #include 31 | 32 | 33 | float DriveInfo::GetFreeMB(int nDrive) { 34 | std::wstring sRoot; 35 | unsigned long totalClusters, freeClusters, sectors, bytes; 36 | 37 | assert(nDrive > 0 && nDrive <= 26); 38 | 39 | if (IsDriveAvailable(nDrive)) { 40 | sRoot = GetRoot(nDrive); 41 | 42 | ::GetDiskFreeSpaceW(sRoot.c_str(), §ors, &bytes, &freeClusters, &totalClusters); 43 | 44 | // do maths like this to avoid truncation 45 | // errors 46 | float fSpace = (float)sectors; 47 | fSpace *= bytes; 48 | fSpace *= freeClusters; 49 | fSpace /= 1048576; 50 | 51 | return fSpace; 52 | } 53 | 54 | return 0.0f; 55 | } 56 | 57 | std::wstring DriveInfo::GetVolume(int nDrive) { 58 | std::wstring sVolume, sRoot; 59 | 60 | assert(nDrive > 0 && nDrive <= 26); 61 | 62 | 63 | 64 | if (IsDriveAvailable(nDrive)) { 65 | sRoot = GetRoot(nDrive); 66 | 67 | wchar_t buf[20] = { 0 }; 68 | GetVolumeInformationW(sRoot.c_str(), buf, 20, NULL, NULL, NULL, NULL, 0); 69 | 70 | std::wstring strVolume = buf; 71 | FormatName(sVolume); 72 | 73 | return sVolume; 74 | } 75 | 76 | return L""; 77 | } 78 | 79 | std::wstring DriveInfo::GetRoot(int nDrive) { 80 | std::wstring sRoot; 81 | 82 | sRoot = GetLetter(nDrive); 83 | sRoot += L":\\"; 84 | 85 | return sRoot; 86 | } 87 | 88 | std::wstring DriveInfo::GetFullName(int nDrive) { 89 | std::wstring sFullName, sLetter, sVolume; 90 | 91 | assert(nDrive > 0 && nDrive <= 26); 92 | 93 | if (IsDriveAvailable(nDrive)) { 94 | sLetter = GetLetter(nDrive); 95 | sVolume = GetVolume(nDrive); 96 | 97 | sFullName = sVolume + L" (" + sLetter + L":)"; 98 | 99 | return sFullName; 100 | } 101 | 102 | return L""; 103 | } 104 | 105 | float DriveInfo::GetTotalMB(int nDrive) { 106 | std::wstring sRoot; 107 | unsigned long totalClusters, freeClusters, sectors, bytes; 108 | 109 | assert(nDrive > 0 && nDrive <= 26); 110 | 111 | if (IsDriveAvailable(nDrive)) { 112 | sRoot = GetRoot(nDrive); 113 | 114 | ::GetDiskFreeSpaceW(sRoot.c_str(), §ors, &bytes, &freeClusters, &totalClusters); 115 | 116 | // do maths like this to avoid truncation 117 | // errors 118 | float fSpace = (float)sectors; 119 | fSpace *= bytes; 120 | fSpace *= totalClusters; 121 | fSpace /= 1048576; 122 | 123 | return fSpace; 124 | } 125 | 126 | return 0.0f; 127 | } 128 | 129 | wchar_t DriveInfo::GetLetter(int nDrive) { 130 | assert(nDrive > 0 && nDrive <= 26); 131 | 132 | return (wchar_t)(nDrive + L'A' - 1); 133 | } 134 | 135 | int DriveInfo::GetType(int nDrive) { 136 | std::wstring sVolume; 137 | 138 | assert(nDrive > 0 && nDrive <= 26); 139 | 140 | // shortcut to avoid floppy access 141 | if (nDrive == 1 || nDrive == 2) 142 | return DRIVE_REMOVABLE; 143 | 144 | return ::GetDriveTypeW(GetRoot(nDrive).c_str()); 145 | } 146 | 147 | int DriveInfo::GetPathType(const wchar_t *szPathName) { 148 | int nDrive = GetDrive(szPathName); 149 | 150 | if (nDrive >= 0) 151 | return GetType(nDrive); 152 | 153 | else if (IsRemotePath(szPathName) > 0) 154 | return DRIVE_REMOTE; 155 | 156 | else 157 | return DRIVE_UNKNOWN; 158 | } 159 | 160 | void DriveInfo::FormatName(std::wstring &sFilename) { 161 | //std::wstring sTemp, sChar; 162 | //int nLen, nChar; 163 | //wchar_t cChar, cLastChar = ' '; // space 164 | 165 | //// this function accepts pathnames and names with spaces 166 | //sFilename.MakeLower(); 167 | //nLen = sFilename.GetLength(); 168 | 169 | //// for each word make the first letter upper case 170 | //for (nChar = 0; nChar < nLen; nChar++) 171 | //{ 172 | // cChar = sFilename[nChar]; 173 | 174 | // if (cLastChar == ' ' || cLastChar == '\\') 175 | // { 176 | // sChar = std::wstring(cChar); 177 | // sChar.MakeUpper(); 178 | // cChar = sChar[0]; 179 | // } 180 | 181 | // sTemp += cChar; 182 | // cLastChar = cChar; 183 | //} 184 | 185 | //sFilename = sTemp; 186 | } 187 | 188 | bool DriveInfo::IsDriveAvailable(int nDrive) { 189 | int nCurDrive; 190 | int nRes; 191 | 192 | // save cur drive and try to change to drive 193 | nCurDrive = _getdrive(); 194 | nRes = _chdrive(nDrive); 195 | 196 | // if change successful change back before return 197 | if (nRes == 0) 198 | _chdrive(nCurDrive); 199 | 200 | return (nRes == 0) ? true : false; 201 | } 202 | 203 | bool DriveInfo::IsUNCPath(const wchar_t *szPathName) { 204 | return (wcsstr(szPathName, L"\\\\") == szPathName); 205 | } 206 | 207 | int DriveInfo::GetDrive(const wchar_t *szPathName) { 208 | int nDrive = 0; 209 | 210 | if (wcsstr(szPathName, L":") == szPathName + 1) { 211 | wchar_t cDrive = szPathName[0]; 212 | cDrive = (wchar_t)toupper(cDrive); 213 | nDrive = cDrive - 64; 214 | 215 | } 216 | 217 | return nDrive ? nDrive : -1; 218 | } 219 | 220 | bool DriveInfo::IsMappedPath(const wchar_t *szPathName) { 221 | int nDrive; 222 | 223 | nDrive = GetDrive(szPathName); 224 | 225 | if (nDrive <= 0) 226 | return FALSE; 227 | 228 | return (GetType(nDrive) == DRIVE_REMOTE); 229 | } 230 | 231 | int DriveInfo::IsRemotePath(const wchar_t *szPathName, bool bAllowFileCheck) { 232 | if (bAllowFileCheck) { 233 | DWORD dwAttr = ::GetFileAttributesW(szPathName); 234 | 235 | if (dwAttr == 0xffffffff) 236 | return -1; 237 | } 238 | 239 | return (IsUNCPath(szPathName) || IsMappedPath(szPathName)); 240 | } 241 | 242 | bool DriveInfo::IsFixedPath(const wchar_t *szPathName) { 243 | int nDrive = GetDrive(szPathName); 244 | 245 | if (nDrive == -1) // unknown 246 | return FALSE; 247 | 248 | return (GetType(nDrive) == DRIVE_FIXED); 249 | } 250 | 251 | bool DriveInfo::IsRemovablePath(const wchar_t *szPathName) { 252 | int nDrive = GetDrive(szPathName); 253 | 254 | if (nDrive == -1) // unknown 255 | return FALSE; 256 | 257 | return (GetType(nDrive) == DRIVE_REMOVABLE); 258 | } 259 | 260 | int DriveInfo::IsReadonlyPath(const wchar_t *szPathName) { 261 | DWORD dwAttr = ::GetFileAttributesW(szPathName); 262 | 263 | if (dwAttr == 0xffffffff) 264 | return -1; 265 | 266 | // else 267 | return (dwAttr & FILE_ATTRIBUTE_READONLY); 268 | } 269 | 270 | unsigned long DriveInfo::GetSerialNumber(int nDrive) { 271 | if (GetType(nDrive) != DRIVE_FIXED) 272 | return 0; 273 | 274 | DWORD dwHDSerialNum = 0; 275 | 276 | if (!::GetVolumeInformationW(GetRoot(nDrive).c_str(), NULL, 0, &dwHDSerialNum, NULL, NULL, NULL, 0)) 277 | return (DWORD) - 1; 278 | 279 | return dwHDSerialNum; 280 | } 281 | -------------------------------------------------------------------------------- /VimeoSetup/vimeo-template.nsi: -------------------------------------------------------------------------------- 1 | # ========================= User Defined Macro ============================== 2 | # Most time you just need edit user defined macro 3 | !define PRODUCT_NAME "vimeo" 4 | !define EXE_NAME "vimeo.exe" 5 | !define EXE_RELATIVE_PATH "bin\vimeo.exe" 6 | !define PRODUCT_VERSION "1.0.0.1" 7 | !define PRODUCT_PUBLISHER "vimeo" 8 | !define PRODUCT_LEGAL "Copyright (C) 1999-2024 vimeo, All Rights Reserved" 9 | !define INSTALL_ICON_PATH "vimeo.ico" 10 | !define UNINSTALL_ICON_PATH "vimeo.ico" 11 | !define DEFAULT_INSTALL_DIR "$PROGRAMFILES\${PRODUCT_NAME}" 12 | 13 | !ifdef DEBUG 14 | !define UI_PLUGIN_NAME nsQtPluginD 15 | !define VC_RUNTIME_DLL_SUFFIX d 16 | !define QT_DLL_SUFFIX d 17 | !else 18 | !define UI_PLUGIN_NAME nsQtPlugin 19 | !define VC_RUNTIME_DLL_SUFFIX 20 | !define QT_DLL_SUFFIX 21 | !endif 22 | 23 | # ========================= User Defined Macro End ============================ 24 | 25 | !include "LogicLib.nsh" 26 | !include "nsDialogs.nsh" 27 | 28 | 29 | # ===================== Setup Info ============================= 30 | VIProductVersion "${PRODUCT_VERSION}" 31 | VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}" 32 | VIAddVersionKey "ProductName" "${PRODUCT_NAME}" 33 | VIAddVersionKey "CompanyName" "${PRODUCT_PUBLISHER}" 34 | VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}" 35 | VIAddVersionKey "InternalName" "${EXE_NAME}" 36 | VIAddVersionKey "FileDescription" "${PRODUCT_NAME}" 37 | VIAddVersionKey "LegalCopyright" "${PRODUCT_LEGAL}" 38 | 39 | # ==================== NSIS Attribute ================================ 40 | 41 | Unicode True 42 | SetCompressor LZMA 43 | !ifdef DEBUG 44 | Name "${PRODUCT_NAME} [Debug]" 45 | OutFile "${PRODUCT_NAME}-setup-debug.exe" 46 | !else 47 | Name "${PRODUCT_NAME}" 48 | OutFile "${PRODUCT_NAME}-setup.exe" 49 | !endif 50 | 51 | # ICON 52 | Icon "${INSTALL_ICON_PATH}" 53 | UninstallIcon "${UNINSTALL_ICON_PATH}" 54 | 55 | # UAC 56 | # RequestExecutionLevel none|user|highest|admin 57 | RequestExecutionLevel admin 58 | 59 | 60 | # Custom Install Page 61 | Page custom QtUiPage 62 | 63 | 64 | # Show Uninstall details 65 | UninstPage instfiles 66 | 67 | # ======================= Qt Page ========================= 68 | Function QtUiPage 69 | ${UI_PLUGIN_NAME}::OutputDebugInfo "NSIS Plugin Dir: $PLUGINSDIR" 70 | 71 | GetFunctionAddress $0 OnUIPrepared 72 | ${UI_PLUGIN_NAME}::BindInstallEventToNsisFunc "UI_PREPARED" $0 73 | 74 | GetFunctionAddress $0 OnStartExtractFiles 75 | ${UI_PLUGIN_NAME}::BindInstallEventToNsisFunc "START_EXTRACT_FILES" $0 76 | 77 | GetFunctionAddress $0 OnBeforeFinished 78 | ${UI_PLUGIN_NAME}::BindInstallEventToNsisFunc "BEFORE_FINISHED" $0 79 | 80 | GetFunctionAddress $0 OnUserCancelInstall 81 | ${UI_PLUGIN_NAME}::BindInstallEventToNsisFunc "USER_CANCEL" $0 82 | 83 | ${UI_PLUGIN_NAME}::ShowSetupUI "${PRODUCT_NAME} Setup" "${DEFAULT_INSTALL_DIR}" "$PLUGINSDIR" 84 | FunctionEnd 85 | 86 | Function OnUIPrepared 87 | ${UI_PLUGIN_NAME}::OutputDebugInfo "OnUIPrepared" 88 | FunctionEnd 89 | 90 | Function OnStartExtractFiles 91 | ${UI_PLUGIN_NAME}::OutputDebugInfo "OnStartExtractFiles" 92 | 93 | ${UI_PLUGIN_NAME}::GetInstallDirectory 94 | Pop $0 95 | StrCmp $0 "" InstallAbort 0 96 | StrCpy $INSTDIR "$0" 97 | ${UI_PLUGIN_NAME}::OutputDebugInfo "Install Dir: $0" 98 | 99 | SetOutPath $INSTDIR 100 | 101 | GetFunctionAddress $0 ___ExtractFiles 102 | ${UI_PLUGIN_NAME}::BackgroundRun $0 103 | 104 | 105 | InstallAbort: 106 | FunctionEnd 107 | 108 | 109 | Function OnUserCancelInstall 110 | ${UI_PLUGIN_NAME}::OutputDebugInfo "OnUserCancelInstall" 111 | 112 | Abort 113 | FunctionEnd 114 | 115 | 116 | Function OnBeforeFinished 117 | ${UI_PLUGIN_NAME}::OutputDebugInfo "OnBeforeFinished" 118 | 119 | SetShellVarContext all 120 | CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" 121 | CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR${EXE_RELATIVE_PATH}" 122 | CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall ${PRODUCT_NAME}.lnk" "$INSTDIR\uninst.exe" 123 | SetShellVarContext current 124 | 125 | 126 | # Create Desktop Shortcut 127 | ${UI_PLUGIN_NAME}::IsCreateDesktopShortcutEnabled 128 | Pop $0 129 | ${If} $0 == 1 130 | SetShellVarContext all 131 | CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR${EXE_RELATIVE_PATH}" 132 | SetShellVarContext current 133 | ${EndIf} 134 | 135 | 136 | # Auto Startup On Boot 137 | ${UI_PLUGIN_NAME}::IsAutoStartupOnBootEnabled 138 | Pop $0 139 | ${If} $0 == 1 140 | WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "${PRODUCT_NAME}" "$INSTDIR${EXE_RELATIVE_PATH}" 141 | ${EndIf} 142 | FunctionEnd 143 | 144 | 145 | # !!! Don't Edit This Function !!! 146 | # This Function Generated by Python Script(NsisScriptGenerate.py) 147 | Function ___ExtractFiles 148 | Call OnAfterExtractFiles 149 | FunctionEnd 150 | 151 | 152 | Function OnAfterExtractFiles 153 | ${UI_PLUGIN_NAME}::OutputDebugInfo "OnAfterExtractFiles" 154 | ${UI_PLUGIN_NAME}::NsisExtractFilesFinished 155 | Call CreateUninstall 156 | FunctionEnd 157 | 158 | 159 | 160 | Function CreateUninstall 161 | WriteUninstaller "$INSTDIR\uninst.exe" 162 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}" 163 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\uninst.exe" 164 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayIcon" "$INSTDIR\${EXE_NAME}" 165 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "Publisher" "$INSTDIR\${PRODUCT_PUBLISHER}" 166 | FunctionEnd 167 | 168 | # Add an empty section, avoid compile error. 169 | Section "None" 170 | SectionEnd 171 | 172 | 173 | # Uninstall Section 174 | Section "Uninstall" 175 | 176 | SetShellVarContext all 177 | Delete "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" 178 | Delete "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall ${PRODUCT_NAME}.lnk" 179 | RMDir "$SMPROGRAMS\${PRODUCT_NAME}\" 180 | Delete "$DESKTOP\${PRODUCT_NAME}.lnk" 181 | SetShellVarContext current 182 | 183 | SetOutPath "$INSTDIR" 184 | 185 | ; Delete installed files 186 | Delete "$INSTDIR\*.*" 187 | 188 | SetOutPath "$DESKTOP" 189 | 190 | RMDir /r "$INSTDIR" 191 | RMDir "$INSTDIR" 192 | 193 | SetAutoClose true 194 | SectionEnd 195 | 196 | 197 | 198 | Function .onInit 199 | # makesure plugin directory exist 200 | InitPluginsDir 201 | 202 | # place Qt dlls to plugin directory 203 | File /oname=$PLUGINSDIR\Qt5Core${QT_DLL_SUFFIX}.dll "$%QTDIR%\bin\Qt5Core${QT_DLL_SUFFIX}.dll" 204 | File /oname=$PLUGINSDIR\Qt5Gui${QT_DLL_SUFFIX}.dll "$%QTDIR%\bin\Qt5Gui${QT_DLL_SUFFIX}.dll" 205 | File /oname=$PLUGINSDIR\Qt5Widgets${QT_DLL_SUFFIX}.dll "$%QTDIR%\bin\Qt5Widgets${QT_DLL_SUFFIX}.dll" 206 | File /oname=$PLUGINSDIR\Qt5Svg${QT_DLL_SUFFIX}.dll "$%QTDIR%\bin\Qt5Svg${QT_DLL_SUFFIX}.dll" 207 | 208 | CreateDirectory $PLUGINSDIR\platforms 209 | File /oname=$PLUGINSDIR\platforms\qwindows${QT_DLL_SUFFIX}.dll "$%QTDIR%\plugins\platforms\qwindows${QT_DLL_SUFFIX}.dll" 210 | 211 | CreateDirectory $PLUGINSDIR\styles 212 | File /oname=$PLUGINSDIR\styles\qwindowsvistastyle${QT_DLL_SUFFIX}.dll "$%QTDIR%\plugins\styles\qwindowsvistastyle${QT_DLL_SUFFIX}.dll" 213 | 214 | CreateDirectory $PLUGINSDIR\imageformats 215 | File /oname=$PLUGINSDIR\imageformats\qgif${QT_DLL_SUFFIX}.dll "$%QTDIR%\plugins\imageformats\qgif${QT_DLL_SUFFIX}.dll" 216 | File /oname=$PLUGINSDIR\imageformats\qicns${QT_DLL_SUFFIX}.dll "$%QTDIR%\plugins\imageformats\qicns${QT_DLL_SUFFIX}.dll" 217 | File /oname=$PLUGINSDIR\imageformats\qico${QT_DLL_SUFFIX}.dll "$%QTDIR%\plugins\imageformats\qico${QT_DLL_SUFFIX}.dll" 218 | File /oname=$PLUGINSDIR\imageformats\qjpeg${QT_DLL_SUFFIX}.dll "$%QTDIR%\plugins\imageformats\qjpeg${QT_DLL_SUFFIX}.dll" 219 | File /oname=$PLUGINSDIR\imageformats\qsvg${QT_DLL_SUFFIX}.dll "$%QTDIR%\plugins\imageformats\qsvg${QT_DLL_SUFFIX}.dll" 220 | CreateDirectory $PLUGINSDIR\iconengines 221 | 222 | File /oname=$PLUGINSDIR\iconengines\qsvgicon${QT_DLL_SUFFIX}.dll "$%QTDIR%\plugins\iconengines\qsvgicon${QT_DLL_SUFFIX}.dll" 223 | 224 | # place vc runtime dlls to plugin directory 225 | File /oname=$PLUGINSDIR\concrt140${VC_RUNTIME_DLL_SUFFIX}.dll "VCRuntimeDLL\concrt140${VC_RUNTIME_DLL_SUFFIX}.dll" 226 | File /oname=$PLUGINSDIR\msvcp140${VC_RUNTIME_DLL_SUFFIX}.dll "VCRuntimeDLL\msvcp140${VC_RUNTIME_DLL_SUFFIX}.dll" 227 | File /oname=$PLUGINSDIR\msvcp140_1${VC_RUNTIME_DLL_SUFFIX}.dll "VCRuntimeDLL\msvcp140_1${VC_RUNTIME_DLL_SUFFIX}.dll" 228 | File /oname=$PLUGINSDIR\msvcp140_2${VC_RUNTIME_DLL_SUFFIX}.dll "VCRuntimeDLL\msvcp140_2${VC_RUNTIME_DLL_SUFFIX}.dll" 229 | File /oname=$PLUGINSDIR\ucrtbase${VC_RUNTIME_DLL_SUFFIX}.dll "VCRuntimeDLL\ucrtbase${VC_RUNTIME_DLL_SUFFIX}.dll" 230 | File /oname=$PLUGINSDIR\vccorlib140${VC_RUNTIME_DLL_SUFFIX}.dll "VCRuntimeDLL\vccorlib140${VC_RUNTIME_DLL_SUFFIX}.dll" 231 | File /oname=$PLUGINSDIR\vcruntime140${VC_RUNTIME_DLL_SUFFIX}.dll "VCRuntimeDLL\vcruntime140${VC_RUNTIME_DLL_SUFFIX}.dll" 232 | FunctionEnd 233 | 234 | 235 | 236 | Function .onInstSuccess 237 | 238 | FunctionEnd 239 | 240 | 241 | Function .onInstFailed 242 | MessageBox MB_ICONQUESTION|MB_YESNO "Install Failed!" /SD IDYES IDYES +2 IDNO +1 243 | FunctionEnd 244 | 245 | 246 | 247 | # Before Uninstall 248 | Function un.onInit 249 | MessageBox MB_ICONQUESTION|MB_YESNO "Are you sure to uninstall ${PRODUCT_NAME}?" /SD IDYES IDYES +2 IDNO +1 250 | Abort 251 | FunctionEnd 252 | 253 | Function un.onUninstSuccess 254 | 255 | FunctionEnd 256 | 257 | 258 | -------------------------------------------------------------------------------- /NSIS-UI-Plugin/Resources/MainPage.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainPage 4 | 5 | 6 | 7 | 0 8 | 0 9 | 682 10 | 369 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 0 20 | 21 | 22 | 0 23 | 24 | 25 | 0 26 | 27 | 28 | 0 29 | 30 | 31 | 0 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 0 41 | 0 42 | 43 | 44 | 45 | 46 | 30 47 | 30 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | NSIS Modern UI Setup by Using Qt 56 | 57 | 58 | 59 | 60 | 61 | 62 | Qt::Horizontal 63 | 64 | 65 | 66 | 560 67 | 20 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 0 77 | 0 78 | 79 | 80 | 81 | 82 | 26 83 | 26 84 | 85 | 86 | 87 | PointingHandCursor 88 | 89 | 90 | background-image: url(:/DefaultTheme/minimize.svg); 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 0 102 | 0 103 | 104 | 105 | 106 | 107 | 26 108 | 26 109 | 110 | 111 | 112 | PointingHandCursor 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 0 126 | 127 | 128 | Qt::ElideNone 129 | 130 | 131 | false 132 | 133 | 134 | false 135 | 136 | 137 | 138 | Tab 1 139 | 140 | 141 | 142 | 143 | 400 144 | 140 145 | 100 146 | 30 147 | 148 | 149 | 150 | 151 | 0 152 | 0 153 | 154 | 155 | 156 | 157 | 100 158 | 30 159 | 160 | 161 | 162 | 163 | 100 164 | 30 165 | 166 | 167 | 168 | PointingHandCursor 169 | 170 | 171 | Start Install 172 | 173 | 174 | 175 | 176 | 177 | 450 178 | 50 179 | 31 180 | 21 181 | 182 | 183 | 184 | PointingHandCursor 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 30 194 | 50 195 | 421 196 | 21 197 | 198 | 199 | 200 | 201 | 202 | 203 | 30 204 | 80 205 | 421 206 | 16 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | Tab 2 217 | 218 | 219 | 220 | 221 | 30 222 | 20 223 | 621 224 | 23 225 | 226 | 227 | 228 | 24 229 | 230 | 231 | 232 | 233 | 234 | 540 235 | 250 236 | 100 237 | 30 238 | 239 | 240 | 241 | 242 | 0 243 | 0 244 | 245 | 246 | 247 | 248 | 100 249 | 30 250 | 251 | 252 | 253 | 254 | 100 255 | 30 256 | 257 | 258 | 259 | PointingHandCursor 260 | 261 | 262 | Next 263 | 264 | 265 | 266 | 267 | 268 | 30 269 | 50 270 | 611 271 | 171 272 | 273 | 274 | 275 | 276 | 277 | 278 | Tab 3 279 | 280 | 281 | 282 | 283 | 230 284 | 110 285 | 171 286 | 16 287 | 288 | 289 | 290 | Create Desktop Shortcut 291 | 292 | 293 | 294 | 295 | 296 | 230 297 | 80 298 | 151 299 | 16 300 | 301 | 302 | 303 | Auto Startup On Boot 304 | 305 | 306 | 307 | 308 | 309 | 260 310 | 200 311 | 100 312 | 30 313 | 314 | 315 | 316 | 317 | 0 318 | 0 319 | 320 | 321 | 322 | 323 | 100 324 | 30 325 | 326 | 327 | 328 | 329 | 100 330 | 30 331 | 332 | 333 | 334 | PointingHandCursor 335 | 336 | 337 | Finish 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | QSvgWidget 349 | QWidget 350 |
qsvgwidget.h
351 | 1 352 |
353 |
354 | 355 | 356 |
357 | --------------------------------------------------------------------------------