-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathfind-update-clients.js
95 lines (77 loc) · 2.57 KB
/
find-update-clients.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
'use strict'
const extractPath = require('../extract-path')
const env = require('windows-env')
const fs = require('fs')
const { basename, resolve, dirname } = require('path')
const registry = require('../registry')
const GUIDS = [
'8A69D345-D564-463C-AFF1-A69D9E530F96', // 32
'4DC8B4CA-1BDA-483E-B5FA-D3C12E15B62D', // 64
'4EA16AC7-FD5A-47C3-875B-DBF4A2008C20' // canary
]
const CHANNELS = [
'canary',
'beta',
'dev'
]
module.exports = function findUpdateClients () {
const next = this.plan(GUIDS.length * (env.X64 ? 4 : 2))
GUIDS.forEach(guid => {
queryState(this, 'HKCU', guid, false, next)
queryState(this, 'HKLM', guid, false, next)
if (env.X64) {
queryState(this, 'HKCU', guid, true, next)
queryState(this, 'HKLM', guid, true, next)
}
})
}
function queryState (self, hive, guid, inWoW, done) {
const software = inWoW ? 'Software\\Wow6432Node' : 'Software'
const key = `${software}\\Google\\Update\\ClientState\\{${guid}}`
registry.values(hive, key, function (err, client) {
if (err) {
done(err.notFound ? null : err)
} else if (client.ap) {
let path
const ap = new Set(client.ap.split('-'))
const metadata = {
channel: getReleaseChannel(ap),
bitness: ap.has('x64') ? 64 : 32,
guid
}
// Not always available
if (client.LastInstallerSuccessLaunchCmdLine) {
path = extractPath(client.LastInstallerSuccessLaunchCmdLine)
}
if (client.UninstallString) {
const args = client.UninstallArguments
metadata.uninstall = {
path: client.UninstallString,
arguments: args ? args.split(' ').filter(Boolean) : []
}
if (!path) {
// Possibly Google\Chrome\Application\<version>\Installer\setup.exe
// with chrome.exe at Google\Chrome\Application\chrome.exe
const installer = extractPath(client.UninstallString)
if (installer && basename(dirname(installer)) === 'Installer' && basename(installer) === 'setup.exe') {
const path = resolve(installer, '..', '..', '..', 'chrome.exe')
return fs.access(path, fs.constants.F_OK, (err) => {
if (err) done()
else self.found(path, metadata, key + '\\UninstallString', done)
})
}
}
}
if (path) self.found(path, metadata, key + '\\LastInstallerSuccessLaunchCmdLine', done)
else done()
} else {
done()
}
})
}
function getReleaseChannel (ap) {
for (const channel of CHANNELS) {
if (ap.has(channel)) return channel
}
return 'stable'
}