Powershell脚本在粘贴到Powershell中时运行,但从快捷方式运行时不运行 [英] Powershell script runs when pasted into Powershell, but not when run from shortcut
问题描述
我正在尝试编写一个脚本,该脚本会将多个excel文件转换为PDF.这是我第一次在Powershell中进行这样的操作. 我找到了一个有效的在线链接.
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()
如果我将其复制并粘贴到Powershell中,该程序将按预期运行.但是,当我尝试通过快捷方式运行该程序时,出现了一些错误(文件另存为.ps1).
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?
推荐答案
要澄清:
-
使用Unicode(非ASCII范围)引号(例如但是,为了在 script文件中使用此类字符,这些文件必须使用 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 )成为 mis ,因为它默认为"ANSI"编码,即与旧版系统区域设置(例如Windows 1252中的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
.在用Unicode引号替换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 .
- 形成一个习惯是使用BOM将所有PowerShell脚本(源代码)常规保存为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.
演示特定问题:
-
左双引号(
-
被编码为 3 字节,格式为UTF-8:
0xE2 0x80 0x9C
.
U+201C
)Unicode字符"
, the LEFT DOUBLE QUOTATION MARK (U+201C
) Unicode character, is encoded as 3 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"编码时,它会认为每个字节本身就是一个字符,这就是为什么您看到 3 的原因输出中单个
的字符,即
“
.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“
.- 您可以使用
[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范围)-标记(U+0022
) -
-左双引号(
U+201C
) -
-正确的双引号(
U+201D
)
"
(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
)
但是不是:
‟
-双高反9引号(U+201F
),即使它的单引号被识别-参见 单引号:-
'
-(ASCII范围) APOSTROPHE() -
‘
-左单引号(U+2018)
-
’
-右单引号(U+2019
) -
‚
-单低9引号() -
‛
-单个高反9引号(U+201B
)
'
- (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
)
破折号(严格来说,ASCII范围破折号"是连字符):
Dashes (strictly speaking, the ASCII-range "dash" is a hyphen):
-
-
(ASCII范围)- HYPHEN-MINUS(U+002D
) -
–
- EN DASH(U+2013
) -
—
- EM DASH(U+2014
) -
―
-水平栏(U+2015
)
-
(ASCII-range) - HYPHEN-MINUS (U+002D
)–
- EN DASH (U+2013
)—
- EM DASH (U+2014
)―
- HORIZONTAL BAR (U+2015
)
空白:
-
注意:链接到下面的源代码位置未明确定义等效的空白字符(与引号和破折号不同).以下内容是根据基于Unicode字符描述的实验得出的,可能不完整.
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) char. is not considered a space syntactically.
空格:
-
(ASCII范围的空格字符.)
U+0020
(无休息空间) -
U+2002
( EN SPACE ) -
U+2003
( EM SPACE ) -
U+2004
(三次PER-EM空间) -
U+2005
(四人间空格)) -
U+2006
( SIX-PER-EM SPACE ) -
U+2007
(配置空间 ) -
U+2008
(标点空间 ) -
U+2009
(薄空间 ) -
U+200A
(头发空间 ) -
U+202F
( NARROW NO-BREAK SPACE ) -
U+205F
(中型数学空间) -
U+3000
(思想空间 )
(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范围制表符)-U+0009
((ASCII范围的垂直制表符)-U+000B
(行标签))
"`t"
(ASCII-range tab char.) -U+0009
(CHARACTER TABULATION)"`v"
(ASCII-range vertical-tab char.) -U+000B
(LINE TABULATION))
行分隔空格:
Line-separating whitespace:
U+000A
(LINE FEED)U+000D
(CARRIAGE RETURN)
注意:
-
重要:以上描述了这些字符的可互换的句法用法;如果您在标识符中(不应使用)或字符串 [1] 中使用此类字符,则它们不是 对待相同.
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 fileparserutils.cs
).[1]有一些例外:由于PowerShell的
-eq
运算符使用不变文化比较字符串,而不是执行常规比较,字符串比较中,空格字符变体 可以被视为相同,取决于宿主平台;例如,在Mac OS和Linux(而不是Windows!)上,"foo bar" -eq "foo`u{a0}bar"
会产生$true
,因为那里的常规ASCII范围空间被认为等于不间断空间(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屋!