Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
CimRegisterCimIndication.cs349 linesDownload Raw Back to Microsoft.Management.Infrastructure.CimCmdlets
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#region Using directives5 6using System;7using System.Globalization;8using System.Management.Automation;9using System.Threading;10 11#endregion12 13namespace Microsoft.Management.Infrastructure.CimCmdlets14{15    /// <summary>16    /// <para>17    /// Subscription result event args18    /// </para>19    /// </summary>20    internal abstract class CimSubscriptionEventArgs : EventArgs21    {22        /// <summary>23        /// <para>24        /// Returns an Object value for an operation context25        /// </para>26        /// </summary>27        public object Context28        {29            get30            {31                return context;32            }33        }34 35        protected object context;36    }37 38    /// <summary>39    /// <para>40    /// Subscription result event args41    /// </para>42    /// </summary>43    internal class CimSubscriptionResultEventArgs : CimSubscriptionEventArgs44    {45        /// <summary>46        /// <para>47        /// subscription result48        /// </para>49        /// </summary>50        public CimSubscriptionResult Result { get; }51 52        /// <summary>53        /// Initializes a new instance of the <see cref="CimSubscriptionResultEventArgs"/> class.54        /// </summary>55        /// <param name="theResult"></param>56        public CimSubscriptionResultEventArgs(57            CimSubscriptionResult theResult)58        {59            this.context = null;60            this.Result = theResult;61        }62    }63 64    /// <summary>65    /// <para>66    /// Subscription result event args67    /// </para>68    /// </summary>69    internal class CimSubscriptionExceptionEventArgs : CimSubscriptionEventArgs70    {71        /// <summary>72        /// <para>73        /// subscription result74        /// </para>75        /// </summary>76        public Exception Exception { get; }77 78        /// <summary>79        /// Initializes a new instance of the <see cref="CimSubscriptionExceptionEventArgs"/> class.80        /// </summary>81        /// <param name="theResult"></param>82        public CimSubscriptionExceptionEventArgs(83            Exception theException)84        {85            this.context = null;86            this.Exception = theException;87        }88    }89 90    /// <summary>91    /// <para>92    /// Implements operations of register-cimindication cmdlet.93    /// </para>94    /// </summary>95    internal sealed class CimRegisterCimIndication : CimAsyncOperation96    {97        /// <summary>98        /// <para>99        /// New subscription result event100        /// </para>101        /// </summary>102        public event EventHandler<CimSubscriptionEventArgs> OnNewSubscriptionResult;103 104        /// <summary>105        /// Initializes a new instance of the <see cref="CimRegisterCimIndication"/> class.106        /// </summary>107        public CimRegisterCimIndication()108            : base()109        {110            this.ackedEvent = new ManualResetEventSlim(false);111        }112 113        /// <summary>114        /// Start an indication subscription target to the given computer.115        /// </summary>116        /// <param name="computerName">Null stands for localhost.</param>117        /// <param name="nameSpace"></param>118        /// <param name="queryDialect"></param>119        /// <param name="queryExpression"></param>120        /// <param name="operationTimeout"></param>121        public void RegisterCimIndication(122            string computerName,123            string nameSpace,124            string queryDialect,125            string queryExpression,126            uint operationTimeout)127        {128            DebugHelper.WriteLogEx("queryDialect = '{0}'; queryExpression = '{1}'", 0, queryDialect, queryExpression);129            this.TargetComputerName = computerName;130            CimSessionProxy proxy = CreateSessionProxy(computerName, operationTimeout);131            proxy.SubscribeAsync(nameSpace, queryDialect, queryExpression);132            WaitForAckMessage();133        }134 135        /// <summary>136        /// Start an indication subscription through a given <see cref="CimSession"/>.137        /// </summary>138        /// <param name="cimSession">Cannot be null.</param>139        /// <param name="nameSpace"></param>140        /// <param name="queryDialect"></param>141        /// <param name="queryExpression"></param>142        /// <param name="operationTimeout"></param>143        /// <exception cref="ArgumentNullException">Throw if cimSession is null.</exception>144        public void RegisterCimIndication(145            CimSession cimSession,146            string nameSpace,147            string queryDialect,148            string queryExpression,149            uint operationTimeout)150        {151            DebugHelper.WriteLogEx("queryDialect = '{0}'; queryExpression = '{1}'", 0, queryDialect, queryExpression);152 153            ArgumentNullException.ThrowIfNull(cimSession, string.Format(CultureInfo.CurrentUICulture, CimCmdletStrings.NullArgument, nameof(cimSession)));154 155            this.TargetComputerName = cimSession.ComputerName;156            CimSessionProxy proxy = CreateSessionProxy(cimSession, operationTimeout);157            proxy.SubscribeAsync(nameSpace, queryDialect, queryExpression);158            WaitForAckMessage();159        }160 161        #region override methods162 163        /// <summary>164        /// <para>165        /// Subscribe to the events issued by <see cref="CimSessionProxy"/>.166        /// </para>167        /// </summary>168        /// <param name="proxy"></param>169        protected override void SubscribeToCimSessionProxyEvent(CimSessionProxy proxy)170        {171            DebugHelper.WriteLog("SubscribeToCimSessionProxyEvent", 4);172            // Raise event instead of write object to ps173            proxy.OnNewCmdletAction += this.CimIndicationHandler;174            proxy.OnOperationCreated += this.OperationCreatedHandler;175            proxy.OnOperationDeleted += this.OperationDeletedHandler;176            proxy.EnableMethodResultStreaming = false;177        }178 179        /// <summary>180        /// <para>181        /// Handler used to handle new action event from182        /// <seealso cref="CimSessionProxy"/> object.183        /// </para>184        /// </summary>185        /// <param name="cimSession">186        /// <seealso cref="CimSession"/> object raised the event187        /// </param>188        /// <param name="actionArgs">Event argument.</param>189        private void CimIndicationHandler(object cimSession, CmdletActionEventArgs actionArgs)190        {191            DebugHelper.WriteLogEx("action is {0}. Disposed {1}", 0, actionArgs.Action, this.Disposed);192 193            if (this.Disposed)194            {195                return;196            }197 198            // NOTES: should move after this.Disposed, but need to log the exception199            if (actionArgs.Action is CimWriteError cimWriteError)200            {201                this.Exception = cimWriteError.Exception;202                if (!this.ackedEvent.IsSet)203                {204                    // an exception happened205                    DebugHelper.WriteLogEx("an exception happened", 0);206                    this.ackedEvent.Set();207                    return;208                }209 210                EventHandler<CimSubscriptionEventArgs> temp = this.OnNewSubscriptionResult;211                if (temp != null)212                {213                    DebugHelper.WriteLog("Raise an exception event", 2);214 215                    temp(this, new CimSubscriptionExceptionEventArgs(this.Exception));216                }217 218                DebugHelper.WriteLog("Got an exception: {0}", 2, Exception);219            }220 221            if (actionArgs.Action is CimWriteResultObject cimWriteResultObject)222            {223                if (cimWriteResultObject.Result is CimSubscriptionResult result)224                {225                    EventHandler<CimSubscriptionEventArgs> temp = this.OnNewSubscriptionResult;226                    if (temp != null)227                    {228                        DebugHelper.WriteLog("Raise an result event", 2);229                        temp(this, new CimSubscriptionResultEventArgs(result));230                    }231                }232                else233                {234                    if (!this.ackedEvent.IsSet)235                    {236                        // an ACK message returned237                        DebugHelper.WriteLogEx("an ack message happened", 0);238                        this.ackedEvent.Set();239                        return;240                    }241                    else242                    {243                        DebugHelper.WriteLogEx("an ack message should not happen here", 0);244                    }245                }246            }247        }248 249        /// <summary>250        /// Block the ps thread until ACK message or Error happened.251        /// </summary>252        private void WaitForAckMessage()253        {254            DebugHelper.WriteLogEx();255            this.ackedEvent.Wait();256            if (this.Exception != null)257            {258                DebugHelper.WriteLogEx("error happened", 0);259                if (this.Cmdlet != null)260                {261                    DebugHelper.WriteLogEx("Throw Terminating error", 1);262 263                    // throw terminating error264                    ErrorRecord errorRecord = ErrorToErrorRecord.ErrorRecordFromAnyException(265                        new InvocationContext(this.TargetComputerName, null), this.Exception, null);266                    this.Cmdlet.ThrowTerminatingError(errorRecord);267                }268                else269                {270                    DebugHelper.WriteLogEx("Throw exception", 1);271                    // throw exception out272                    throw this.Exception;273                }274            }275 276            DebugHelper.WriteLogEx("ACK happened", 0);277        }278        #endregion279 280        #region internal property281        /// <summary>282        /// The cmdlet object who issue this subscription,283        /// to throw ThrowTerminatingError284        /// in case there is a subscription failure.285        /// </summary>286        /// <param name="cmdlet"></param>287        internal Cmdlet Cmdlet288        {289            get;290            set;291        }292 293        /// <summary>294        /// Target computername.295        /// </summary>296        internal string TargetComputerName297        {298            get;299            set;300        }301 302        #endregion303 304        #region private methods305        /// <summary>306        /// <para>307        /// Create <see cref="CimSessionProxy"/> and set properties308        /// </para>309        /// </summary>310        /// <param name="computerName"></param>311        /// <param name="timeout"></param>312        /// <returns></returns>313        private CimSessionProxy CreateSessionProxy(314            string computerName,315            uint timeout)316        {317            CimSessionProxy proxy = CreateCimSessionProxy(computerName);318            proxy.OperationTimeout = timeout;319            return proxy;320        }321 322        /// <summary>323        /// Create <see cref="CimSessionProxy"/> and set properties.324        /// </summary>325        /// <param name="session"></param>326        /// <param name="timeout"></param>327        /// <returns></returns>328        private CimSessionProxy CreateSessionProxy(329            CimSession session,330            uint timeout)331        {332            CimSessionProxy proxy = CreateCimSessionProxy(session);333            proxy.OperationTimeout = timeout;334            return proxy;335        }336        #endregion337 338        #region private members339 340        /// <summary>341        /// Exception occurred while start the subscription.342        /// </summary>343        internal Exception Exception { get; private set; }344 345        #endregion346 347    }348}349