在Cmdlet中,如何检测是否设置了Debug标志

本文关键字:是否 设置 标志 Debug 检测 Cmdlet 何检测 | 更新日期: 2023-09-27 18:29:06

我正在编写PowerShell Cmdlet并使用WriteDebug,但我想编写一个需要额外API调用的对象,并且我宁愿在调试关闭时不进行该调用。如何检测是否设置了Debug标志,以便完全跳过对WriteDebug的调用?

例如,我的WriteDebug调用看起来像这样:

WriteDebug(string.Format("Name : {0}", api.GetName(myobj)));

在该示例中,除非启用调试,否则我希望避免调用api.GetName

在Cmdlet中,如何检测是否设置了Debug标志

只需检查是否设置了-Debug标志就可以用下面的代码完成,但这还不够。

bool debug = false;
bool containsDebug = MyInvocation.BoundParameters.ContainsKey("Debug");
if (containsDebug)
    debug = ((SwitchParameter)MyInvocation.BoundParameters["Debug"]).ToBool();

PowerShell还允许您设置一个名为$DebugPreference的全局标志,上面的代码不会检查该标志。从另一个cmdlet调用cmdlet会继承这些通用参数,这些参数不是通过上面代码检查时的Debug标志继承的。下面的代码将检查$DebugPreference并解决这些问题。

debug = (ActionPreference)GetVariableValue("DebugPreference") != ActionPreference.SilentlyContinue;

不幸的是,与PowerShell中的cmdlet相反,您必须同时检查两者。所以最后的C#代码如下。我还添加了Verbose公共参数的代码作为奖励。请确保从PSCmdlet而不是Cmdlet继承以获得GetVariableValue方法。

bool debug = false;
bool containsDebug = MyInvocation.BoundParameters.ContainsKey("Debug");
if (containsDebug)
    debug = ((SwitchParameter)MyInvocation.BoundParameters["Debug"]).ToBool();
else
    debug = (ActionPreference)GetVariableValue("DebugPreference") != ActionPreference.SilentlyContinue;
bool verbose = false;
bool containsVerbose = MyInvocation.BoundParameters.ContainsKey("Verbose");
if (containsVerbose)
    verbose = ((SwitchParameter)MyInvocation.BoundParameters["Verbose"]).ToBool();
else
    verbose = (ActionPreference)GetVariableValue("VerbosePreference") != ActionPreference.SilentlyContinue; 

试试这个:

$Debug = $psboundparameters.debug.ispresent

if ($Debug){
  Write-Debug(string.Format("Name : {0}", api.GetName(myobj))
  }

Experimentation表示您可能希望查看$DebugPreference变量。我用高级函数尝试过它,但它在cmdlet中可能也同样有效。

尝试以下命令序列:

function f { [cmdletbinding()]Param() $DebugPreference }
function g { [cmdletbinding()]Param() f }
f
f -Debug
g
g -Debug

要从C#访问Debug标志,您应该能够做与mjolinor建议的基本相同的事情:

if (this.MyInvocation.BoundParameters.ContainsKey("Debug"))
{
    ... do something ...
}

但是,请注意,您可以指定值为false的调试参数:

MyCmdlet -Debug:$false

为了处理这种情况,您可能需要添加这样的内容(从PSCmdlet中):

bool debug = MyInvocation.BoundParameters.ContainsKey("Debug") &&
             ((SwitchParameter)MyInvocation.BoundParameters["Debug"]).ToBool();

在C#中,BoundParameters是一个字典,因此您也可以使用TryGetValue(),但请注意,开关(如Debug)的值是SwitchParameter,而不是bool。

有关更多信息,请参阅以下内容:

  • PSCmdlet.My位置:http://msdn.microsoft.com/en-us/library/system.management.automation.pscmdlet.myinvocation(v=vs.85).aspx
  • 边界参数:http://msdn.microsoft.com/en-us/library/system.management.automation.invocationinfo.boundparameters(v=vs.85).aspx
  • 开关参数:http://msdn.microsoft.com/en-us/library/windows/desktop/system.management.automation.switchparameter(v=vs.85).aspx