CBe*_*als 3 unicode powershell utf-8 character-encoding codepages
我正在尝试编写一个脚本,将多个 Excel 文件转换为 PDF 文件。我在网上找到了一个有效的链接。
\n$path = Read-Host -Prompt \'Input Directory Path and Press Enter\'\n$xlFixedFormat = \xe2\x80\x9cMicrosoft.Office.Interop.Excel.xlFixedFormatType\xe2\x80\x9d -as [type]\n$excelFiles = Get-ChildItem -Path $path -include *.xls, *.xlsx -recurse\n$objExcel = New-Object -ComObject excel.application\n$objExcel.visible = $false\nforeach($wb in $excelFiles)\n{\n $filepath = Join-Path -Path $path -ChildPath ($wb.BaseName + \xe2\x80\x9c.pdf\xe2\x80\x9d)\n $workbook = $objExcel.workbooks.open($wb.fullname, 3)\n $workbook.Saved = $true\n \xe2\x80\x9csaving $filepath\xe2\x80\x9d\n $workbook.ExportAsFixedFormat($xlFixedFormat::xlTypePDF, $filepath)\n $objExcel.Workbooks.close()\n}\n$objExcel.Quit()\nRun Code Online (Sandbox Code Playgroud)\n如果我将其复制并粘贴到 PowerShell 窗口中,程序将按预期运行。但是,当我尝试创建运行该程序的快捷方式时,出现了几个错误(文件保存为 .ps1)。
\n这是我在设置快捷方式时所做的路径和参数:
\n$path = Read-Host -Prompt \'Input Directory Path and Press Enter\'\n$xlFixedFormat = \xe2\x80\x9cMicrosoft.Office.Interop.Excel.xlFixedFormatType\xe2\x80\x9d -as [type]\n$excelFiles = Get-ChildItem -Path $path -include *.xls, *.xlsx -recurse\n$objExcel = New-Object -ComObject excel.application\n$objExcel.visible = $false\nforeach($wb in $excelFiles)\n{\n $filepath = Join-Path -Path $path -ChildPath ($wb.BaseName + \xe2\x80\x9c.pdf\xe2\x80\x9d)\n $workbook = $objExcel.workbooks.open($wb.fullname, 3)\n $workbook.Saved = $true\n \xe2\x80\x9csaving $filepath\xe2\x80\x9d\n $workbook.ExportAsFixedFormat($xlFixedFormat::xlTypePDF, $filepath)\n $objExcel.Workbooks.close()\n}\n$objExcel.Quit()\nRun Code Online (Sandbox Code Playgroud)\n这是我收到的错误消息:
\nC:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -noexit -ExecutionPolicy Bypass -File C:\\[File Path]\nRun Code Online (Sandbox Code Playgroud)\n为什么这会失败?
\n澄清:
\n使用 Unicode(非 ASCII 范围)引号是完全可以的,例如\xe2\x80\x9c在 PowerShell 中- 请参阅底部部分。
但是,为了在脚本文件中使用此类字符,这些文件必须使用Unicode字符编码,例如 UTF-8 或 UTF-16LE(“Unicode”)。
\n您的问题是您的脚本文件保存为没有BOM的 UTF-8 ,这会导致Windows PowerShell(但不是 PowerShell (Core) 7+)误解它,因为它默认为“ANSI”编码,即单字节与遗留系统区域设置相关的遗留编码又称为非 Unicode 程序的语言(例如,美国和西欧的Windows-1252Default ),PowerShell 将其称为.
虽然用对应的 ASCII 引号替换 Unicode 引号可以解决眼前的问题,但脚本中的任何其他非 ASCII 范围字符将继续被误解。
\n正确的解决方案是将文件重新保存为带有 BOM 的UTF-8 。
\n养成定期将所有 PowerShell 脚本(源代码)保存为带有 BOM 的UTF-8是一个好习惯,因为这可以确保它们被解释为相同,而不管任何给定计算机的系统区域设置(文化)如何,并且无论您使用什么PowerShell 版本。
\n为了演示具体问题:
\n\xe2\x80\x9c,左双引号 ( ) Unicode 字符,以UTF-8 格式U+201C编码为三个0xE2 0x80 0x9C字节: 。
您可以通过以下输出来验证这一点\'\xe2\x80\x9c\' | Format-Hex -Encoding Utf8(这里只有字节序列重要;右侧打印的字符在这种情况下不具有代表性)。
当 Windows PowerShell 将此序列读取为“ANSI”编码时,它会将每个字节视为其自身的一个字符,这就是为什么您在输出中看到单个字节的三个字符,即。\xe2\x80\x9c\xc3\xa2\xe2\x82\xac\xc5\x93
您可以使用[Text.Encoding]::Default.GetString([byte[]] (0xE2, 0x80, 0x9C))(从 PowerShell Core中使用[Text.Encoding]::GetEncoding([cultureinfo]::CurrentCulture.TextInfo.ANSICodePage).GetString([byte[]] (0xE2, 0x80, 0x9C)))来验证这一点。
在正确编码的输入文件中,PowerShell 允许互换使用以下引号和标点符号;例如,"hi"、\xe2\x80\x9dhi\xe2\x80\x9d和 Even"hi\xe2\x80\x9e是等价的。
双引号:
\n"(ASCII 范围)-引号 ( U+0022)
\xe2\x80\x9c-左双引号 ( U+201C)
\xe2\x80\x9d-右双引号 ( U+201D)
\xe2\x80\x9e-双低 9 引号 (U+201E )
但不是:\xe2\x80\x9f- DOUBLE HIGH-REVERSED-9 QUOTATION MARK ( U+201F),即使它的单引号副本被识别 - 请参阅此 GitHub 问题。
单引号:
\n\'-(ASCII 范围)撇号(U+0027 )\xe2\x80\x98-左单引号 (U+2018 )\xe2\x80\x99-右单引号 (U+2019 )\xe2\x80\x9a-单低 9 引号 (U+201A )\xe2\x80\x9b-单高反转 9 引号 (U+201B )破折号(严格来说,ASCII 范围“破折号”是连字符):
\n-(ASCII 范围)-连字符减号 (U+002D )\xe2\x80\x93- EN 破折号(U+2013 )\xe2\x80\x94- EM 破折号(U+2014 )\xe2\x80\x95-水平条(U+2015 )空白:
\n注意:下面链接的源代码位置没有明确定义等效的空白字符(与引号和破折号不同)。以下内容是从基于 Unicode 字符描述的实验中收集到的,可能不完整。Unicode BMP(基本多语言平面)之外的字符(即那些代码点不适合 .NET 用于表示字符的 16 位代码单元的字符)被排除在外。
\n行内空白:
\n注意:空格字符和制表符变体可以互换用作语法单词分隔符。在空格字符变体中,只有U+200B( ZERO WIDTH SPACE ) 字符不是被视为空格。
空间:
\n (ASCII 范围空格字符)U+0020( SPACE ) U+00A0(不间断空格)\xe2\x80\x82 U+2002(空间)\xe2\x80\x83 U+2003(电磁空间)\xe2\x80\x84 U+2004(每人三个空间)\xe2\x80\x85 U+2005(四人空间))\xe2\x80\x86 U+2006(每人六人空间)\xe2\x80\x87 U+2007(图形空间)\xe2\x80\x88 U+2008(标点符号 空格)\xe2\x80\x89 U+2009(稀疏空间)\xe2\x80\x8a U+200A(头发空间)\xe2\x80\xaf U+202F(狭窄的不间断空间)\xe2\x81\x9f U+205F(中等数学空间)\xe3\x80\x80 U+3000(表意空间)制表符(由于此处无法直接打印而显示为转义序列):
\n\n行分隔空白:
\n\n笔记:
\n重要提示:上面描述了这些字符的可互换语法使用;如果您在标识符(不应该)或字符串[1]中使用此类字符,则它们不会被同等对待。
\n上面的部分内容是从 GitHub 上的源代码中收集的(Is...文件中的函数CharTraits.cs,另请参阅上面的SpecialChars定义)。
[1] 有有限的例外:鉴于 PowerShell 的运算符使用不变区域性-eq来比较字符串而不是执行序数比较,因此在字符串比较中空格字符的变化可能会被视为相同,具体取决于主机平台;例如,在 macOS 和 Linux(但不是 Windows!)上产生,因为常规 ASCII 范围空间被认为等于那里的不间断空格 ( )。"foo bar" -eq "foo`u{a0}bar"$trueU+00A0
| 归档时间: |
|
| 查看次数: |
2765 次 |
| 最近记录: |