Powershell v4 - 无法捕获XmlDocument Load()方法错误详细信息

时间:2016-03-09 12:19:20

标签: powershell error-handling

目前正在努力理解为什么我的脚本没有像我预期的那样工作,所以我想我会把问题告诉你:)

基本上,我正在编写一个程序,它将在系统上搜索XML文件并迭代它们以确定它们是否格式正确。为此,我将Get-ChildItem查询的输出传递给ForEach-Object语句,并将详细信息记录在稍后要解析的ArrayList对象中。脚本看起来像这样;

// Variable declaration removed for brevity

Get-ChildItem -Path $dirFilePaths -Include "*.xml" -Recurse | ForEach-Object {
    $tmpFile= $_;
    $tmpXml= New-Object System.Xml.XmlDocument;

    try {
        $tmpXml.Load($tmpFile.FullName);
        $tmpValues= New-Object PSObject;

        $tmpValues | Add-Member -MemberType NoteProperty -Name "File_Name" -Value $tmpFile.Name;
        $tmpValues | Add-Member -MemberType NoteProperty -Name "File_Path" -Value $tmpFile.FullName;
        $tmpValues | Add-Member -MemberType NoteProperty -Name "File_Status" -Value "OK";

        $arlFilesSuccess.Add($tmpValues)
        }
    catch {
        $tmpValues= New-Object PSObject;

        $tmpValues | Add-Member -MemberType NoteProperty -Name "File_Name" -Value $tmpFile.Name;
        $tmpValues | Add-Member -MemberType NoteProperty -Name "File_Path" -Value $tmpFile.FullName;
        $tmpValues | Add-Member -MemberType NoteProperty -Name "File_Status" -Value "NOT OK";
        $tmpValues | Add-Member -MemberType NoteProperty -Name "Error_Details" -Value $Error[-1].Exception;

        $arlFilesFailure.Add($tmpValues); 
        }
    }

我面临的问题是$Error变量实际上并不包含任何有关如果$tmpXml.Load()方法因文件问题而失败而无法加载XML的信息。例如,如果我将名为“style.xml”的系统上的文件调用到脚本之外的$ tmpXml中,我会从PowerShell窗口中收到以下错误消息;

Exception calling "Load" with "1" argument(s): "The 'install-disabled' start tag on line 26 position 3 does not match the end tag of 'install'.
Line 26, position 105."
At line:1 char:1
+ $tmpXml.Load($arlFilesFailure[20].File_Path)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

但是当我在PowerShell控制台中输入$Error.count时,由于某种未知原因,我得到的值为0。我已尝试将$ErrorActionPreference变量修改为Stop以强制终止错误;我也尝试将上面的脚本写入ScriptBlock并使用Invoke-Command调用它,并将ErrorVariable CommonParameter设置为自定义变量 - 仍然没有捕获命令的错误信息,我无法弄清楚这里发生了什么!

这是否与遇到的异常是MethodInvocationException并且未被归类为终止错误这一事实有关?它在Try / Catch语句中被“捕获”,因此它必须是终止错误,不是吗?任何人都可以告诉我为什么这些细节没有记录在全局$Error变量中(以及我如何检索该信息)?

2 个答案:

答案 0 :(得分:1)

catch块中,变量$_表示当前异常(如 ErrorRecord)。您不必使用$Error。但是当你必须使用时 $Error请记住,最近的错误是$Error[0],即第一个错误 清单。

此外,ForEach-Object可能会导致一些不明确的错误,请参阅以下示例: PowerShellTraps//Cmdlets/ForEach-Object

答案 1 :(得分:0)

我建议在这里使用PowerShell Community Extensions module。它已经有一个Test-Xml函数,可以完成你想要做的事情。