Powershell script runs when pasted into Powershell, but not when run from shortcut

有些话、适合烂在心里 提交于 2019-12-29 08:11:53

问题


I am trying to put together a script that will convert several excel files into PDFs. This is my first time doing something like this in 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()

If I copy and paste this into Powershell, 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

Any ideas why this would be failing?


回答1:


To clarify:

  • It is perfectly fine to use Unicode (non-ASCII-range) quotation marks such as “ in PowerShell - see the bottom section.

  • 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").

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.

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.

  • 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.

To demonstrate the specific problem:

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

    • 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).
  • When Windows PowerShell reads this sequence as "ANSI"-encode, it considers each byte a character in its own right, which is why you saw 3 characters for the single in your output, namely “.

    • 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))).

Interchangeable use of ASCII-range and Unicode quotation marks / dashes / whitespace in PowerShell:

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.

  • Double quotes:

    • " (ASCII-range) - QUOTATION MARK (U+0022)
    • - LEFT DOUBLE QUOTATION MARK (U+201C)
    • - RIGHT DOUBLE QUOTATION MARK (U+201D)
    • - DOUBLE LOW-9 QUOTATION MARK (U+201E)

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

  • Single quotes:

    • ' - (ASCII-range) APOSTROPHE (U+0027)
    • - LEFT SINGLE QUOTATION MARK (U+2018)
    • - RIGHT SINGLE QUOTATION MARK (U+2019)
    • - SINGLE LOW-9 QUOTATION MARK (U+201A)
    • - SINGLE HIGH-REVERSED-9 QUOTATION MARK (U+201B)
  • Dashes (strictly speaking, the ASCII-range "dash" is a hyphen):

    • - (ASCII-range) - HYPHEN-MINUS (U+002D)
    • - EN DASH (U+2013)
    • - EM DASH (U+2014)
    • - HORIZONTAL BAR (U+2015)
  • Whitespace:

    • 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:

      • 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) char. is not considered a space syntactically.

      • Spaces:

        • (ASCII-range space char.) 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-range tab char.) - U+0009(CHARACTER TABULATION)
        • "`v" (ASCII-range vertical-tab char.) - U+000B(LINE TABULATION))
    • Line-separating whitespace:

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

Note:

  • 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.

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


[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.



来源:https://stackoverflow.com/questions/55049410/powershell-script-runs-when-pasted-into-powershell-but-not-when-run-from-shortc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!