Node.js + Powershell : how to encode Unicode characters when using stdin. 写入

标签 node.js powershell

这个问题与这个问题有关:Powershell: how to execute command for a path containing Unicode characters?
我有一个 Node.js 应用程序,它使用 Powershell 5.1 生成一个子进程,然后重新使用它来运行不同的命令,因为它比生成单独的进程更快。
问题
问题是,包含 Unicode 字符的命令会静默失败。
代码

let childProcess = require('child_process')
let testProcess = childProcess.spawn('powershell', [])
testProcess.stdin.setEncoding('utf-8')

testProcess.stdout.on('data', (data) => {
  console.log(data.toString())
})

testProcess.stdout.on('error', (error) => {
  console.log(error)
})

// This path is working, I get command output in the console:
// testProcess.stdin.write("(Get-Acl 'E:/test.txt').access\n");

// This path is not working. I get nothing in the console
testProcess.stdin.write("(Get-Acl 'E:/test 📚.txt').access\n");
编辑#1
在将命令发送到 Powershell 然后将其转换为 System.Char 之前,我尝试在 Node.js 端对 UTF-8 的路径进行编码:
const path = 'E:/test $([char]0x1f4da).txt'
const command = `Get-Acl $(${path}).access`
testProcess.stdin.write(`${command}\n`)
但我不知道如何正确地做到这一点。好像我没有将它编码为正确的格式。这也不是一个真正合适的解决方案,我只是手动将表情符号编码为 utf。我可能需要将整个路径转换为 ​​UTF-16 或其他东西以确保其中没有不受支持的字符:
"E:/test 📚.txt".split("").reduce((hex,c) => hex += c.charCodeAt(0).toString(16).padStart(4,"0"),"")
不确定它是否会起作用

最佳答案

尝试以下操作:

let childProcess = require('child_process')

let testProcess = childProcess.spawn(
  'chcp 65001 >NUL & powershell.exe -NonInteractive -NoProfile -Command -', 
  { shell: true }
)

testProcess.stdout.on('data', (data) => {
  console.log(data.toString())
})

testProcess.stdout.on('error', (error) => {
  console.log(error)
})

testProcess.stdin.write("Get-Item '📚.txt'\n");
  • 虽然 Node.js 本身默认为 UTF-8,但 控制台应用程序 通常由它产生 使用系统的有效 OEM 代码页 ,如 Code page 437在美国英语系统上,它通常是一个固定的单字节,限制为 256 个字符,不支持大多数 Unicode 字符。
  • 顺便说一句:有一个 still-in-beta Windows 10 feature that allows setting both legacy code pages - ANSI and OEM - to UTF-8 ,但这样做会产生深远的影响。

  • powershell.exe , Windows PowerShell CLI也不异常(exception),因此为了使其将其标准输入输入解释为 UTF-8,OEM 代码页必须显式设置为 UTF-8 代码页,65001 , 在 powershell.exe 之前启动。
  • 因此,{ shell : true }用于确保 powershell.exe通过 cmd.exe 启动,Windows 上的默认 shell,允许执行 chcp 65001首先,它执行到 UTF-8 代码页的切换。
  • 注意:此切换到 UTF-8 作为 OEM 代码页也会影响在同一进程中对控制台应用程序的后续调用。

  • 此外:
  • -NonInteractive用于告诉 PowerShell 在 session 中不需要用户交互,这会显着阻止加载 PSReadLine用于命令行编辑的模块,这可能会导致 BMP 之外的 Unicode 字符出现问题,即代码点高于 0xFFFF 的字符(如 📚 ),需要两个 [char] .NET 中的实例。
  • -NoProfile阻止加载(点源)PowerShell配置文件,因为它们(a)通常只在交互式 session 中需要,并且(b)它们的加载不仅会减慢速度,而且会产生副作用。
  • -Command -告诉 PowerShell 从标准输入读取命令;虽然省略这个参数有点类似,但它相当于 -File - ,它表现出伪交互行为。
  • 顺便说一句:最终,-Command -和(暗示)-File -表现出意想不到的行为,如 GitHub issue #3223 中所述和 GitHub issue #15331


  • 关于Node.js + Powershell : how to encode Unicode characters when using stdin. 写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67578079/

    相关文章:

    linux - 如何获得在 Linux 上运行的全功能 PowerShell?

    powershell - 使用 PowerShell 连接文件

    node.js - Websocket 连接错误 : Does not return a 101 changing protocal when using from different path

    javascript - 如何在 linux 上安装 electron.js?

    javascript - 将 Python 脚本转换为 Node.js 的问题

    node.js - 用户如何使用 sequelize postgres nodejs 来喜欢和不喜欢彼此的帖子?

    node.js - 正确检索和显示来自 Mongoose/MongoDB .find 方法的数据

    performance - Switch 与 If-Else 性能

    Powershell脚本 “on exit”事件?

    PowerShell 函数从函数加载