#30: Add uninstall feature with reboot to handle WinFSP upgrades/downgrades
This commit is contained in:
108
src/helpers.js
108
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
|
||||
|
||||
Reference in New Issue
Block a user