From 056c88f741acad167af812407525733b379c5ccc Mon Sep 17 00:00:00 2001 From: Albin Ekblom Date: Fri, 9 Jun 2017 20:29:15 +0200 Subject: [PATCH] Check default app (#1918) * Check .js default app * Cleanup fallback check * Check all keys * Check for empty strings --- app/config/open.js | 76 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/app/config/open.js b/app/config/open.js index 9d7d0aa9..c344390d 100644 --- a/app/config/open.js +++ b/app/config/open.js @@ -4,7 +4,56 @@ const {cfgPath} = require('./paths'); module.exports = () => Promise.resolve(shell.openItem(cfgPath)); if (process.platform === 'win32') { - const exec = require('child_process').exec; + const Registry = require('winreg'); + const {exec} = require('child_process'); + + // Windows opens .js files with WScript.exe by default + // If the user hasn't set up an editor for .js files, we fallback to notepad. + const getFileExtKeys = () => new Promise((resolve, reject) => { + Registry({ + hive: Registry.HKCU, + key: '\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.js' + }) + .keys((error, keys) => { + if (error) { + reject(error); + } else { + resolve(keys || []); + } + }); + }); + + const hasDefaultSet = async () => { + const keys = await getFileExtKeys(); + + const valueGroups = await Promise.all(keys.map(key => new Promise((resolve, reject) => { + key.values((error, items) => { + if (error) { + reject(error); + } + resolve(items.map(item => item.value || '') || []); + }); + }))); + + const values = valueGroups + .reduce((allValues, groupValues) => ([...allValues, ...groupValues]), []) + .filter(value => value && typeof value === 'string'); + + // No default app set + if (values.length === 0) { + return false; + } + + // WScript is in default apps list + if (values.some(value => value.includes('WScript.exe'))) { + const userDefaults = values.filter(value => value.endsWith('.exe') && !value.includes('WScript.exe')); + + // WScript.exe is overidden + return (userDefaults.length > 0); + } + + return true; + }; // This mimics shell.openItem, true if it worked, false if not. const openNotepad = file => new Promise(resolve => { @@ -13,21 +62,16 @@ if (process.platform === 'win32') { }); }); - // Windows opens .js files with WScript.exe by default - // If the user hasn't set up an editor for .js files, we fallback to notepad. - const canOpenNative = () => new Promise((resolve, reject) => { - exec('ftype JSFile', (error, stdout) => { - if (error) { - reject(error); - } else if (stdout && stdout.includes('WScript.exe')) { - reject(new Error('WScript is the default editor for .js files')); - } else { - resolve(true); + module.exports = () => hasDefaultSet() + .then(yes => { + if (yes) { + return shell.openItem(cfgPath); } + console.warn('No default app set for .js files, using notepad.exe fallback'); + return openNotepad(cfgPath); + }) + .catch(err => { + console.error('Open config with default app error:', err); + return openNotepad(cfgPath); }); - }); - - module.exports = () => canOpenNative() - .then(() => shell.openItem(cfgPath)) - .catch(() => openNotepad(cfgPath)); }