diff --git a/lib/gui/app/os/windows-network-drives.js b/lib/gui/app/os/windows-network-drives.js index 09678b24..c4a7e025 100644 --- a/lib/gui/app/os/windows-network-drives.js +++ b/lib/gui/app/os/windows-network-drives.js @@ -79,36 +79,7 @@ const tmpFileDisposer = () => { const readFileAsync = promisify(fs.readFile) -/** - * @summary Promisified child_process.execFile - * @function - * - * @param {String} file - command - * @param {String[]} args - arguments - * @param {Object} options - child_process.execFile options - * - * @returns {Promise} - { stdout, stderr } - * - * @example - * execFileAsync('ls', [ '.' ]) - * .then(console.log); - */ -const execFileAsync = async (file, args, options) => { - return new Promise((resolve, reject) => { - cp.execFile( - file, - args, - options, - (error, stdout, stderr) => { - if (error) { - reject(error) - } else { - resolve({ stdout, stderr }) - } - } - ) - }) -} +const execAsync = promisify(cp.exec) /** * @summary Returns wmic's output for network drives @@ -121,27 +92,27 @@ const execFileAsync = async (file, args, options) => { */ exports.getWmicNetworkDrivesOutput = async () => { // Exported for tests. - // Windows's wmic outputs ucs2 encoded data. - // When trying to read its stdout from node's execFile, it is always transformed (even if you pass { encoding: 'buffer' }) - // Information is lost and accented characters become unreadable (with no way to guess what they were). - // Because of this, we use the wmic's "/output:" switch that redirects the output to a file. - // For some reason wmic doesn't like dashes in filenames, that's why we change the tmp file prefix in tmpFileAsync above. + // When trying to read wmic's stdout directly from node, it is encoded with the current + // console codepage (depending on the computer). + // Decoding this would require getting this codepage somehow and using iconv as node + // doesn't know how to read cp850 directly for example. + // We could also use wmic's "/output:" switch but it doesn't work when the filename + // contains a space and the os temp dir may contain spaces ("D:\Windows Temp Files" for example). + // So we just redirect to a file and read it afterwards as we know it will be ucs2 encoded. return Bluebird.using(tmpFileDisposer(), async ({ path }) => { - await execFileAsync( + const command = [ Path.join(process.env.SystemRoot, 'System32', 'Wbem', 'wmic'), - [ - `/output:${path}`, - 'path', - 'Win32_LogicalDisk', - 'Where', - 'DriveType="4"', - 'get', - 'DeviceID,ProviderName' - ], - { windowsHide: true, windowsVerbatimArguments: true } - ) - const data = await readFileAsync(path, 'ucs2') - return data + 'path', + 'Win32_LogicalDisk', + 'Where', + 'DriveType="4"', + 'get', + 'DeviceID,ProviderName', + '>', + `"${path}"` + ] + await execAsync(command.join(' '), { windowsHide: true }) + return readFileAsync(path, 'ucs2') }) }