diff --git a/public/electron.js b/public/electron.js index 8eb484c..dd4ab76 100644 --- a/public/electron.js +++ b/public/electron.js @@ -88,9 +88,9 @@ const unmountAllDrives = () => { mountedData = {}; }; -function createWindow() { +function createWindow() { loadUiSettings(); - + let extra = {}; if (os.platform() === 'linux') { extra = { @@ -726,20 +726,45 @@ ipcMain.on(Constants.IPC_Install_Dependency, (event, data) => { }, error); }); } else { - helpers - .executeAndWait(data.Source) - .then(() => { - standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { - Source: data.Source, - URL: data.URL, + const execInstall = () => { + helpers + .executeAndWait(data.Source) + .then(() => { + standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { + Source: data.Source, + URL: data.URL, + }); + }) + .catch(error => { + standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { + Source: data.Source, + URL: data.URL, + }, error); }); - }) - .catch(error => { - standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { - Source: data.Source, - URL: data.URL, - }, error); - }); + }; + if (data.IsWinFSP) { + helpers + .performWindowsUninstall(["WinFsp 2019.3 B1", "WinFsp 2019.3 B2"]) + .then(uninstalled => { + if (uninstalled) { + standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { + RebootRequired: true, + Source: data.Source, + URL: data.URL, + }); + } else { + execInstall(); + } + }) + .catch(error => { + standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { + Source: data.Source, + URL: data.URL, + }, error); + }); + } else { + execInstall(); + } } }); diff --git a/src/helpers.js b/src/helpers.js index 3fbd787..d904fb3 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -12,6 +12,55 @@ const _getDataDirectory = () => { return _resolvePath(Constants.DATA_LOCATIONS[os.platform()]); }; +const _executeProcess = (command, args=[]) => { + return new Promise((resolve, reject) => { + const processOptions = { + detached: true, + shell: false, + }; + + const process = new spawn(command, args, processOptions); + const pid = process.pid; + + process.on('error', (err) => { + reject(err, pid); + }); + + process.on('exit', (code) => { + resolve(code); + }); + + process.unref(); + }); +}; + +const _execProcessGetOutput = (cmd, args) => { + return new Promise((resolve, reject) => { + const proc = spawn(cmd, args, { + env: process.env, + stdio: ['ignore', 'pipe', 'pipe'] + }); + + let output; + proc.stdout.on('data', data => { + output += data.toString(); + }); + + proc.on('error', (err) => { + reject(err); + }); + + proc.on('exit', () => { + const lines = output + .replace(/\r\n/g, '\n') + .split('\n'); + resolve(lines); + }); + + proc.unref(); + }); +}; + const _resolvePath = str => { if (os.platform() === 'win32') { return str.replace(/%([^%]+)%/g, (_, n) => { @@ -484,6 +533,65 @@ module.exports.mkDirByPathSync = (targetDir, { isRelativeToScript = false } = {} }, initDir); }; +module.exports.performWindowsUninstall = names => { + return new Promise((resolve, reject) => { + if (os.platform() !== 'win32') { + reject('Windows OS is not being used'); + } else { + const cmd = path.join(process.env.windir, 'system32', 'reg.exe'); + const args = ["QUERY", "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"]; + _execProcessGetOutput(cmd, args) + .then(lines => { + const parseLine = index => { + if (index < lines.length) { + const line = lines[index]; + if (line.startsWith('HKEY_LOCAL_MACHINE\\')) { + let args2 = JSON.parse(JSON.stringify(args)); + args2[1] = 'HKLM\\' + line.substr(19); + args2.push('/v'); + args2.push('DisplayName'); + args2.push('/t'); + args2.push('REG_SZ'); + _execProcessGetOutput(cmd, args2) + .then(lines => { + const value = lines[2].trim().substr(args2[3].length).trim().substr(6).trim(); + if (names.includes(value)) { + const items = line.split('\\'); + const productCode = items[items.length - 1]; + _executeProcess('msiexec.exe', ['/x', productCode, '/norestart']) + .then(code => { + if ((code === 0) || (code === 3010) || (code === 1641)) { + resolve(true); + } else { + reject('[' + value + '] uninstall failed: ' + code); + } + }) + .catch(err => { + reject(err); + }); + } else { + parseLine(++index); + } + }) + .catch(err=> { + parseLine(++index); + }); + } else { + parseLine(++index); + } + } else { + resolve(false); + } + }; + parseLine(0); + }) + .catch( err => { + reject(err); + }); + } + }); +}; + module.exports.removeDirectoryRecursively = (p) => { if (fs.existsSync(p)) { fs