深入浅出Electron:原理、工程与实践
上QQ阅读APP看书,第一时间看更新

3.7 修改可执行程序

对于Windows应用程序来说,每个可执行程序都有其相应的资源,比如图标、字符串、字体文件等。这些资源往往是内嵌到可执行程序中的,很多开发工具(比如Visual Studio、QtCreator等)都提供了这方面的能力,如图3-3所示。

073-1

图3-3 VisualStudio应用资源管理器

electron.exe可执行程序内部也有很多这样的资源,图3-4是使用Resource-Hacker(http://www.angusj.com/resourceha-cker/)看到的electron.exe内的资源情况。

074-1

图3-4 ResourceHacker资源修改器

那么electron-builder是如何修改这些资源的呢?

Windows SDK提供了一系列的API用于操作exe文件内置的资源,比如Find-Resource(用于查找资源所在的位置)、BeginUpdateResource(准备开始更新资源)、UpdateResource(开始更新资源)、EndUpdate-Resource(结束更新资源)等。

只要愿意,我们完全可以自己写程序来修改electron.exe可执行文件的图标、厂商和版权信息等资源。但这脱离了本书的主题,我们主要介绍electron-builder是如何修改可执行程序的资源的。

electron-builder也并没有自己完成这项工作,而是借助了winCodeSign工具内置的rcedit工具来完成这项工作。如果你成功地安装过electron-builder,并且使用electron-builder打包过应用,那么这个工具应该在你的电脑的这个目录下面:

C:\Users\[yourUserName]\AppData\Local\electron-builder\Cache\winCodeSign\  winCodeSign-2.6.0\rcedit-x64.exe

可以在命令行下启动这个工具,并为其传递参数,以使其完成修改目标程序资源的工作。如下代码是electron-builder在调用rcedit时传递参数的示例代码:

async editResource() {
  let args = [
    path.join(process.cwd(), 'release/win-ia32-unpacked/yourApp.exe'),
    '--set-version-string',
    'FileDescription',
    'yourApp',                        // 从调用electron-builder时提供的配置信息中得到
    '--set-version-string',           
    'ProductName',                    
    'yourApp',                        // 从调用electron-builder时提供的配置信息中得到
    '--set-version-string',
    'LegalCopyright',
    'Copyright © 2021 yourCompany',   // 从调用electron-builder时提供的配置信息中得到
    '--set-file-version',
    '1.3.6',                          // 从调用electron-builder时提供的配置信息中得到
    '--set-product-version',
    '1.3.6.0',                        // 从调用electron-builder时提供的配置信息中得到
    '--set-version-string',
    'InternalName',
    'yourApp',                        // 从调用electron-builder时提供的配置信息中得到
    '--set-version-string',
    'CompanyName',
    'yourCompany',                    // 从调用electron-builder时提供的配置信息中得到
    '--set-icon',
    path.join(process.cwd(), 'resource/unrelease/icon.ico'),
  ]
  let env = {
    ...process.env,
  }
  spawn(
    builderToolPath,
    ['rcedit', '--args', JSON.stringify(args)],
    {
      env,
      stdio: ['ignore', 'pipe', process.stdout],
    }
  )
}

上述代码并没有直接调用rcedit工具,而是通过前面介绍的app-builder工具间接调用rcedit,builderToolPath指向的就是app-builder可执行文件的路径。

代码中涉及的资源信息,比如应用名称、版本号等,都是从electron-builder的配置信息中提取的。

读者可能注意到rcedit工具是应用签名工具winCodeSign内置的子工具,由此可见给应用签名也是通过修改可执行文件的资源实现的。如果开发者为electron-builder配置了用于签名的证书,则签名工具就会把证书以资源的形式添加到可执行程序文件内部。

微软为开发者推荐了几个可以采购签名证书的商业机构,详见https://docs.microsoft.com/zh-cn/windows-hardware/drivers/dashboard/get-a-code-signing-certificate。准备好证书后,可以通过提供如下配置项来使electron-builder为应用程序签名:

{
  win:{
      signingHashAlgorithms:'sha256',                  // 不推荐再使用sha1签名
      certificateFile:'d:/codeSign/yourSign.pfx',      // 你的证书的路径
      certificatePassword:'******',                    // 你的证书的密码
    }
    ...
  }
  ...
}

在electron-builder生成应用安装包期间,会启动winCodeSign子进程来完成应用签名的工作。

以上所有工作执行完成后,electron.exe文件的图标、厂商、版权等信息都修改成了你配置的信息,这时只要给electron.exe改一下文件名,它看上去就是你开发的应用程序了。虽然这个程序并没有一行代码是你写的,它是Electron团队、Chroium团队和Node.js团队一起完成的,但这一点也不妨碍你把它当做自己开发的商业应用来分发给你的用户。