基于Electron开发的客户端最终分发时需要打包。
最简单的方式就是大家喜闻乐见的Portable的压缩包形式。
当有某些特殊需求时,就需要制作安装包了。
Windows
在Windows下有很多免费、商用的安装包制作工具。功能异常强大。
其中比较著名的免费安装包制作工具就是Inno Setup
Inno Setup是使用Delphi开发的,使用RemObjects为安装程序增加基于Pascal的脚本支持。
当我们的应用需要某些权限时,需要弹出UAC对话框请求授权。
此时需要安装程序将应用对应的EXE文件增加到注册表对应项中。使用Inno Setup可以在注册表段增加需要设置的内容,并可以引用安装程序路径等变量:
RunAs Admin
为了让我们的应用启动时就请求管理员权限,可以写入如下内容到注册表:
[Registry]
Root: "HKCU";
Subkey: "SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\";
ValueType: String;
ValueName: "{app}\{#MyAppExeName}";
ValueData: "RUNASADMIN";
Flags: uninsdeletekeyifempty uninsdeletevalue;
MinVersion: 0,6.1
要注意的是,写入的是HKCU,不是HKLM。打开注册表找到上面的项,你会发现里面已经有一些程序RunAs Admin
了。
CreateProcess Failed
另一个问题:在安装完毕后可以选择立即运行应用程序,此时会出现CreateProcess
失败。
此时需要在Run段Flags里增加一个runascurrentuser参数:
[Run]
Filename: "{app}\{#MyAppExeName}";
Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}";
Flags: runascurrentuser nowait postinstall skipifsilent
隐藏安装中的文件路径
前面提到过,Inno Setup使用RemObject
为安装程序增加了脚本能力。
在code端可以增加特定事件的处理函数。
在[code]段增加下面代码
procedure InitializeWizard;
begin
with TNewStaticText.Create(WizardForm) do
begin
Parent := WizardForm.FilenameLabel.Parent;
Left := WizardForm.FilenameLabel.Left;
Top := WizardForm.FilenameLabel.Top;
Width := WizardForm.FilenameLabel.Width;
Height := WizardForm.FilenameLabel.Height;
Caption := "";
end;
WizardForm.FilenameLabel.Visible := False;
end;
上面的InitializeWizard
是一个回调函数,在安装向导初始化时被调用。上面代码创建了另一个TNewStaticText实例然后覆盖在原有的FilenameLabel上,以达到不显示安装过程时拷贝文件的路径的效果。
2016-08-07更新:
node-innosetup-compiler InnoSetup命令行工具ISCC的Node Wrapper
Mac
Mac下最简单的方式是使用Disk Utility(hdiutil)创建空白dmg文件,然后将要打包的app文件夹和Application文件夹的软连接放到dmg文件中。这个过程中比较tricky的部分是
- 要实现计算好dmg文件的容量,使其恰好可以容纳app和背景图片
- 如何设置dmg mount后的背景图
好在已经有很多工具可以帮我们完整这个繁琐的过程:
以下几个语言都有对应的DMG生成工具,可以方便的集成到系统中:
- Shell: A shell script to build fancy DMGs
- Ruby:Ruby Library to build DMG files
- Python:dmgbuild
- NodeJS:Generate your app dmgs
使用node-appdmg生成dmg
安装:
> npm i --save-dev appdmg
package.json中增加:
{
"scripts": {
"build": "appdmg appdmg.json APPNAME.dmg"
}
}
编辑appdmg.json:
{
"title": "App Name",
"icon": "./.VolumeIcon.icns", //dmg加载后弹窗的图标
"background": "./.background.tiff", //dmg加载后弹出窗口的背景图片
"contents": [{
"x": 448,
"y": 140,
"type": "link", //应用目录的软链
"path": "/Applications"
}, {
"x": 192,
"y": 140,
"type": "file",
"path": "./AppName.app" //你的应用目录
}]
}
运行命令生成dmg文件:
> npm run build
> appdmg appdmg.json APPNAME.dmg
[ 1/20] Looking for target... [ OK ]
[ 2/20] Reading JSON Specification... [ OK ]
[ 3/20] Parsing JSON Specification... [ OK ]
[ 4/20] Validating JSON Specification... [ OK ]
[ 5/20] Looking for files... [ OK ]
[ 6/20] Calculating size of image... [ OK ]
[ 7/20] Creating temporary image... [ OK ]
[ 8/20] Mounting temporary image... [ OK ]
[ 9/20] Making hidden background folder... [ OK ]
[10/20] Copying background... [ OK ]
[11/20] Reading background dimensions... [ OK ]
[12/20] Copying icon... [ OK ]
[13/20] Setting icon... [ OK ]
[14/20] Creating links... [ OK ]
[15/20] Copying files... [ OK ]
[16/20] Making all the visuals... [ OK ]
[17/20] Blessing image... [ OK ]
[18/20] Unmounting temporary image... [ OK ]
[19/20] Finalizing image... [ OK ]
[20/20] Removing temporary image... [ OK ]
Your image is ready:
APPNAME.dmg
在dmg中可以在背景,在背景中写上客服电话。还可以在dmg里放上webloc文件,方便访问官网和帮助页面。
Flash缓存文件路径
Windows:
通过setPath设置userData路径。各种缓存都保存在这里
app.setPath("userData", path + "/user_data");
所以打包的时候要记得删除缓存!
Mac下Flash的SharedObject保存在:
~/Library/Preferences/Macromedia/Flash Player/#SharedObjects/
另外,sol文件编辑工具:minerva