美化nwjs生成的桌面程序安装包
Posted 蔚蓝
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了美化nwjs生成的桌面程序安装包相关的知识,希望对你有一定的参考价值。
上期讲到用nw.js打包vuecli3创建的项目为桌面程序:传送门:使用nw.js将vue项目打包为可在xp系统运行的桌面程序。打包完成之后却发现打包出来的是一个文件夹,里面有可执行程序exe和一堆环境或资源文件,这么一个文件夹丢给客户安装显然太不优雅。
这期就讲下如何将这一堆东西美化成一个.exe安装包。本文先粗浅研究美化程序在vuecli3项目上的实现,主要参考不爱吃西红柿的文章:用 vue2 和 webpack 快速建构 NW.js 项目(3),并将其修改为在vuecli3项目上的实现。
美化nwjs安装包
上个文章已经完成了vuecli3项目打包成.exe,现在接着处理美化程序。
先安装相关依赖
npm install iconv-lite innosetup-compiler --save-dev
创建config/setup.iss文件
复制即可,后面理解了可以自行修改;另外如果安装包出现乱码,可将setup.iss文件修改后缀为txt然后以ansi格式保存后再改回setup.iss
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
; This CWD is the directory where the `setup.iss`, pay attention to join the relative directory!
; 该执行目录为 `setup.iss` 所在的目录,请注意拼接相对目录
#define MyAppName "_name_"
#define MyAppAliasName "_appName_"
#define MyAppVersion "_version_"
#define MyAppPublisher "_appPublisher_"
#define MyAppURL "_appURL_"
#define MyAppExeName "_name_.exe"
#define OutputPath "_outputPath_"
#define OutputFileName "_outputFileName_"
#define SourceMain "_filesPath_\\_name_.exe"
#define SourceFolder "_filesPath_\\*"
#define LicenseFilePath "_resourcesPath_\\license.txt"
#define SetupIconFilePath "_resourcesPath_\\logo.ico"
#define MyAppId "_appId_"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={#MyAppId}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppAliasName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\\{#MyAppName}
LicenseFile={#LicenseFilePath}
OutputDir={#OutputPath}
OutputBaseFilename={#OutputFileName}
SetupIconFile={#SetupIconFilePath}
Compression=lzma
SolidCompression=yes
PrivilegesRequired=admin
Uninstallable=yes
UninstallDisplayName={#MyAppAliasName}
DefaultGroupName={#MyAppAliasName}
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkedonce
[Files]
Source: {#SourceMain}; DestDir: "{app}"; Flags: ignoreversion
Source: {#SourceFolder}; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
[Messages]
SetupAppTitle={#MyAppAliasName} setup wizard
SetupWindowTitle={#MyAppAliasName} setup wizard
[Icons]
Name: "{commondesktop}\\{#MyAppAliasName}"; Filename: "{app}\\{#MyAppExeName}"; Tasks: desktopicon
Name: "{group}\\{#MyAppAliasName}"; Filename: "{app}\\{#MyAppExeName}"
Name: "{group}\\uninstall {#MyAppAliasName}"; Filename: "{uninstallexe}"
[Run]
Filename: "{app}\\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, \'&\', \'&&\')}}"; Flags: nowait postinstall skipifsilent
新增build/setup.js
var innosetupCompiler = require(\'innosetup-compiler\')
var path = require(\'path\')
var fs = require(\'fs\')
var iconv = require(\'iconv-lite\')
function resolve() {
return path.resolve.apply(path, [__dirname, \'..\'].concat(...arguments))
}
var rootPath = path.resolve(__dirname, \'../\')
// `./package.json`
var tmpJson = require(path.resolve(rootPath, \'./package.json\'))
var curReleasesPath = resolve(\'./releases\');
// 约定性配置
var setupOptions = {
issPath: resolve(\'./config/setup.iss\'),
// only one version path
files: curReleasesPath,
resourcesPath: resolve(\'./build/setup_resources\'),
appPublisher: \'nw-vue-demo, Inc.\',
appURL: \'your url\',
appId: \'{{your id}}\',
// data: { name, version, platform }
};
fs.readdir(setupOptions.files, function (err, files) {
if (err) throw err
files.forEach(function (fileName) {
if (!~fileName.indexOf(\'win\')) return
const curPath = path.resolve(setupOptions.files, fileName)
fs.stat(curPath, function (err, stats) {
if (err || stats.isFile()) return
if (stats.isDirectory()) {
makeExeSetup(Object.assign({}, setupOptions, { files: curPath, platform: fileName }))
}
})
})
})
function makeExeSetup(opt) {
const { issPath, files, resourcesPath, appPublisher, appURL, appId, platform } = opt
const { name, version } = tmpJson
const tmpIssPath = path.resolve(path.parse(issPath).dir, \'_tmp.iss\')
return new Promise(function (resolve, reject) {
// rewrite name, version to iss
fs.readFile(issPath, null, function (err, text) {
if (err) return reject(err)
// 这里是iss文件里的变量配置的地方
let str = iconv.decode(text, \'gbk\')
.replace(/_name_/g, name) // 名字
.replace(/_appName_/g, name) // app名字,这里用name代替
.replace(/_version_/g, version) // 版本
.replace(/_outputPath_/g, \'app\') // 美化程序输出的路径,这里写死config/app,则美化程序打包后将在config/app/下生成
.replace(/_outputFileName_/g, name + version) // 输出的文件名
.replace(/_filesPath_/g, files) // 要打包的文件路径
.replace(/_resourcesPath_/g, resourcesPath) // 资源路径,主要是图标、安装协议等,复制build下的setup_resources目录即可
.replace(/_appPublisher_/g, appPublisher) // 软件出版商,自己写
.replace(/_appURL_/g, appURL) // app线上路径
.replace(/_appId_/g, appId) // appid
fs.writeFile(tmpIssPath, iconv.encode(str, \'gbk\'), null, function (err) {
if (err) return reject(err)
// inno setup start
innosetupCompiler(tmpIssPath, { gui: false, verbose: true }, function (err) {
fs.unlinkSync(tmpIssPath)
if (err) return reject(err)
resolve(opt)
})
})
})
})
}
主要的调整修改就是在setup.js文件
修改完成,先打包nw文件,再打包美化文件
yarn build:nw
yarn setup
项目地址:
Github
以上是关于美化nwjs生成的桌面程序安装包的主要内容,如果未能解决你的问题,请参考以下文章
cxfreeze打包python程序的方法说明(生成安装包,实现桌面快捷方式删除快捷方式)