接到一个需求是要让客户使用桌面程序来登录并操作,而我们的服务是 B/S 架构,前端与后台应用都是独立的微服务,也不太可能临时去开发原生的桌面程序,那么就要考虑通过对页面打包的形式来获得桌面程序。
可以选择的框架主要有 nw.js 和 Electron,考虑实际情况并不需要从零开发移植,只需要一个 index 页面指向系统的登录页即可,最终选择了使用 nw.js 。
软件准备
- 
使用 nw.js 进行页面打包。 
- 
资源编辑器,用于修改打包获得的 .exe的图标。
- 
虚拟化工具,用于将通过 nw.js 打包获得的 .exe与所需依赖打包为一个.exe。
nw.js 打包
配置说明
新建 index.html、package.json 以及 assets 文件夹。
index.html
用于控制打开应用后跳转的页面,简单通过 window.location.href 实现即可。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <script>
        window.location.href = "https://blog.homurax.com/";
    </script>
  </body>
</html>
assets
习惯上在 assets 目录下放置静态文件,比如可以将 logo 图片放在这里。
package.json
应用相关的配置。
{
    "name": "blog_homurax",
    "main": "index.html",
    "window": {
        "title": "Homurax's Blog",
        "icon": "assets/favicon.png",
        "position": "center",
        "width": 1920,
        "height": 1080,
        "min_width": 1366,
        "min_height": 768,
        "max_width": 1920,
        "max_height": 1080
    }
}
配置说明参见:
三组宽高可以都不配置,则打开后的窗口没有大小限制,可以任意拖拽。
如果配置了最大宽高,存在一个操作 bug。打开应用,随意拖拽应用后,点击右上角最大化按钮,窗口会正常变化;此后无论如何拖拽,最大化按钮均不可点击。建议不要填写最大宽高配置项。
打包
首先选中 assets、index.html、package.json 打为 zip 包,注意不要对这三个文件所在的目录打包。
以 app.zip 为例,修改文件后缀为 nw,将 app.nw 拷贝至 nwjs 目录下。
运行 cmd,进入到 nwjs 目录下,执行 copy 命令。注意必须用 cmd 执行,不可使用 PowerShell 或是 Terminal 去执行。
copy /b nw.exe+app.nw app.exe
此时运行 app.exe,就可以展示出 index.html 中配置的跳转地址了。
删除 app.nw 。
修改图标
app.exe 使用的是默认图标,这一步就是要修改这个图标。如果不需要修改,可以跳过。
运行 Resource Hacker,在其中打开 app.exe,在要替换的图标上右键,选择替换图标。
选择替换图标后,操作界面中可以看到生成了选择图标的各种尺寸大小,点击保存。
保存后 nwjs 目录下会多出一个 app_original.exe,这个是 Resource Hacker 在修改前进行的备份,可以直接删掉,真正修改了图标的依旧是 app.exe 。
清除缓存
此时可能看到的 app.exe 图标没有发生变化,原因是操作系统存在对图标的缓存,可以执行脚本清除缓存。
rem 关闭 explorer
taskkill /f /im explorer.exe
rem 清理系统图标缓存数据库
attrib -h -s -r "%userprofile%\AppData\Local\IconCache.db"
del /f "%userprofile%\AppData\Local\IconCache.db"
attrib /s /d -h -s -r "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\*"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_32.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_96.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_102.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_1024.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_idx.db"
del /f "%userprofile%\AppData\Local\Microsoft\Windows\Explorer\thumbcache_sr.db"
rem 清理 系统托盘记忆的图标
echo y|reg delete "HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v IconStreams
echo y|reg delete "HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v PastIconsStream
rem 重启 explorer
start explorer
依赖打包
此时 app.exe 只可以在 nwjs 目录下启动,移动至其他目录则会启动失败,所以需要将 app.exe 和相关依赖整体打包。
运行 Enigma Virtual Box,input 中选中 app.exe;output 会自动设置为在同级目录下生成打包后的 app_boxed.exe 。
点击 Add - Add File(s),ctrl + a 全选  nwjs 目录下全部文件,再排除所有的 .exe 文件,点击确认。
确认后出现的 Select Folder 直接点 OK,即使用 Add Folder %DEFAULT FOLDER% 项。
点击 New Folder,新建 locales 文件夹,然后在 locales 上右键,选择 Add File(s) 。
添加全部的 .\nwjs\locales 目录下的文件,点击确认。
点击 Files Options ,勾选 Compress Files 。
最后点击 Process 开始打包。
在 nwjs 目录下可以得到 app_boxed.exe,此文件可以用以拷贝和分发。
另一种打包选择:使用 Inno Setup 打包
这里推荐另一个打包方式,就是用 Inno Setup 来打包成安装程序,即将你的一开始的 web 应用源文件和 node-webkit 的 nw.exe 和一些 dll 直接压缩成一个安装文件,我们并不需要上述中间那先打包成 app.exe 的步骤。用户在使用你的 exe 后会出现 setup wizard 把程序安装到 Program Files 目录中,其实等于解压缩了,将 nw.exe 和dll 还有你的 web 应用释放出来,这个时候所生成的安装文件其实 size 会小很多。