3.4 辅助工具app-builder
在上一节介绍的代码中,getBinFromUrl方法拼接好下载的url,并把这个url传递给了getBin方法。getBin方法把这个url转换成命令行参数,传递给了一个应用程序app-builder.exe,由它负责下载对应的文件,代码逻辑如下:
export function download(url: string, output: string, checksum?: string | null): Promise<void> { const args = ["download", "--url", url, "--output", output] if (checksum != null) { args.push("--sha512", checksum) } return executeAppBuilder(args) as Promise<any> // 此方法最终调用了app-builder.exe }
executeAppBuilder方法使用Node.js子进程控制的API启动了app-builder.exe,并把命令行参数传递给了app-builder.exe。后面会介绍Node.js子进程控制的使用方式。
这里不单是Electron的二进制包,包括签名工具、资源修改工具、打包工具,都是由app-builder.exe负责下载并缓存的。大部分这些工具的使用也是由它来完成调用的,可以说它就是electron-builder的辅助工具之母。
app-builder(https://github.com/develar/app-builder)是由electron-builder的主要作者develar使用Go语言开发的,在这个工具中也使用了ELECTRON_BUILDER_CACHE环境变量来缓存文件,如下是它获取缓存目录的逻辑:
func GetCacheDirectory(appName string, envName string, isAvoidSystemOnWindowsbool) (string, error) { env := os.Getenv(envName) if len(env) != 0 { return env, nil } currentOs := util.GetCurrentOs() if currentOs == util.MAC { userHomeDir, err := homedir.Dir() if err != nil { return "", errors.WithStack(err) } return filepath.Join(userHomeDir, "Library", "Caches", appName), nil } if currentOs == util.WINDOWS { localAppData := os.Getenv("LOCALAPPDATA") if len(localAppData) != 0 { if isAvoidSystemOnWindows && strings.Contains(strings.ToLower(localAppData), "\\ windows\\ system32\\ ") || strings.ToLower(os.Getenv("USERNAME")) == "system" { return filepath.Join(os.TempDir(), appName+"-cache"), nil } return filepath.Join(localAppData, appName, "Cache"), nil } } xdgCache := os.Getenv("XDG_CACHE_HOME") if xdgCache != "" { return filepath.Join(xdgCache, appName), nil } userHomeDir, err := homedir.Dir() if err != nil { return "", errors.WithStack(err) } return filepath.Join(userHomeDir, ".cache", appName), nil }
如果下载的是签名工具或打包工具,那么这个envName的值就是ELECTRON_BUILDER_CACHE。也就是说,如果设置了ELECTRON_BUILDER_CACHE环境变量,则使用这个环境变量的值;如果没有设置,则计算一个默认值。一般情况下这个计算出来的值所指向的路径为:
C:\Users\yourUserName\AppData\Local\electron-builder\Cache
如果下载的是Electron的二进制包,那么这个envName的值就是electron_config_cache环境变量对应的值。如果开发者没有配置这个环境变量,它的默认值应为:
C:\Users\[yourUserName]\AppData\Local\electron\Cache
下载的过程并无太多出奇的地方,且与普通开发者关系不大,值得一提的是,作者非常细心,不但提供了下载失败后的重连能力、代理能力、下载过程和记录日志,甚至会验证下载文件的哈希值是否合法。
启动外部工具也与Node.js的子进程控制方式非常相似:准备目标程序路径,生成命令行指令,对接标准输入、输出流等;由于是Go语言完成的逻辑,这里不再多做介绍。