Fix reading images from network drives on windows when the tmp dir has spaces

Changelog-entry: (Windows): Fix reading images from network drives when the tmp dir has spaces
Change-type: patch
This commit is contained in:
Alexis Svinartchouk 2019-04-16 13:44:25 +02:00
parent 9da9e73f7a
commit 11def54adb

View File

@ -79,36 +79,7 @@ const tmpFileDisposer = () => {
const readFileAsync = promisify(fs.readFile) const readFileAsync = promisify(fs.readFile)
/** const execAsync = promisify(cp.exec)
* @summary Promisified child_process.execFile
* @function
*
* @param {String} file - command
* @param {String[]} args - arguments
* @param {Object} options - child_process.execFile options
*
* @returns {Promise<Object>} - { 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 })
}
}
)
})
}
/** /**
* @summary Returns wmic's output for network drives * @summary Returns wmic's output for network drives
@ -121,27 +92,27 @@ const execFileAsync = async (file, args, options) => {
*/ */
exports.getWmicNetworkDrivesOutput = async () => { exports.getWmicNetworkDrivesOutput = async () => {
// Exported for tests. // Exported for tests.
// Windows's wmic outputs ucs2 encoded data. // When trying to read wmic's stdout directly from node, it is encoded with the current
// When trying to read its stdout from node's execFile, it is always transformed (even if you pass { encoding: 'buffer' }) // console codepage (depending on the computer).
// Information is lost and accented characters become unreadable (with no way to guess what they were). // Decoding this would require getting this codepage somehow and using iconv as node
// Because of this, we use the wmic's "/output:" switch that redirects the output to a file. // doesn't know how to read cp850 directly for example.
// For some reason wmic doesn't like dashes in filenames, that's why we change the tmp file prefix in tmpFileAsync above. // 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 }) => { return Bluebird.using(tmpFileDisposer(), async ({ path }) => {
await execFileAsync( const command = [
Path.join(process.env.SystemRoot, 'System32', 'Wbem', 'wmic'), Path.join(process.env.SystemRoot, 'System32', 'Wbem', 'wmic'),
[ 'path',
`/output:${path}`, 'Win32_LogicalDisk',
'path', 'Where',
'Win32_LogicalDisk', 'DriveType="4"',
'Where', 'get',
'DriveType="4"', 'DeviceID,ProviderName',
'get', '>',
'DeviceID,ProviderName' `"${path}"`
], ]
{ windowsHide: true, windowsVerbatimArguments: true } await execAsync(command.join(' '), { windowsHide: true })
) return readFileAsync(path, 'ucs2')
const data = await readFileAsync(path, 'ucs2')
return data
}) })
} }