Skip to content

Commit

Permalink
feat: read from windows registry
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmaddock committed Feb 5, 2025
1 parent 77a27fe commit 3f258ce
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { promises as fs } from 'node:fs'
import * as path from 'node:path'
import { app } from 'electron'
import { ExtensionSender } from '../../router'
import { readRegistryKey } from './winreg'

const d = require('debug')('electron-chrome-extensions:nativeMessaging')

Expand All @@ -17,21 +18,41 @@ interface NativeConfig {
async function readNativeMessagingHostConfig(
application: string,
): Promise<NativeConfig | undefined> {
let searchPaths = [path.join(app.getPath('userData'), 'NativeMessagingHosts')]
let searchPaths: string[]
switch (process.platform) {
case 'darwin':
searchPaths.push('/Library/Google/Chrome/NativeMessagingHosts')
searchPaths = [
path.join(app.getPath('userData'), 'NativeMessagingHosts', `${application}.json`),
path.join('/Library/Google/Chrome/NativeMessagingHosts', `${application}.json`),
]
break
case 'linux':
searchPaths = [
path.join(app.getPath('userData'), 'NativeMessagingHosts', `${application}.json`),
path.join('/etc/opt/chrome/native-messaging-hosts/', `${application}.json`),
]
break
case 'win32': {
searchPaths = (
await Promise.allSettled([
readRegistryKey('HKLM', '\\Software\\Google\\Chrome\\NativeMessagingHosts', application),
readRegistryKey('HKCU', '\\Software\\Google\\Chrome\\NativeMessagingHosts', application),
])
)
.map((result) => (result.status === 'fulfilled' ? result.value : undefined))
.filter(Boolean) as string[]
break
}
default:
throw new Error('Unsupported platform')
}

for (const basePath of searchPaths) {
const filePath = path.join(basePath, `${application}.json`)
for (const filePath of searchPaths) {
try {
const data = await fs.readFile(filePath)
return JSON.parse(data.toString())
} catch {
} catch (error) {
d('readNativeMessagingHostConfig: unable to read %s', filePath, error)
continue
}
}
Expand Down
40 changes: 40 additions & 0 deletions packages/electron-chrome-extensions/src/browser/api/lib/winreg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { spawn } from 'child_process'

export function readRegistryKey(hive: string, path: string, key?: string) {
if (process.platform !== 'win32') {
return Promise.reject('Unsupported platform')
}

return new Promise<string | null>((resolve, reject) => {
const child = spawn('reg', ['query', `${hive}\\${path}`, ...(key ? ['/v', key] : [])])

let output = ''
let error = ''

child.stdout.on('data', (data) => {
output += data.toString()
})

child.stderr.on('data', (data) => {
error += data.toString()
})

child.on('close', (code) => {
if (code !== 0 || error) {
return reject(new Error(`Failed to read registry: ${error}`))
}

const lines = output.trim().split('\n')
const resultLine = lines.find((line) =>
key ? line.includes(key) : line.includes('(Default)'),
)

if (resultLine) {
const parts = resultLine.trim().split(/\s{2,}/)
resolve(parts.pop() || null)
} else {
resolve(null)
}
})
})
}

0 comments on commit 3f258ce

Please sign in to comment.