06月24, 2016

打包Electron应用

基于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的部分是

  1. 要实现计算好dmg文件的容量,使其恰好可以容纳app和背景图片
  2. 如何设置dmg mount后的背景图

好在已经有很多工具可以帮我们完整这个繁琐的过程: 以下几个语言都有对应的DMG生成工具,可以方便的集成到系统中:

使用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

其他Electron相关文章和链接

本文链接:http://aztack.wang/post/packe-electron-apps.html

-- EOF--

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。