【问题标题】:In a Cmdlet, how can I detect if the Debug flag is set?在 Cmdlet 中,如何检测是否设置了 Debug 标志?
【发布时间】:2013-12-30 01:40:59
【问题描述】:

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

例如,我的 WriteDebug 调用将如下所示:

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

在那个例子中,我想避免调用api.GetName,除非打开调试。

【问题讨论】:

标签: c# powershell


【解决方案1】:

试试这个:

$Debug = $psboundparameters.debug.ispresent


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

【讨论】:

  • +1 - 你有一个很好的链接来解释 $psboundparameters 的这种很棒的用法吗?谢谢!
  • 谢谢!抱歉不行。我刚刚运行了一个测试函数并检查了 -debug 开关是如何出现在绑定中的。
  • 如何从 C# 访问它?我正在编写一个扩展 PSCmdlet 的 C# 类,而不是脚本 cmdlet。
  • $psboundparameters 用法在about_Automatic_Variables中描述
  • 这种方法的问题是 Debug 设置是继承的,但是它在 psboundparameters 中的存在没有被继承。 (对不起,我没有任何建设性的贡献。)
【解决方案2】:

只检查是否设置了-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;

不幸的是in contrary to a cmdlet in PowerShell 你必须同时检查两者。所以最终的 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; 

【讨论】:

    【解决方案3】:

    要从 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 而不是布尔值。

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

    【讨论】:

    • 如果从另一个 cmdlet 调用 cmdlet 并且不考虑 $DebugPreference,则此方法不起作用。
    【解决方案4】:

    实验表明您可能希望查看 $DebugPreference 变量。我尝试过使用高级功能,但它可能在 cmdlet 中也能正常工作。

    尝试以下命令序列:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-23
      • 2011-03-09
      • 2016-05-25
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多