PowerShell 脚本在粘贴到 PowerShell 窗口时运行,但在从快捷方式运行时不运行 [英] PowerShell script runs when pasted into the PowerShell window, but not when run from shortcut

查看:111
本文介绍了PowerShell 脚本在粘贴到 PowerShell 窗口时运行,但在从快捷方式运行时不运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个脚本,将多个 Excel 文件转换为 PDF 文件.我在网上找到了一个有效的链接.

I am trying to put together a script that will convert several Excel files into PDF files. 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).

If I copy and paste this into a PowerShell window, the program runs as intended. However, when I attempted to make a shortcut to run the program, I get several errors (the file is saved as a .ps1).

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

This is the path and arguments I made when setting up the shortcut:

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

这是我收到的错误消息:

This is the error message I get:

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

为什么会失败?

推荐答案

澄清:

  • 使用 Unicode(非 ASCII 范围)引号非常好,例如 在 PowerShell 中 - 请参阅底部.

但是,为了在脚本文件中使用这些字符,这些文件必须使用Unicode字符编码,例如UTF-8 或 UTF-16LE(Unicode").

However, in order to use such characters in script files, these files must use a Unicode character encoding such as UTF-8 or UTF-16LE ("Unicode").

您的问题是您的脚本文件被保存为 UTF-8 而没有 BOM,这会导致 Windows PowerShell(但不是 PowerShell Core)误解,因为它默认为 "ANSI"编码,即与旧系统区域设置相关联的单字节旧编码(例如,Windows-1252 在美国和西欧),PowerShell 将其称为 Default.

Your problem was that your script file was saved as UTF-8 without a BOM, which causes Windows PowerShell (but not PowerShell Core) to misinterpret it, because it defaults to "ANSI" encoding, i.e., the single-byte legacy encoding associated with the legacy system locale (e.g., Windows-1252 in the US and Western Europe), which PowerShell calls Default.

虽然用对应的 ASCII 字符替换 Unicode 引号解决了眼前的问题,但脚本中的任何其他非 ASCII 范围字符都会继续被误解.

While replacing the Unicode quotation marks with their ASCII counterparts solves the immediate problem, any other non-ASCII-range characters in the script would continue to be misinterpreted.

  • 正确的解决方案是将文件重新保存为带有 BOM 的 UTF-8 .
  • 养成将所有 PowerShell 脚本(源代码)定期保存为带有 BOM 的 UTF-8 的好习惯,因为这样可以确保它们被解释为无论任何给定计算机的系统区域设置如何,都相同.
    • 请参阅此相关答案,其中显示了如何相应地配置 Visual Studio Code.
    • The proper solution is to re-save the file as UTF-8 with BOM.
    • It is a good habit to form to routinely save all PowerShell scripts (source code) as UTF-8 with BOM, because that ensures that they're interpreted the same irrespective of any given computer's system locale.
      • See this related answer, which shows how to configure Visual Studio Code accordingly.

      演示具体问题:

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

      • ", the LEFT DOUBLE QUOTATION MARK (U+201C) Unicode character, is encoded as three bytes in UTF-8 format: 0xE2 0x80 0x9C.

      您可以通过 '' | 的输出来验证这一点.Format-Hex -Encoding Utf8(此处仅字节序列重要;打印的字符.在这种情况下,右侧不具有代表性).

      You can verify this via the output from '"' | Format-Hex -Encoding Utf8 (only the byte sequence matters here; the printed chars. on the right are not representative in this case).

      当 Windows PowerShell 将此序列读取为ANSI"编码时,它认为每个字节本身就是一个字符,这就是为什么您看到 三个 输出中单个 的字符,即 “.

      When Windows PowerShell reads this sequence as "ANSI"-encoded, it considers each byte a character in its own right, which is why you saw three characters for the single " in your output, namely “.

      您可以使用 [Text.Encoding]::Default.GetString([byte[]] (0xE2, 0x80, 0x9C))(来自 PowerShell Core,使用 [Text.Encoding]::GetEncoding([cultureinfo]::CurrentCulture.TextInfo.ANSICodePage).GetString([byte[]] (0xE2, 0x80, 0x9C))).

      You can verify this with [Text.Encoding]::Default.GetString([byte[]] (0xE2, 0x80, 0x9C)) (from PowerShell Core, use [Text.Encoding]::GetEncoding([cultureinfo]::CurrentCulture.TextInfo.ANSICodePage).GetString([byte[]] (0xE2, 0x80, 0x9C))).

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

      In a properly encoded input file, PowerShell allows interchangeable use of the following quotation and punctuation characters; e.g., "hi", "hi" and even "hi„ are equivalent.

      • 双引号:

      • " (ASCII-range) - QUOTATION MARK (U+0022)

      - LEFT双引号 (U+201C)

      " - 正确双引号 (U+201D)

      - DOUBLELOW-9 引号 (U+201E)

      不是: - DOUBLE HIGH-REVERSED-9 QUOTATION MARK (U+201F),即使它的单引号对应被识别 - 见这个 GitHub 问题.

      But not: - DOUBLE HIGH-REVERSED-9 QUOTATION MARK (U+201F), even though its single-quote counterpart is recognized - see this GitHub issue.

      单引号:

      ' -(ASCII 范围)撇号 (U+0027)

      ' - (ASCII-range) APOSTROPHE (U+0027)

      ' - LEFT单引号 (U+2018)

      ' - 正确单引号 (U+2019)

      - SINGLELOW-9 引号 (U+201A)

      - SINGLEHIGH-REVERSED-9 引号 (U+201B)

      破折号(严格来说,ASCII 范围的破折号"是一个连字符):

      Dashes (strictly speaking, the ASCII-range "dash" is a hyphen):

      -(ASCII 范围)-连字符减号 (U+002D)

      - (ASCII-range) - HYPHEN-MINUS (U+002D)

      - ENDASH (U+2013)

      - EMDASH (U+2014)

      - HORIZONTAL酒吧 (U+2015)

      空格:

      • 注意:链接到下面的源代码位置没有明确定义等效的空白字符(与引号和破折号不同).以下内容是从基于 Unicode 字符描述的实验中收集的,可能不完整.Unicode BMP(基本多语言平面)之外的字符,即那些代码点不适合 .NET 用来表示字符的 16 位代码单元的字符,被排除在外.

      • Note: The source-code location linked to below doesn't define equivalent whitespace characters explicitly (unlike quotation marks and dashes). The following was gleaned from experiments based on Unicode character descriptions and may be incomplete. Characters outside the Unicode BMP (basic multilingual plane), i.e. those with code point that won't fit into the 16-bit code units .NET uses to represent characters, were excluded.

      行内空格:

      Intra-line whitespace:

      • 注意:空格字符和制表符变体可以互换用作句法单词分隔符.在空格字符变体中,只有 U+200B (零宽度空格) 字符在语法上被视为空格.

      • Note: Space-character and tab-character variations can interchangeably serve as syntactic word separators. Among the space-character variations, only the U+200B (ZERO WIDTH SPACE) character is not considered a space syntactically.

      空格:

      • (ASCII-range space character) U+0020 (SPACE)
      • U+00A0 (NO-BREAK SPACE)
      • U+2002 (EN SPACE)
      • U+2003 (EM SPACE)
      • U+2004 (THREE-PER-EM SPACE)
      • U+2005 (FOUR-PER-EM SPACE))
      • U+2006 (SIX-PER-EM SPACE)
      • U+2007 (FIGURE SPACE)
      • U+2008 (PUNCTUATION SPACE)
      • U+2009 (THIN SPACE)
      • U+200A (HAIR SPACE)
      • U+202F (NARROW NO-BREAK SPACE)
      • U+205F (MEDIUM MATHEMATICAL SPACE)
      •   U+3000 (IDEOGRAPHIC SPACE)

      制表符(显示为转义序列,因为这里不能直接打印):

      Tabulators (shown as escape sequences due not being directly printable here):

      • "`t"(ASCII 范围制表符) - U+0009(字符列表)
      • `v"(ASCII 范围垂直制表符) - U+000B(行表))
      • "`t" (ASCII-range tab character) - U+0009 (CHARACTER TABULATION)
      • "`v" (ASCII-range vertical-tab character) - U+000B (LINE TABULATION))

      行分隔空格:

      Line-separating whitespace:

      • (ASCII-range LF) U+000A (LINE FEED)
      • (ASCII-range CR) U+000D (CARRIAGE RETURN)

      注意:

      • 重要:以上描述了这些字符的可互换句法使用;如果你在标识符(你不应该)或字符串[1]中使用这样的字符,它们不是em> 一样对待.

      • Important: The above describes interchangeable syntactic use of these characters; if you use such characters in identifiers (which you shouldn't) or in strings[1], they are not treated the same.

      以上部分摘自 来自 GitHub 上的源代码(parserutils.cs 文件中的 SpecialCharacters 类).

      The above was in part gleaned from the source code on GitHub (class SpecialCharacters in file parserutils.cs).

      [1] 有一些例外情况:考虑到 PowerShell 的 -eq 运算符使用 不变区域性 来比较字符串,而不是执行 ordinal> 比较,空格字符 变体可能在字符串比较中被视为相同,取决于主机平台;例如,"foo bar"-eq "foo`u{a0}bar" 在 macOS 和 Linux(但不是 Windows!)上产生 $true,因为常规 ASCII 范围空间被认为等于 no- 在那里打断空格 (U+00A0).

      [1] There are limited exceptions: given that PowerShell's -eq operator compares string using the invariant culture rather than performing ordinal comparison, space-character variations may be treated the same in string comparisons, depending on the host platform; e.g., "foo bar" -eq "foo`u{a0}bar" yields $true on macOS and Linux (but not Windows!), because the regular ASCII-range space is considered equal to the no-break space (U+00A0) there.

      这篇关于PowerShell 脚本在粘贴到 PowerShell 窗口时运行,但在从快捷方式运行时不运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆