将Powershell脚本粘贴到Powershell中时运行,但是从快捷方式运行时不运行

时间:2019-03-07 17:12:07

标签: powershell unicode utf-8 character-encoding codepages

我正在尝试编写一个脚本,该脚本会将多个excel文件转换为PDF。这是我第一次在Powershell中进行类似的操作。 I found a link to one online that works

$path = Read-Host -Prompt 'Input Directory Path and Press Enter' 
$xlFixedFormat = “Microsoft.Office.Interop.Excel.xlFixedFormatType” -as [type] 
$excelFiles = Get-ChildItem -Path $path -include *.xls, *.xlsx -recurse 
$objExcel = New-Object -ComObject excel.application 
$objExcel.visible = $false 
foreach($wb in $excelFiles) 
{ 
 $filepath = Join-Path -Path $path -ChildPath ($wb.BaseName + “.pdf”) 
 $workbook = $objExcel.workbooks.open($wb.fullname, 3) 
 $workbook.Saved = $true 
“saving $filepath” 
 $workbook.ExportAsFixedFormat($xlFixedFormat::xlTypePDF, $filepath) 
 $objExcel.Workbooks.close() 
} 
$objExcel.Quit()

如果我将其复制并粘贴到Powershell中,程序将按预期运行。但是,当我尝试通过快捷方式运行该程序时,出现了一些错误(文件另存为.ps1)。

这是设置快捷方式时我做的路径和参数:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -ExecutionPolicy Bypass -File C:\[File Path]

这是我收到的错误消息:

At C:\Users\cbeals.ENVIROTECH\Documents\Test\ConvertExcelToPDF.ps1:8 char:62
+  $filepath = Join-Path -Path $path -ChildPath ($wb.BaseName + “.pdf ...
+                                                              ~
You must provide a value expression following the '+' operator.
At C:\Users\cbeals.ENVIROTECH\Documents\Test\ConvertExcelToPDF.ps1:8 char:63
+ ... lepath = Join-Path -Path $path -ChildPath ($wb.BaseName + “.pdfâ€)
+                                                               ~~~~~~~~~~
Unexpected token '“.pdfâ€' in expression or statement.
At C:\Users\cbeals.ENVIROTECH\Documents\Test\ConvertExcelToPDF.ps1:8 char:62
+  $filepath = Join-Path -Path $path -ChildPath ($wb.BaseName + “.pdf ...
+                                                              ~
Missing closing ')' in expression.
At C:\Users\cbeals.ENVIROTECH\Documents\Test\ConvertExcelToPDF.ps1:7 char:1
+ {
+ ~
Missing closing '}' in statement block or type definition.
At C:\Users\cbeals.ENVIROTECH\Documents\Test\ConvertExcelToPDF.ps1:8 char:73
+ ... lepath = Join-Path -Path $path -ChildPath ($wb.BaseName + “.pdfâ€)
+                                                                         ~
Unexpected token ')' in expression or statement.
At C:\Users\cbeals.ENVIROTECH\Documents\Test\ConvertExcelToPDF.ps1:14 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedValueExpression

有什么想法会失败吗?

1 个答案:

答案 0 :(得分:1)

要澄清:

  • 完全可以在PowerShell中使用Unicode(非ASCII范围)引号,例如 -请参阅底部。

  • 但是,为了在 script文件中使用此类字符,这些文件必须使用 Unicode 字符编码,例如UTF -8或UTF-16LE(“ Unicode”)。

您的问题是您的脚本文件被保存为UTF-8 而没有BOM ,这会导致Windows PowerShell(而不是PowerShell Core )出现 mis ,因为它默认为“ ANSI”编码,即与旧版系统语言环境(例如Windows 1252中的美国和西欧),PowerShell将其称为Default

在用Unicode引号替换Unicode引号可以解决当前的问题时,脚本中的其他任何非ASCII范围的字符都将继续被误解。

  • 正确的解决方案是使用BOM将文件重新保存为UTF-8
  • 形成一个习惯是使用BOM将所有PowerShell脚本(源代码)常规保存为UTF-8 ,因为这样可以确保对它们进行解释。无论任何给定计算机的系统区域设置如何,都相同。

演示特定问题:

  • ,左双引号(U+201C)Unicode字符,以UTF-8格式编码为 3 个字节:0xE2 0x80 0x9C

    • 您可以通过'“' | Format-Hex -Encoding Utf8的输出来验证这一点(这里只涉及字节序列;在这种情况下,右边的印刷字符不具有代表性)。
  • 当Windows PowerShell将该序列读取为“ ANSI”编码时,它会认为每个字节本身就是一个字符,这就是为什么看到 3 的原因输出中的单个的字符,即“

    • 您可以使用[Text.Encoding]::Default.GetString([byte[]] (0xE2, 0x80, 0x9C))进行验证(从PowerShell Core ,使用[Text.Encoding]::GetEncoding([cultureinfo]::CurrentCulture.TextInfo.ANSICodePage).GetString([byte[]] (0xE2, 0x80, 0x9C)))。

在PowerShell中可互换使用ASCII范围和Unicode引号/破折号/空格:

在正确编码的输入文件中,PowerShell允许以下引号和标点符号可互换使用;例如"hi"”hi”甚至"hi„都是等效的。

注意:

  • 重要:以上描述了这些字符的可互换的句法用法;如果您在标识符(不应使用)或字符串 [1] 中使用此类字符,则它们不是 也是一样。

  • 上面部分收集了CARRIAGE RETURN(文件SpecialCharacters中的类parserutils.cs)。


[1]有一些例外:由于PowerShell的-eq运算符使用不变文化比较字符串,而不是执行常规比较, em> space-character 变体 在字符串比较中可以被视为相同,取决于宿主平台;例如,"foo bar" -eq "foo`u{a0}bar"在macOS和Linux(而不是Windows!)上产生$true,因为常规的ASCII范围空间被认为等于其中的不间断空间(U+00A0)。 / sup>