如何重构/设计自定义 Cmdlet 的以下代码?在调用堆栈中,从任何地方知道正在执行的cmd

本文关键字:堆栈 调用 执行 cmd 方知道 任何地 代码 重构 何重构 Cmdlet 自定义 | 更新日期: 2023-09-27 18:33:55

基本上我有自己的自定义 Cmdlet。在调用堆栈中的任何给定时间点,我想知道由PowerShell命令处理器执行而不传递Cmd的Cmdlet。 由于它是一个相对较大的程序集 (PSModule(,具有如此多的自定义 cmdlet (>=160( 和实用工具方法,我希望有一种集中式或通用的方式来了解当前正在执行的 Cmd。

请参阅下面的代码,这可能会更好地解释问题。

使用全局(静态(变量并在实例化 Cmdlet 时或在 BeginProcessing 时对其进行设置,但如果同时执行超过 1 cmd,则会产生副作用,例如可能使用 PowerShell 作业的基础结构作为其全局变量之一将替换它。

看起来我需要上下文信息(主要是实例化 Cmdlet 的线程,但不知道如何构建它(。谁能给我一些想法?

 /// <summary>
    /// Psudeo code to depict the problem
    /// </summary>
    class MyCmdlet : PSCmdlet
    {
        public MyCmdlet()
        {
        }
        /// <summary>
        /// It doesnt seem right
        /// For ex, if two of my cmdslets are instantiated (probably by say, Start-Job)
        /// </summary>
        internal static MyCmdlet ExecutingCmdInstance
        {
            get;
            set;
        }
        protected override void BeginProcessing()
        {
            base.BeginProcessing();
            //it will have side effects if more than one Cmdlet has been executed by start-job.
            //as executing cmd instance will replaced by last Cmdlet thats been run by job.
            ExecutingCmdInstance = this;
        }
        private void foo()
        {
            MyCmdlet cmdlet = null;//How do i know which Cmdlet is being executing without passing Cmdlet?
            Class1.foo(this /*I dont want to pass it as the parameter needs to be passed around in so many places*/);
        }
    }
    internal static class Class1
    {
        /// <summary>
        /// I dont want to pass MyCmdlet with each invocation 
        /// Is there a better way the Cmdlet thats been currently executing
        /// (within which cmdlet execution context the cmd is running?)
        /// Say, for ex: asking powershell engine or some other way?
        /// </summary>
        /// <param name="IDontWantToPassit"></param>
        static internal void foo(MyCmdlet IDontWantToPassit)
        {
            MyCmdlet cmdlet = null;//How do i know which Cmdlet is being executing without passing Cmdlet?
        }
    }

问候。

如何重构/设计自定义 Cmdlet 的以下代码?在调用堆栈中,从任何地方知道正在执行的cmd

我不认为PowerShell公开了任何获得您要求的方法。

一种可能性是保留静态堆栈。 在每个 BeginProcessing/ProcessRecord/EndProcessing 方法中,您将像这样包装正文:

try {
    stack.Push(this);    
    // regular body
} finally {
    stack.Pop();
}

然后,只需查看堆栈即可查看顶部的 cmdlet。 如果你的 cmdlet 不写入任何对象或以其他方式调用需要此信息的代码,则可以避免包装正文。