Powershell 使用十六进制数据写入REG_MULTI_SZ

Powershell 使用十六进制数据写入REG_MULTI_SZ,powershell,hex,registry,Powershell,Hex,Registry,我试图写入多字符串,但使用从REG文件收集的数据,所以它是十六进制格式的。我已经设法使用convert HexStringToByteArray将字符串转换为字节数组,但在注册表中产生的结果与加载REG的结果不一样,因此我认为这实际上不是要强制转换的正确数据类型。 初始数据如下所示 "NavigatorLayoutOrder"=hex(7):31,00,30,00,00,00,31,00,00,00,32,00,00,00,33,00,00,00,30,00,00,00,34,00,00,00,

我试图写入多字符串,但使用从REG文件收集的数据,所以它是十六进制格式的。我已经设法使用convert HexStringToByteArray将字符串转换为字节数组,但在注册表中产生的结果与加载REG的结果不一样,因此我认为这实际上不是要强制转换的正确数据类型。 初始数据如下所示

"NavigatorLayoutOrder"=hex(7):31,00,30,00,00,00,31,00,00,00,32,00,00,00,33,00,00,00,30,00,00,00,34,00,00,00,35,00,00,00,36,00,00,00,37,00,00,00,38,00,00,00,39,00,00,00,31,00,31,00,00,00,31,00,32,00,00,00,31,00,33,00,00,00,31,00,34,00,00,00,31,00,35,00,00,00,31,00,36,00,00,00,31,00,37,00,00,00,31,00,38,00,00,00,31,00,39,00,00,00,32,00,30,00,00,00,32,00,31,00,00,00,32,00,32,00,00,00,00,00
我已经删除了前面的十六进制(7):然后尝试将其作为纯字符串并转换为字节数组,但两种方法都不起作用。 我发现REG_MULTI_SZ是UTF-16le,但我的理解是这也是PowerShell的默认值,所以我不需要更改编码,但可能我错了

编辑:我也尝试过这个,再次写了一篇成功的文章,但结果是错误的

$enc = [system.Text.Encoding]::UTF8
[byte[]]$bytes = $enc.GetBytes($string) 
也试过

$array = $string.Split(',')
$byte = [byte[]]$array
这也会将数据放入注册表,但结果与导入注册表不同。而且,我发现的一切都指向REG文件是UTF16的想法,所以我尝试了

$enc = [system.Text.Encoding]::Unicode
[byte[]]$bytes = $enc.GetBytes($string)
都使用双端Unicode和Unicode。这不仅不起作用,结果也是一样,我觉得很奇怪。似乎改变endian值应该会改变结果

编辑:为了澄清,上面显示了从REG文件中获取的输入字符串。我只是从数据前面删除了十六进制(7):

这里可以看到结果,其中第二个值是PowerShell产生的结果,而第一个值是REG文件产生的结果。

用来产生这个的代码是

$string = "31,00,30,00,00,00,31,00,00,00,32,00,00,00,33,00,00,00,30,00,00,00,34,00,00,00,35,00,00,00,36,00,00,00,37,00,00,00,38,00,00,00,39,00,00,00,31,00,31,00,00,00,31,00,32,00,00,00,31,00,33,00,00,00,31,00,34,00,00,00,31,00,35,00,00,00,31,00,36,00,00,00,31,00,37,00,00,00,31,00,38,00,00,00,31,00,39,00,00,00,32,00,30,00,00,00,32,00,31,00,00,00,32,00,32,00,00,00,00,00"

$enc = [system.Text.Encoding]::BigEndianUnicode
[byte[]]$bytes = $enc.GetBytes($string)

New-ItemProperty "HKCU:\Software\Synchro\Synchro\ProjectConfig" -name:"NavigatorLayoutOrder2" -value:$bytes -propertyType:MultiString -force
使用Unicode编码产生的结果略有不同,但仍然是错误的。

首先,多字符串是小尾端编码的,因此您需要
[Text.Encoding]:Unicode
,而不是
[Text.Encoding]::bigendiaUnicode
。另外,对.reg文件中的字符串(
“31,00,30,00,…”
)使用
[Text.Encoding]::Unicode.GetBytes()
)将为您提供该字符串字符的字节数组:

  • '3'
    → 51,0
  • '1'
    → 49,0
  • ,”
    → 44,0
  • '0'
    → 48,0
您实际需要的是该字符串中以逗号分隔的十六进制值的字节数组:

  • 31
    → 49(字符
    '1'
  • 00
    → 0(字符
    NUL
  • 30
    → 48(字符
    '0'
在逗号处拆分字符串,将十六进制数字字符串转换为整数,并将生成的整数列表转换为字节数组:

[byte[]]$bytes = $string -split ',' | ForEach-Object { [int]"0x$_" }
然后,您可以将该(小尾端编码)字节数组转换为字符串:

$ms = [Text.Encoding]::Unicode.GetString($bytes)
并将其写入注册表:

$key  = 'HKCU:\Software\Synchro\Synchro\ProjectConfig'
$name = 'NavigatorLayoutOrder2'
New-ItemProperty $key -Name $name -Value $ms -PropertyType MultiString -Force

谢谢你,安斯加!这正是我需要的。