Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wrong encoding when using child_process spawn or exec under Windows

Using the dir command in Windows CMD will result in the following output:

Verzeichnis von D:\workspace\filewalker

22.12.2013  17:27    <DIR>          .
22.12.2013  17:27    <DIR>          ..
22.12.2013  17:48               392 test.js
22.12.2013  17:23                 0 testöäüÄÖÜ.txt
22.12.2013  17:27    <DIR>          testÖÄÜöüäß
2 Datei(en),            392 Bytes
3 Verzeichnis(se), 273.731.170.304 Bytes frei

Using exec or spawn will result in this:

Verzeichnis von D:\workspace\filewalker

22.12.2013  17:27    <DIR>          .
22.12.2013  17:27    <DIR>          ..
22.12.2013  17:48               392 test.js
22.12.2013  17:23                 0 test������.txt
22.12.2013  17:27    <DIR>          test�������
2 Datei(en),            392 Bytes
3 Verzeichnis(se), 273.731.170.304 Bytes frei

Here is my Node Code:

var exec = require('child_process').exec,
    child;

child = exec('dir',
  function (error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
});
like image 660
Robert Avatar asked Dec 22 '13 17:12

Robert


3 Answers

I managed to fix it by adding cmd /c chcp 65001>nul &&(this command sets cmd's console output to utf-8) at start of my exec command, so your would look like cmd /c chcp 65001>nul && dir, it should work.

If you write cross-platform can use process.platform, to determine when you need that, something like that:

var cmd = "";
if (process.platform === "win32") { 
  cmd += "cmd /c chcp 65001>nul && "; 
};
cmd += "dir";

child = exec(cmd, //...
  • Even though dir command is not "cross-platform".
like image 77
BladeMight Avatar answered Nov 17 '22 15:11

BladeMight


I solved it (Simplified Chinese) by below code, don't know the coding page for other languages, maybe you can find it from Microsoft website:

  const encoding          = 'cp936';
  const binaryEncoding    = 'binary';

  function iconvDecode(str = '') {
      return iconv.decode(Buffer.from(str, binaryEncoding), encoding);
  }

  const  { exec } = require('child_process');  
  exec('xxx', { encoding: 'binary' }, (err, stdout, stderr) => {
        const result = iconvDecode(stdout);
        xxx
  });
like image 40
Zhang Buzz Avatar answered Nov 17 '22 14:11

Zhang Buzz


From http://www.nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback

There is a second optional argument to specify several options. The default options are

{ encoding: 'utf8',
  timeout: 0,
  maxBuffer: 200*1024,
  killSignal: 'SIGTERM',
  cwd: null,
  env: null }

That is Node defaults to utf8, while Windows has different code pages for different language version.

like image 44
Paul Verest Avatar answered Nov 17 '22 14:11

Paul Verest