0

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

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

使用 gloabl (静态)变量并在可能实例化 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?
        }
    }

问候。

4

1 回答 1

2

我不认为 PowerShell 公开任何方式来获得你所要求的。

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

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

然后,您可以查看堆栈以查看哪个 cmdlet 在顶部。如果您的 cmdlet 不编写任何对象或以其他方式调用您需要此信息的代码,您可能可以避免包装正文。

于 2013-10-04T05:46:08.883 回答