To facilitate a better understanding and application of the configuration process during the installation package creation, we have organized the configuration of nsNiuniuSkin from manual configuration to fully automated integration, providing comprehensive explanations and instructions!
We will use the leeqia_mountain template as an example to demonstrate how to configure and package:
Before formally starting the configuration, there are a few points that need to be explained:
. 7z compression tool and python, bat packaging scripts
├── FilesToInstall Directory for the list of files to be packaged
├── Helper Packaging auxiliary tools
├── NiuNiuCaptureElectronDemo Electron project example (for demonstrating how to package Electron programs)
├── NSIS Files related to the NSIS packaging tool
├── Output Directory for storing completed packaging files
├── SetupScripts Core nsis script for packaging
│ └── leeqia_mountain Location of nsi files and installation/uninstallation icons
│ ├── LanguageFiles Language translation files
│ └── skin Configuration files for the installation interface
│ └── images Images required for the installation interface
└── Sign Signing scripts
Regardless of the packaging method used, essential UI modifications need to be made, such as replacing icons and certain prompt messages on the interface. Our UI template has been designed to be as simple and aesthetic as possible. After replacing some icons, you should be able to use it directly as the installation package interface for your product.
If you are not familiar with duilib's interface configuration, we do not recommend modifying the layout of the interface. Try to replace only the images with those of the original size. In the SetupScripts\leeqia_mountain\skin directory, files related to UI are stored:
Filename | Description |
---|---|
install.xml | This is a master script that includes the title bar, shadows, and language selection box. |
configpage.xml | Configure the first interface displayed when the installation package is opened. It is also used for selecting the installation path. |
licensepage.xml | Configure the license agreement display interface. |
installingpage.xml | Interface during the installation process. |
finishpage.xml | Interface after the installation is complete. |
uninstallpage.xml | Uninstallation entry interface. |
uninstallingpage.xml | Interface during the uninstallation process. |
uninstallfinishpage.xml | Interface after uninstallation is complete. |
msgBox.xml | Secondary popup window. |
The above XML can be edited in a text tool, and modifications to attributes should refer to the attribute list of duilib_ultimate. Additionally, we provide an online preview and debugging tool that allows you to preview all interface effects without repackaging. This will significantly increase the efficiency of your interface modifications. See the following link:
http://ggniu.com/articles/nsniuniuskin_designer.html
Note:
Manual configuration and packaging are suitable for projects where product and version information does not change frequently. For example, if you have a product with information on the installation package (mainly version information) that does not change often, configuring and packaging in this way is the most time-efficient.
In the soft_setup.nsi file, modify the following macro definitions according to your project:
# ====================== Custom Macros for Product Information==============================
!define /ifndef PRODUCT_NAME "利洽科技截图控件" #Product name
!define /ifndef PRODUCT_NAME_EN "Leeqia ScreenCapture" #English product name
!define /ifndef PRODUCT_PATHNAME "Leeqia_Capture" #KEY used for installation and uninstallation, same as the guid in Electron
!define /ifndef INSTALL_APPEND_PATH "Leeqia_Capture" #Name appended to the installation path
!define /ifndef INSTALL_DEFALT_SETUPPATH "$PROGRAMFILES32\${INSTALL_APPEND_PATH}" #Default generated installation path
!define /ifndef EXE_NAME "NiuNiuCapture.exe" #Main program EXE file name
!define /ifndef PRODUCT_VERSION "2.5.0.0" #Version number
!define /ifndef PRODUCT_PUBLISHER "Leeqia" #Publisher
!define /ifndef PRODUCT_LEGAL "Leeqia Copyright (c) 2020" #Copyright information
!define /ifndef INSTALL_MODE_ALL_USERS "all" # all current, whether to install for all users, default is yes, affects registry, shortcuts, start menu, etc.
!define /ifndef INSTALL_EXECUTION_LEVEL "admin" # If INSTALL_MODE_ALL_USERS is current, please synchronize this to user (RequestExecutionLevel none|user|highest|admin)
!define /ifndef INSTALL_OUTPUT_NAME "Test_PC_Setup_v2.5.0.exe" #Default setup package name, controlled by bat
!define /ifndef INSTALL_LOCATION_KEY "InstPath" #Default key value for installation location in the registry
# ====================== The specific macro definitions above can be pre-defined in the pre_define.nsh file, and can be arbitrarily specified as other values ==============================
In the leeqia_mountain directory, there is an rtf document named according to the language ID. Modify its content accordingly. If there are new language license agreement files, please add them.
Copy the files to be installed to the FilesToInstall directory. The packaging script will compress and package this directory (including multi-level subdirectories). This step is generally used in the testing phase; in the actual packaging process, copying is usually automated through scripts.
Double-click the specified bat file to complete the packaging:
Filename | Description |
---|---|
build-leeqia_mountain.bat | Compresses the files into 7z.app before packaging |
build-leeqia_mountain-nozip.bat | Packages the files directly |
build-leeqia_mountain-online.bat | Packages the online installation package and generates online data packet files and configurations simultaneously |
After going through the above process, doesn't packaging seem really simple? With just five steps, you can create your own installation!
In order to integrate more conveniently into existing packaging processes, we have developed a set of command-line interfaces using Python. You no longer need to modify macro definitions in the soft_setup.nsi file; you only need to control it through the command-line parameters of our package.py.
The reason this can be set up this way is because NSIS macro definitions support the /ifndef attribute, indicating that it should only be defined if not defined before this. In our soft_setup.nsi file, we first import a file called pre_define.nsh at the top. If a macro is already defined in pre_define.nsh, it will take precedence.
In fact, NSIS itself also supports passing macro definitions through the command line. In this case, the priority of a macro being effective is:
NSIS Command Line > pre_define.nsh > soft_setup.nsi
With this premise, in the package.py, we convert the received command-line parameters into NSIS macro definitions and write them to the pre_define.nsh file. This way, we achieve parameterization of configuration information during packaging.
The package.py has various specific parameters, as follows:
optional arguments:
-h, --help show this help message and exit
--log_dir LOG_DIR if None, log will be written to console
--project_name PROJECT_NAME the project name, eg: leeqia_moutain
--package_mode PACKAGE_MODE the package mode, 0:7z, 1:nozip, 2: online
--need_sign NEED_SIGN check if sign uninstall and setup file
--build_for_electron BUILD_FOR_ELECTRON check if build for electron, if True, we will call npm build in scripts
--electron_build_path ELECTRON_BUILD_PATH electron build path, the dir path of package.json
--generate_latest_file GENERATE_LATEST_FILE check if generate latest.yml for electron-updater
--files_toinstall_name FILES_TOINSTALL_NAME local directory name for nsNiuniuSkin, FilesToInstall default
--auto_write_uninst AUTO_WRITE_UNINST check if generate uninstall automatically, default False
--uninst_file_name UNINST_FILE_NAME the uninstall file name
--src_files_dir SRC_FILES_DIR the unpacked file path, if specified, we will copy the files to [files_toinstall_name] and package them
--PRODUCT_NAME PRODUCT_NAME setup file name, if None, we will use the definition in soft_setup.nsi
--PRODUCT_NAME_EN PRODUCT_NAME_EN setup file name, if None, we will use the definition in soft_setup.nsi
--INSTALL_OUTPUT_NAME INSTALL_OUTPUT_NAME setup file name, if None, we will use the definition in soft_setup.nsi
--PRODUCT_VERSION PRODUCT_VERSION the package version, if None, we will use the definition in soft_setup.nsi
--EXE_NAME EXE_NAME the main exe name, if None, we will use the definition in soft_setup.nsi
--INSTALL_LOCATION_KEY INSTALL_LOCATION_KEY the install localtion key, if None, we will use the definition in soft_setup.nsi
--INSTALL_APPEND_PATH INSTALL_APPEND_PATH the append path when install, if None, we will use the definition in soft_setup.nsi
--PRODUCT_PATHNAME PRODUCT_PATHNAME the identity in reg, if None, we will use the definition in soft_setup.nsi
--INSTALL_DEFALT_SETUPPATH INSTALL_DEFALT_SETUPPATH the default setup path, if None, we will use the definition in soft_setup.nsi
--TEST_SLEEP TEST_SLEEP if True, it will sleep when extract the files, if None, we will use the definition in soft_setup.nsi
--INSTALL_DEFAULT_SHOTCUT INSTALL_DEFAULT_SHOTCUT check if add shortcut for default, if None, we will use the definition in soft_setup.nsi
--INSTALL_DEFAULT_AUTORUN INSTALL_DEFAULT_AUTORUN check if add auto run for default, if None, we will use the definition in soft_setup.nsi
--INSTALL_EXECUTION_LEVEL INSTALL_EXECUTION_LEVEL execution level(admin/user), if None, we will use the definition in soft_setup.nsi
--INSTALL_MODE_ALL_USERS INSTALL_MODE_ALL_USERS install mode(all/current), if None, we will use the definition in soft_setup.nsi
--INSTALL_DOWNLOAD_BASEURL INSTALL_DOWNLOAD_BASEURL download base url for online install, if None, we will use the definition in soft_setup.nsi
--PRODUCT_LEGAL PRODUCT_LEGAL product legal, if None, we will use the definition in soft_setup.nsi
--PRODUCT_PUBLISHER PRODUCT_PUBLISHER publisher info, if None, we will use the definition in soft_setup.nsi
Specific explanations for each parameter are as follows:
Parameter Name | Parameter Type | Parameter Purpose | Remarks |
---|---|---|---|
--log_dir | str | Specifies the path for log writing | If not specified, logs will be printed to the console |
--project_name | str | Name of the packaged project |
Corresponds to the template name used, e.g., leeqia_moutian for the High Mountain version * Required field |
--package_mode | int | Packaging mode |
Used to specify the packaging method: 1: 7z decompression mode, 2: non-7z mode, 3: create online installer * Required field |
--need_sign | bool | Whether to sign the uninstall and install programs | Default is False, if specified as True, code signing configuration is also required |
--build_for_electron | bool | Whether to package an electron program | Default is False |
--electron_build_path | str | Directory for packaging electron programs | Required if build_for_electron is True |
--generate_latest_file | bool | Whether to generate the latest.yml for electron-updater | Default is False |
--files_toinstall_name | str | Local packaging directory name for nsNiuniuSkin | Default is FilesToInstall, can be left unspecified |
--auto_write_uninst | bool | Whether to automatically generate the uninstall program during installation | Default is False, programs generated this way cannot be signed, it is recommended not to specify |
--uninst_file_name | str | Uninstall program filename | Default is uninst.exe |
--src_files_dir | str | Source directory to be packaged |
If specified, files from this directory will be copied to our local packaging directory during packaging, ignored when build_for_electron is True |
--PRODUCT_NAME | str | Name of the packaged product | Used for shortcuts, start menu, and installation interface in Chinese mode |
--PRODUCT_NAME_EN | str | English name of the packaged product |
Used for shortcuts, start menu, and installation interface in English mode Note: If adding a new language, parameters need to be expanded in package.py or set in soft_setup.nsi |
--INSTALL_OUTPUT_NAME | str | Name of the generated installation package | Required when build_fore_electron is False, also used during signing |
--PRODUCT_VERSION | str | Product version number | Version number |
--EXE_NAME | str | Name of the main program to be installed | Used in shortcuts, start menu, etc. |
--INSTALL_LOCATION_KEY | str | Registry key to save the installation path | Used to find the installation directory before software installation, default is InstPath, for Electron programs specify as InstallLocation |
--PRODUCT_PATHNAME | str | Key to save software installation identification in the registry | Used for saving software and uninstallation information |
--INSTALL_APPEND_PATH | str | Directory name to append during installation | |
--INSTALL_DEFALT_SETUPPATH | str | Default installation path for the software | |
--TEST_SLEEP | int | Whether to add a delay during the decompression process | Default is 0, indicating no delay; 1 indicates adding a delay |
--INSTALL_DEFAULT_SHOTCUT | int | Whether to enable adding shortcuts by default | Default is 0, indicating not enabled |
--INSTALL_DEFAULT_AUTORUN | int | Whether to enable auto-start by default | Default is 0, indicating not enabled |
--INSTALL_EXECUTION_LEVEL | str | Installation package permissions | none/user/highest/admin, default is admin |
--INSTALL_MODE_ALL_USERS | str | Installation for all users or the current user | all/current, this parameter is related to the previous one, please pay attention |
--INSTALL_DOWNLOAD_BASEURL | str | Base URL for downloading data packages of online installer | Required if creating an online installer |
--PRODUCT_LEGAL | str | Version information | Example: Leeqia Copyright(c) 2020 |
--PRODUCT_PUBLISHER | str | Publisher information | Example: Company Name |
For example, to package a program with the following specified information:
The command line parameters for packaging would be:
python package.py --package_mode=1 --project_name=leeqia_mountain --PRODUCT_NAME=Test Software --PRODUCT_VERSION=0.5.0 --EXE_NAME=Test.exe --INSTALL_OUTPUT_NAME=Test_Setup.exe --src_files_dir=C:\unpacked_files
If there are more parameters to specify, append them accordingly.
After reading this section, you might have noticed that the steps to manually configure the soft_setup.nsi file in the first section can be completely abandoned. You can directly use this command line approach for packaging. Even if the information is relatively fixed, you can save this command line parameter in a batch file.
Note:
To use the python.py command line script, python3 needs to be installed in the packaging environment.
For packaging Electron programs, we support generating latest.yml compatible with electron-updater for automatic updates of Electron programs.
Before packaging Electron programs, we need to consider the following questions and form correct configurations based on the conclusions:
Is the current program being initially released or is it a continuation of a previously built Electron program?
Packaging entry point:
a) If electron-builder is the packaging entry point, you only need to pass accurate information through the command line and specify build_for_electron as False because this mode is the same for nsNiuniuSkin as other packaging methods (this is the recommended approach)
b) If you want the packaging entry point to be our package.py, you need to pass build_for_electron as True and also pass the project path. We will attempt to read information such as version number, software name, GUID, etc., from package.json in the project path, then execute the npm build run command in the project path, and finally package it into a complete installer (if your packaging configuration or method differs from our default integration, you need to modify the implementation of the build_for_electron function in package_util.py).
You also need to consider how to configure the following parameters:
Feature | Configuration Parameter | Suggestion (Try to match the original installation package configuration as much as possible) |
---|---|---|
Install for all users | --INSTALL_MODE_ALL_USERS | Suggested to install for all users, pass 'all,' and also consider the permissions of the old Electron program |
Start with administrator privileges | --INSTALL_EXECUTION_LEVEL | Suggested to start with administrator privileges, pass 'admin,' and also consider the permissions of the old Electron program |
Software installation identifier | --PRODUCT_PATHNAME | Pass the GUID configured in electron-builder |
Registry key for installation path | --INSTALL_LOCATION_KEY | Pass 'InstallLocation' |
Generate latest.yml | --generate_latest_file | Pass 'True' |
Based on the issues encountered by previous clients when packaging Electron programs, areas prone to errors are as follows, hoping it will be helpful:
Issue | Cause | Solution |
---|---|---|
No GUID in package.json, resulting in failure to read | The GUID is the software identifier in the registry, and each installation package needs a unique value. In some projects, the packaging configuration is not entirely in package.json, and in some cases, the guid property is not set. This leads to failure to read it during nsNiuniuSkin packaging and cannot be correctly written to the registry. |
In this case, generally solve as follows: a) If it is set but not in package.json, pass it directly from the command line parameters b) If not specified in electron-builder and you don't know what the original key is In this case, you need to use 7zip to unzip the installation package generated by electron-builder, find this value in its nsi script, and pass it to us via the command line. Of course, this is generally used when an installation package has been released before using nsNiuniuSkin, and you need the new installation package to have consistent configurations with the old one. Otherwise, just pass a value that you think is unique and correct. |
The packaged installation package is larger than the one packaged by electron-builder | This generally indicates a problem with the incorrectly specified package_mode | Specify package_mode as 1 |
The packaged installation package cannot recognize the path previously installed by electron-builder |
a) Inconsistency between current user and all user configurations In electron-builder's configuration, there is usually a configuration for whether to install perMachine, indicating installation for all users. The default configuration in nsNiuniuSkin is for all users. If these two configurations do not match, it will not be read. b) Inconsistency in the key value of the installation location in the registry nsNiuniuSkin defaults to InstPath in the registry for the installation location, while the program packaged by electron-builder uses InstallLocation c) Inconsistency in the software identifier in the registry The registry key of nsNiuniuSkin installation package is inconsistent with that of the program packaged by electron-builder |
Pass the correct values |
After packaging is complete, find that the size and sha512 value in the generated latest.yml do not match the actual installation file | After the packaging process generates the latest.yml, the installation package file is modified again |
In our packaging process, the final step is to generate the latest.yml, meaning that any changes to the installation package after this (such as code signing) will make the information in the latest.yml no longer correct. We recommend configuring the certificate into our packaging process, which can effectively solve this problem and also sign the uninstaller to prevent false positives. Alternatively, if you sign the installation package separately, you need to generate the latest.yml again based on the signed file. |
We have written the complete installation functions into the setup_control.nsh script. Normally, you don't need to modify scripts here. Some key functions in the setup_control.nsh file include:
Function Name | Main Function Description |
---|---|
DUIPage | Installation entry script for initializing information |
un.DUIPage | Uninstallation entry script |
BindUIControls | Bind buttons and other response events |
ShowMsgBox | Display secondary child window |
OnBtnInstall | Installation main process control |
CustomizeInstall | Additional custom installation behaviors |
If there are additional features to be added during the installation process, you can extend them under the CustomizeInstall function in setup_control.nsh, such as installing .NET Framework. This function will run under BGWorker, so you don't have to worry about the installation interface freezing.
Code signing plays a crucial role in software distribution and preventing false positives. In the Sign directory, we have placed basic script information for signing. You only need to replace some key information in signfile.bat and provide certificate and password details. Specify need_sign as True during packaging.
Note:
1) If your signing certificate does not follow our method by default, you need to modify Sign.bat to ensure that it can sign correctly without breaking the parameter reception.
Hopefully, this configuration guide helps you quickly set up a customized packaging script for your project. The key is to understand the order of command-line parameters in package.py and the macro definitions set by NSIS.
In the installation process, a beautiful UI often leaves a more profound impression on customers about the installed product, reflecting the software service provider's focus and dedication to user experience! We hope our efforts can make packaging easier and more enjoyable!
May there be no difficult installation packages in the world!