I need to complete the following task (with only two tools: Node.js and the 7-Zip CLI):
.zip, unpack it with the 7-Zip CLI in the corresponding file's directory (I am interested in using the “spawn()” method to spawn a new process);'close' event is emitted, log the corresponding exit code.I used the following code:
import { readdir } from 'node:fs/promises';
import { join, extname } from 'node:path';
import { spawn } from 'node:child_process';
const pathToDir = 'D:\\test\\mydirectory';
try {
const entries = await readdir(pathToDir, { recursive: true, withFileTypes: true });
for (const entry of entries) {
const extension = extname(entry.name);
if (extension === '.zip') {
const extract = spawn( 'C:\\software\\7z2501-extra\\x64\\7za.exe', [ 'x', join(entry.parentPath, entry.name), '-o"' + entry.parentPath + '"' ] );
extract.on( 'close', ( code ) => console.log( `child process exited with code ${code}` ) );
}
}
} catch (err) {
console.error(err);
}
But it does not work: files are not unpacked, all I get is messages indicating that 7-Zip had an error. I tried other variants. For example, enclosing the second argument in double quotes:
'"' + join(entry.parentPath, entry.name) + '"'
Or avoiding double quotes:
[ 'x', join(entry.parentPath, entry.name), '-o', entry.parentPath ]
But the result is the same. Usually, exit code 7, but sometimes exit code 2. Why? How to solve the problem?
The syntax for output directory is:
-o{dir_path}https://web.mit.edu/outland/arch/i386_rhel4/build/p7zip-current/DOCS/MANUAL/switches/output_dir.htm
So, the correct code for output argument is '-o' + entry.parentPath:
spawn( 'C:\\software\\7z2501-extra\\x64\\7za.exe', [ 'x', join(entry.parentPath, entry.name), '-o' + entry.parentPath ]);
Exit codes can be one of the following:
Code Meaning
0 No error
1 Warning (Non fatal error(s)). For example, one or more files were locked by some other application, so they were not compressed.
2 Fatal error
7 Command line error
8 Not enough memory for operation
255 User stopped the process
So, if you don't receive 0 code, it means you have some problem with the input files.
You might add code to check whether exit code is not successful, and then log the file for further processing, and also capture extract.stderr to log exact 7zip error for debugging.
For example:
const zipFile = join(entry.parentPath, entry.name);
const extract = spawn( 'C:\\software\\7z2501-extra\\x64\\7za.exe', [ 'x', zipFile, '-o' + entry.parentPath ]);
extract.on('close', (code) => {
// some problem, handle
if (code !== 0) {
console.log('failed extracting zip: ', zipFile, 'code: ', code);
} else {
// success
console.log(`extracted`, zipFile);
}
});
// debug error
extract.stderr.on('data', (data) => {
console.log(`err`, data.toString());
});
Or you might test if first, and only then extract it.