.NET方法的例外是终止或不终止错误吗?

And*_*ykh 12 error-handling powershell exception

在这篇伟大的文章中, Keith解释了Powershell中终止和非终止错误之间的区别.根据Keith从调用.NET对象或类型成员抛出的异常是非终止错误.

确实,如果我们定义这个.NET类进行测试:

$a = Add-Type 'public class bla { public static void bl() { throw new System.ApplicationException("test"); }}' -PassThru
Run Code Online (Sandbox Code Playgroud)

然后这个功能:

function tst { 1 | write-host; $a::bl(); 2 | Write-host }
Run Code Online (Sandbox Code Playgroud)

我们将看到,当调用tst函数时,异常似乎是非终止的:第二个Write-Host起作用.

但考虑一下:

function tst2 { try { tst } catch { "Catch!" } }
Run Code Online (Sandbox Code Playgroud)

如果我们打开文档,我们可以读到catch响应或处理脚本中的终止错误.在文章的整个文本中,文章所处理的错误在许多地方被称为"终止".

因此,当我们在第二个Write-Host上面运行该行时,不会运行但是catch块会运行.似乎我们的非终止错误突然终止了.

怎么会?

另一个观察结果是,有了旧的陷阱,它仍然是非终止错误:

function tst3 { tst trap { "Trap!" } }
Run Code Online (Sandbox Code Playgroud)

现在,从实际角度来看,我想要实现的目标如下.在一段代码中,我想终止从.NET代码抛出的异常.我想留下cmdlet终止的终止错误和cmdlet非终止的非终止错误.

我该如何实现这一目标?

例:

Do-Something
Call::Something()
Do-SomethingElse
Call::SomethingElse()
Do-YetMoreSomething
Call::YetMoreSomething()
Run Code Online (Sandbox Code Playgroud)

我想终止上面.NET调用的所有异常.我还想终止从cmdlet终止错误.我不想终止cmdlet中的非终止错误.

Kei*_*ill 10

是的,今年早些时候出现在PowerShell MVP电子邮件列表中.PowerShell更改其.NET异常的错误处理行为,具体取决于是否存在外部try/catch.这只是推测,但我猜这是针对简单的脚本方案.也就是说,如果脚本编写者(admin)混淆了调用.NET方法并产生异常,那么PowerShell团队不希望停止执行整个脚本.一旦V2出现并引入了正确的尝试/捕获,我猜他们必须重新审视这个决定并提出当前的妥协.

也就是说,解决这个问题就像你发现的一样痛苦.您可以Stop在脚本级别设置$ ErrorActionPreference ,然后对于每个可以生成非终止错误的cmdlet使用该-ErrorAction Continue参数.或者您可以将所有.NET调用放在高级函数中,然后使用参数调用该函数-ErrorAction Stop.我希望有一个更好的答案,但在审查了MVP线程后,我没有看到任何更好的解决方案.