PowerShell 脚本用于在打开 PDF 时捕获 Adob​​e Reader 错误

PowerShell 脚本用于在打开 PDF 时捕获 Adob​​e Reader 错误

我编写了一个 PowerShell 脚本来打开文件夹及其子文件夹中的所有 PDF 文件。我知道某些 PDF 在打开时会出现 Adob​​e Acrobat Reader DC 错误。

该脚本的目标是打开目录(和子目录)内的所有 pdf 文件,并记录任何打开时出现错误的文件路径(成功打开的文件不应记录任何内容)。

我认为这是因为 PowerShell 成功打开了文件,本身没有错误;错误发生在 Adob​​e 方面。Adobe Acrobat Reader DC 显示的错误是:

Adobe Acrobat Reader DC could not open 'FileName' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded).

是否可以使用 PowerShell 捕获这些 Adob​​e Acrobat Reader DC 错误?我当前的脚本如下:

$TargetPath = "C:\Users\User1\Desktop\Test.pdf"
$ErrorLog = "C:\Users\User1\Desktop\ErrorLog.txt"

Try
{
    Get-ChildItem -Path $TargetPath *.pdf -Recurse | ForEach { Invoke-Item -Path $_.FullName }
}
Catch
{
    "Error Opening $_.FullName" | Add-Content $ErrorLog
}

请注意,我是 PowerShell 的完全初学者,我根据从 Google 搜索中收集到的信息编写了此脚本。任何改进它的技巧都值得赞赏。

答案1

花时间来了解它真的很重要,以避免误解、错误、坏习惯等......

Powershell 入门

Windows PowerShell 生存指南

错误处理非常具体,具体到您要捕获的错误类型,甚至具体到您应该捕获的错误类型。 Try/catch 仅捕获终止错误。您收到的错误不是 Adob​​e 应用程序终止错误,不是 Adob​​e 打开,而只是文件打开错误。

PowerShell 教程 – Try Catch Finally 和 PowerShell 中的错误处理

了解 PowerShell 中的非终止错误

强制错误停止 Windows PowerShell(而不是允许其继续执行下一行)的一种方法是将 ErrorAction 首选项从 Continue 更改为 Stop。我可以在 cmdlet 级别执行此操作。我使用 Get-ChildItem cmdlet 中的 –ErrorAction 自动参数(Dir 是别名),并将其更改为 Stop。这会导致错误终止 Windows PowerShell 执行并强制其进入 Catch 块。以下是更改:

Try {dir c:\missingFolder -ErrorAction Stop}
Catch [System.Exception] {"Caught the exception"}
Finally {$error.Clear() ; "errors cleared"}

OP 更新

至于……

无论如何,根据您的评论和链接,我无法弄清楚这种类型的“文件打开错误”是否可以在任何时候使用 PowerShell 将其识别为非终止错误。

... 如果您尝试捕获文件错误,则无法捕获,因为它从未打开,只有指定的应用程序打开了。即使打开尝试失败,Adobe 也会在其列表中加载错误的文件名。因此,您也不能为此使用 Invoke-Item。您必须使用调用的应用程序/进程名称。在本例中为 AcroRd32。

下面的代码可以工作,但你会注意到它永远不会像你那样在日志中写入文件名,但它会写入消息。如果你使用默认的 $Error 变量,你会得到更多。此外,始终避免使用保留的名称或非常接近 PowerShell 中保留变量的名称。这就是我向你指出额外培训的原因。

你的帖子中还有几件事不合逻辑。你传入一个文件名,但却对所有 pdf 文件进行目录搜索。为什么?这无论如何都行不通,因为有明确的单个文件请求。所以,根本不需要 ForEach,也不需要 Get-ChildItem。然而,请记住应用程序父级,在这种情况下,Adobe 将始终启动和加载,并且在打开失败时需要人工交互。

因此,你最终会到达这里:

$TargetPath = 'D:\Documents\B1UD8+QD0gS.pdf'
$TargetPath = 'E:\temp\TestBadPDF.pdf'
$ErrorLog = 'E:\temp\ErrorLog.txt'

Get-content -Path $ErrorLog

# What is in the log now

$Error.Clear()
# My new log


# Start the file 
Invoke-Item -Path $TargetPath

# Get the process title
$ProcessHandle = (Get-Process -Name AcroRd32).MainWindowTitle

# Parse the file name
$FileName = (($TargetPath) -split '\\')[-1]

#  Validate the process call
If ($ProcessHandle -eq "$($FileName) - Adobe Acrobat Reader DC")
{
    # Custom success message
    Add-Content -Path $ErrorLog -Value "Success Opening $TargetPath"  
}
Else
{
    # Custom error message
    Add-Content -Path $ErrorLog -Value "Error Opening $TargetPath"    
}

# Check the log
Get-content -Path $ErrorLog
# My new log

Success Opening D:\Documents\B1UD8+QD0gS.pdf

# repeat the process using a bad file

$TargetPath = 'E:\temp\TestBadPDF.pdf'
$ErrorLog = 'E:\temp\ErrorLog.txt'

Get-content -Path $ErrorLog
# My new log

Success Opening D:\Documents\B1UD8+QD0gS.pdf

 $Error.Clear()

 Invoke-Item -Path $TargetPath
$ProcessHandle = (Get-Process -Name AcroRd32).MainWindowTitle
$FileName = (($TargetPath) -split '\\')[-1]

 If ($ProcessHandle -eq "$($FileName) - Adobe Acrobat Reader DC")
{
    # Custom success message
    Add-Content -Path $ErrorLog -Value "Success Opening $TargetPath"  
}
Else
{
    # Custom error message
    Add-Content -Path $ErrorLog -Value "Error Opening $TargetPath"    
}

 Get-content -Path $ErrorLog
# My new log

Success Opening D:\Documents\B1UD8+QD0gS.pdf
Error Opening E:\temp\TestBadPDF.pdf

相关内容