Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#region Using directives5 6using System;7using System.Collections;8using System.Collections.Generic;9using System.Diagnostics;10using System.Globalization;11using System.Management.Automation;12using System.Runtime.InteropServices;13using System.Text;14using System.Threading;15using Microsoft.Management.Infrastructure.Generic;16using Microsoft.Management.Infrastructure.Options;17 18#endregion19 20namespace Microsoft.Management.Infrastructure.CimCmdlets21{22    #region Context base class23 24    /// <summary>25    /// Context base class for cross operations26    /// for example, some cmdlets need to query instance first and then27    /// remove instance, those scenarios need context object transferred28    /// from one operation to another.29    /// </summary>30    internal abstract class XOperationContextBase31    {32        /// <summary>33        /// <para>namespace</para>34        /// </summary>35        internal string Namespace36        {37            get38            {39                return this.nameSpace;40            }41        }42 43        protected string nameSpace;44 45        /// <summary>46        /// <para>47        /// Session proxy.48        /// </para>49        /// </summary>50        internal CimSessionProxy Proxy51        {52            get53            {54                return this.proxy;55            }56        }57 58        protected CimSessionProxy proxy;59    }60 61    /// <summary>62    /// Class provides all information regarding the63    /// current invocation to the .NET API.64    /// </summary>65    internal class InvocationContext66    {67        /// <summary>68        /// Initializes a new instance of the <see cref="InvocationContext"/> class.69        /// </summary>70        /// <param name="proxy"></param>71        internal InvocationContext(CimSessionProxy proxy)72        {73            if (proxy != null)74            {75                this.ComputerName = proxy.CimSession.ComputerName;76                this.TargetCimInstance = proxy.TargetCimInstance;77            }78        }79 80        /// <summary>81        /// Initializes a new instance of the <see cref="InvocationContext"/> class.82        /// </summary>83        /// <param name="proxy"></param>84        internal InvocationContext(string computerName, CimInstance targetCimInstance)85        {86            this.ComputerName = computerName;87            this.TargetCimInstance = targetCimInstance;88        }89 90        /// <summary>91        /// <para>92        /// ComputerName of the session93        /// </para>94        /// </summary>95        /// <remarks>96        /// return value could be null97        /// </remarks>98        internal virtual string ComputerName { get; }99 100        /// <summary>101        /// <para>102        /// CimInstance on which the current operation against.103        /// </para>104        /// </summary>105        /// <remarks>106        /// return value could be null107        /// </remarks>108        internal virtual CimInstance TargetCimInstance { get; }109    }110    #endregion111 112    #region Preprocessing of result object interface113    /// <summary>114    /// Defines a method to preprocessing an result object before sending to115    /// output pipeline.116    /// </summary>117    [ComVisible(false)]118    internal interface IObjectPreProcess119    {120        /// <summary>121        /// Performs pre processing of given result object.122        /// </summary>123        /// <param name="resultObject"></param>124        /// <returns>Pre-processed object.</returns>125        object Process(object resultObject);126    }127    #endregion128 129    #region Eventargs class130    /// <summary>131    /// <para>132    /// CmdletActionEventArgs holds a CimBaseAction object133    /// </para>134    /// </summary>135    internal sealed class CmdletActionEventArgs : EventArgs136    {137        /// <summary>138        /// Initializes a new instance of the <see cref="CmdletActionEventArgs"/> class.139        /// </summary>140        /// <param name="action">CimBaseAction object bound to the event.</param>141        public CmdletActionEventArgs(CimBaseAction action)142        {143            this.Action = action;144        }145 146        public readonly CimBaseAction Action;147    }148 149    /// <summary>150    /// OperationEventArgs holds a cancellation object, and an operation.151    /// </summary>152    internal sealed class OperationEventArgs : EventArgs153    {154        /// <summary>155        /// Initializes a new instance of the <see cref="OperationEventArgs"/> class.156        /// </summary>157        /// <param name="operationCancellation">Object used to cancel the operation.</param>158        /// <param name="operation">Async observable operation.</param>159        public OperationEventArgs(IDisposable operationCancellation,160            IObservable<object> operation,161            bool theSuccess)162        {163            this.operationCancellation = operationCancellation;164            this.operation = operation;165            this.success = theSuccess;166        }167 168        public readonly IDisposable operationCancellation;169        public readonly IObservable<object> operation;170        public readonly bool success;171    }172 173    #endregion174 175    /// <summary>176    /// <para>177    /// Wrapper of <see cref="CimSession"/> object.178    /// A CimSessionProxy object can only execute one operation at specific moment.179    /// </para>180    /// </summary>181    internal class CimSessionProxy : IDisposable182    {183        #region static members184 185        /// <summary>186        /// <para>187        /// global operation counter188        /// </para>189        /// </summary>190        private static long gOperationCounter = 0;191 192        /// <summary>193        /// Temporary CimSession cache lock.194        /// </summary>195        private static readonly object temporarySessionCacheLock = new();196 197        /// <summary>198        /// <para>temporary CimSession cache</para>199        /// <para>Temporary CimSession means the session is created by cimcmdlets,200        /// which is not created by <see cref="New-CimSession"/> cmdlet.201        /// Due to some cmdlet, such as <see cref="Remove-CimInstance"/>202        /// might need to split the operation into multiple stages, i.e., query203        /// CimInstance firstly, then remove the CimInstance resulted from query,204        /// such that the temporary CimSession need to be shared between205        /// multiple <see cref="CimSessionProxy"/> objects, introducing a206        /// temporary session cache is necessary to control the lifetime of the207        /// temporary CimSession objects.</para>208        /// <para>209        /// Once the reference count of the CimSession is decreased to 0,210        /// then call Dispose on it.211        /// </para>212        /// </summary>213        private static readonly Dictionary<CimSession, uint> temporarySessionCache = new();214 215        /// <summary>216        /// <para>217        /// Add <see cref="CimSession"/> to temporary cache.218        /// If CimSession already present in cache, then increase the refcount by 1,219        /// otherwise insert it into the cache.220        /// </para>221        /// </summary>222        /// <param name="session">CimSession to be added.</param>223        internal static void AddCimSessionToTemporaryCache(CimSession session)224        {225            if (session != null)226            {227                lock (temporarySessionCacheLock)228                {229                    if (temporarySessionCache.ContainsKey(session))230                    {231                        temporarySessionCache[session]++;232                        DebugHelper.WriteLogEx(@"Increase cimsession ref count {0}", 1, temporarySessionCache[session]);233                    }234                    else235                    {236                        temporarySessionCache.Add(session, 1);237                        DebugHelper.WriteLogEx(@"Add cimsession to cache. Ref count {0}", 1, temporarySessionCache[session]);238                    }239                }240            }241        }242 243        /// <summary>244        /// <para>Wrapper function to remove CimSession from cache</para>245        /// </summary>246        /// <param name="session"></param>247        /// <param name="dispose">Whether need to dispose the <see cref="CimSession"/> object.</param>248        private static void RemoveCimSessionFromTemporaryCache(CimSession session,249            bool dispose)250        {251            if (session != null)252            {253                bool removed = false;254                lock (temporarySessionCacheLock)255                {256                    if (temporarySessionCache.ContainsKey(session))257                    {258                        temporarySessionCache[session]--;259                        DebugHelper.WriteLogEx(@"Decrease cimsession ref count {0}", 1, temporarySessionCache[session]);260                        if (temporarySessionCache[session] == 0)261                        {262                            removed = true;263                            temporarySessionCache.Remove(session);264                        }265                    }266                }267                // there is a race condition that if268                // one thread is waiting to add CimSession to cache,269                // while current thread is removing the CimSession,270                // then invalid CimSession may be added to cache.271                // Ignored this scenario in CimCmdlet implementation,272                // since the code inside cimcmdlet will not hit this273                // scenario anyway.274                if (removed && dispose)275                {276                    DebugHelper.WriteLogEx(@"Dispose cimsession ", 1);277                    session.Dispose();278                }279            }280        }281 282        /// <summary>283        /// <para>284        /// Remove <see cref="CimSession"/> from temporary cache.285        /// If CimSession already present in cache, then decrease the refcount by 1,286        /// otherwise ignore.287        /// If refcount became 0, call dispose on the <see cref="CimSession"/> object.288        /// </para>289        /// </summary>290        /// <param name="session">CimSession to be added.</param>291        internal static void RemoveCimSessionFromTemporaryCache(CimSession session)292        {293            RemoveCimSessionFromTemporaryCache(session, true);294        }295        #endregion296 297        #region Event definitions298 299        /// <summary>300        /// Define an Event based on the NewActionHandler.301        /// </summary>302        public event EventHandler<CmdletActionEventArgs> OnNewCmdletAction;303 304        /// <summary>305        /// Event triggered when a new operation is started.306        /// </summary>307        public event EventHandler<OperationEventArgs> OnOperationCreated;308 309        /// <summary>310        /// Event triggered when a new operation is completed,311        /// either success or failed.312        /// </summary>313        public event EventHandler<OperationEventArgs> OnOperationDeleted;314 315        #endregion316 317        #region constructors318 319        /// <summary>320        /// Initializes a new instance of the <see cref="CimSessionProxy"/> class.321        /// </summary>322        /// <remarks>323        /// Then create wrapper object by given CimSessionProxy object.324        /// </remarks>325        /// <param name="computerName"></param>326        public CimSessionProxy(CimSessionProxy proxy)327        {328            DebugHelper.WriteLogEx("protocol = {0}", 1, proxy.Protocol);329 330            CreateSetSession(null, proxy.CimSession, null, proxy.OperationOptions, proxy.IsTemporaryCimSession);331            this.Protocol = proxy.Protocol;332            this.OperationTimeout = proxy.OperationTimeout;333            this.isDefaultSession = proxy.isDefaultSession;334        }335 336        /// <summary>337        /// Initializes a new instance of the <see cref="CimSessionProxy"/> class.338        /// </summary>339        /// <remarks>340        /// Create <see cref="CimSession"/> by given computer name.341        /// Then create wrapper object.342        /// </remarks>343        /// <param name="computerName"></param>344        public CimSessionProxy(string computerName)345        {346            CreateSetSession(computerName, null, null, null, false);347            this.isDefaultSession = computerName == ConstValue.NullComputerName;348        }349 350        /// <summary>351        /// Initializes a new instance of the <see cref="CimSessionProxy"/> class.352        /// </summary>353        /// <remarks>354        /// Create <see cref="CimSession"/> by given computer name355        /// and session options.356        /// Then create wrapper object.357        /// </remarks>358        /// <param name="computerName"></param>359        /// <param name="sessionOptions"></param>360        public CimSessionProxy(string computerName, CimSessionOptions sessionOptions)361        {362            CreateSetSession(computerName, null, sessionOptions, null, false);363            this.isDefaultSession = computerName == ConstValue.NullComputerName;364        }365 366        /// <summary>367        /// Initializes a new instance of the <see cref="CimSessionProxy"/> class.368        /// </summary>369        /// <remarks>370        /// Create <see cref="CimSession"/> by given computer name371        /// and cimInstance. Then create wrapper object.372        /// </remarks>373        /// <param name="computerName"></param>374        /// <param name="cimInstance"></param>375        public CimSessionProxy(string computerName, CimInstance cimInstance)376        {377            DebugHelper.WriteLogEx("ComputerName {0}; cimInstance.CimSessionInstanceID = {1}; cimInstance.CimSessionComputerName = {2}.",378                0,379                computerName,380                cimInstance.GetCimSessionInstanceId(),381                cimInstance.GetCimSessionComputerName());382 383            if (computerName != ConstValue.NullComputerName)384            {385                CreateSetSession(computerName, null, null, null, false);386                return;387            }388 389            Debug.Assert(cimInstance != null, "Caller should verify cimInstance != null");390 391            // computerName is null, fallback to create session from cimInstance392            CimSessionState state = CimSessionBase.GetCimSessionState();393            if (state != null)394            {395                CimSession session = state.QuerySession(cimInstance.GetCimSessionInstanceId());396                if (session != null)397                {398                    DebugHelper.WriteLogEx("Found the session from cache with InstanceID={0}.", 0, cimInstance.GetCimSessionInstanceId());399                    CreateSetSession(null, session, null, null, false);400                    return;401                }402            }403 404            string cimsessionComputerName = cimInstance.GetCimSessionComputerName();405            CreateSetSession(cimsessionComputerName, null, null, null, false);406            this.isDefaultSession = cimsessionComputerName == ConstValue.NullComputerName;407 408            DebugHelper.WriteLogEx("Create a temp session with computerName = {0}.", 0, cimsessionComputerName);409        }410 411        /// <summary>412        /// Initializes a new instance of the <see cref="CimSessionProxy"/> class.413        /// </summary>414        /// <remarks>415        /// Create <see cref="CimSession"/> by given computer name,416        /// session options.417        /// </remarks>418        /// <param name="computerName"></param>419        /// <param name="sessionOptions"></param>420        /// <param name="operOptions">Used when create async operation.</param>421        public CimSessionProxy(string computerName, CimSessionOptions sessionOptions, CimOperationOptions operOptions)422        {423            CreateSetSession(computerName, null, sessionOptions, operOptions, false);424            this.isDefaultSession = computerName == ConstValue.NullComputerName;425        }426 427        /// <summary>428        /// Initializes a new instance of the <see cref="CimSessionProxy"/> class.429        /// </summary>430        /// <remarks>431        /// Create <see cref="CimSession"/> by given computer name.432        /// Then create wrapper object.433        /// </remarks>434        /// <param name="computerName"></param>435        /// <param name="operOptions">Used when create async operation.</param>436        public CimSessionProxy(string computerName, CimOperationOptions operOptions)437        {438            CreateSetSession(computerName, null, null, operOptions, false);439            this.isDefaultSession = computerName == ConstValue.NullComputerName;440        }441 442        /// <summary>443        /// Initializes a new instance of the <see cref="CimSessionProxy"/> class.444        /// </summary>445        /// <remarks>446        /// Create wrapper object by given session object.447        /// </remarks>448        /// <param name="session"></param>449        public CimSessionProxy(CimSession session)450        {451            CreateSetSession(null, session, null, null, false);452        }453 454        /// <summary>455        /// Initializes a new instance of the <see cref="CimSessionProxy"/> class.456        /// </summary>457        /// <remarks>458        /// Create wrapper object by given session object.459        /// </remarks>460        /// <param name="session"></param>461        /// <param name="operOptions">Used when create async operation.</param>462        public CimSessionProxy(CimSession session, CimOperationOptions operOptions)463        {464            CreateSetSession(null, session, null, operOptions, false);465        }466 467        /// <summary>468        /// Initialize CimSessionProxy object.469        /// </summary>470        /// <param name="computerName"></param>471        /// <param name="session"></param>472        /// <param name="sessionOptions"></param>473        /// <param name="options"></param>474        private void CreateSetSession(475            string computerName,476            CimSession cimSession,477            CimSessionOptions sessionOptions,478            CimOperationOptions operOptions,479            bool temporaryCimSession)480        {481            DebugHelper.WriteLogEx("computername {0}; cimsession {1}; sessionOptions {2}; operationOptions {3}.", 0, computerName, cimSession, sessionOptions, operOptions);482 483            lock (this.stateLock)484            {485                this.CancelOperation = null;486                this.operation = null;487            }488 489            InitOption(operOptions);490            this.Protocol = ProtocolType.Wsman;491            this.IsTemporaryCimSession = temporaryCimSession;492 493            if (cimSession != null)494            {495                this.CimSession = cimSession;496                CimSessionState state = CimSessionBase.GetCimSessionState();497                if (state != null)498                {499                    CimSessionWrapper wrapper = state.QuerySession(cimSession);500                    if (wrapper != null)501                    {502                        this.Protocol = wrapper.GetProtocolType();503                    }504                }505            }506            else507            {508                if (sessionOptions != null)509                {510                    if (sessionOptions is DComSessionOptions)511                    {512                        string defaultComputerName = ConstValue.IsDefaultComputerName(computerName) ? ConstValue.NullComputerName : computerName;513                        this.CimSession = CimSession.Create(defaultComputerName, sessionOptions);514                        this.Protocol = ProtocolType.Dcom;515                    }516                    else517                    {518                        this.CimSession = CimSession.Create(computerName, sessionOptions);519                    }520                }521                else522                {523                    this.CimSession = CreateCimSessionByComputerName(computerName);524                }525 526                this.IsTemporaryCimSession = true;527            }528 529            if (this.IsTemporaryCimSession)530            {531                AddCimSessionToTemporaryCache(this.CimSession);532            }533 534            this.invocationContextObject = new InvocationContext(this);535            DebugHelper.WriteLog("Protocol {0}, Is temporary session ? {1}", 1, this.Protocol, this.IsTemporaryCimSession);536        }537 538        #endregion539 540        #region set operation options541 542        /// <summary>543        /// Gets or sets a value indicating whether to retrieve localized information for the CIM class.544        /// </summary>545        public bool Amended546        {547            get => OperationOptions.Flags.HasFlag(CimOperationFlags.LocalizedQualifiers);548 549            set550            {551                if (value)552                {553                    OperationOptions.Flags |= CimOperationFlags.LocalizedQualifiers;554                }555                else556                {557                    OperationOptions.Flags &= ~CimOperationFlags.LocalizedQualifiers;558                }559            }560        }561 562        /// <summary>563        /// Set timeout value (seconds) of the operation.564        /// </summary>565        public uint OperationTimeout566        {567            get568            {569                return (uint)this.OperationOptions.Timeout.TotalSeconds;570            }571 572            set573            {574                DebugHelper.WriteLogEx("OperationTimeout {0},", 0, value);575 576                this.OperationOptions.Timeout = TimeSpan.FromSeconds((double)value);577            }578        }579 580        /// <summary>581        /// Set resource URI of the operation.582        /// </summary>583        public Uri ResourceUri584        {585            get586            {587                return this.OperationOptions.ResourceUri;588            }589 590            set591            {592                DebugHelper.WriteLogEx("ResourceUri {0},", 0, value);593 594                this.OperationOptions.ResourceUri = value;595            }596        }597 598        /// <summary>599        /// Enable/Disable the method result streaming,600        /// it is enabled by default.601        /// </summary>602        public bool EnableMethodResultStreaming603        {604            get605            {606                return this.OperationOptions.EnableMethodResultStreaming;607            }608 609            set610            {611                DebugHelper.WriteLogEx("EnableMethodResultStreaming {0}", 0, value);612                this.OperationOptions.EnableMethodResultStreaming = value;613            }614        }615 616        /// <summary>617        /// Enable/Disable prompt user streaming,618        /// it is enabled by default.619        /// </summary>620        public bool EnablePromptUser621        {622            set623            {624                DebugHelper.WriteLogEx("EnablePromptUser {0}", 0, value);625                if (value)626                {627                    this.OperationOptions.PromptUser = this.PromptUser;628                }629            }630        }631 632        /// <summary>633        /// Enable the pssemantics.634        /// </summary>635        private void EnablePSSemantics()636        {637            DebugHelper.WriteLogEx();638 639            // this.options.PromptUserForceFlag...640            // this.options.WriteErrorMode641            this.OperationOptions.WriteErrorMode = CimCallbackMode.Inquire;642 643            // !!!NOTES: Does not subscribe to PromptUser for CimCmdlets now644            // since cmdlet does not provider an approach645            // to let user select how to handle prompt message646            // this can be enabled later if needed.647            this.OperationOptions.WriteError = this.WriteError;648            this.OperationOptions.WriteMessage = this.WriteMessage;649            this.OperationOptions.WriteProgress = this.WriteProgress;650        }651 652        /// <summary>653        /// Set keyonly property.654        /// </summary>655        public SwitchParameter KeyOnly656        {657            set { this.OperationOptions.KeysOnly = value.IsPresent; }658        }659 660        /// <summary>661        /// Set Shallow flag.662        /// </summary>663        public SwitchParameter Shallow664        {665            set666            {667                if (value.IsPresent)668                {669                    this.OperationOptions.Flags = CimOperationFlags.PolymorphismShallow;670                }671                else672                {673                    this.OperationOptions.Flags = CimOperationFlags.None;674                }675            }676        }677 678        /// <summary>679        /// Initialize the operation option.680        /// </summary>681        private void InitOption(CimOperationOptions operOptions)682        {683            DebugHelper.WriteLogEx();684 685            if (operOptions != null)686            {687                this.OperationOptions = new CimOperationOptions(operOptions);688            }689            else690            {691                this.OperationOptions ??= new CimOperationOptions();692            }693 694            this.EnableMethodResultStreaming = true;695            this.EnablePSSemantics();696        }697 698        #endregion699 700        #region misc operations701 702        /// <summary>703        /// Caller call Detach to retrieve the session704        /// object and control the lifecycle of the CimSession object.705        /// </summary>706        /// <returns></returns>707        public CimSession Detach()708        {709            DebugHelper.WriteLogEx();710 711            // Remove the CimSession from cache but don't dispose it712            RemoveCimSessionFromTemporaryCache(this.CimSession, false);713            CimSession sessionToReturn = this.CimSession;714            this.CimSession = null;715            this.IsTemporaryCimSession = false;716            return sessionToReturn;717        }718 719        /// <summary>720        /// Add a new operation to cache.721        /// </summary>722        /// <param name="operation"></param>723        /// <param name="cancelObject"></param>724        private void AddOperation(IObservable<object> operation)725        {726            DebugHelper.WriteLogEx();727 728            lock (this.stateLock)729            {730                Debug.Assert(this.Completed, "Caller should verify that there is no operation in progress");731                this.operation = operation;732            }733        }734 735        /// <summary>736        /// Remove object from cache.737        /// </summary>738        /// <param name="operation"></param>739        private void RemoveOperation(IObservable<object> operation)740        {741            DebugHelper.WriteLogEx();742 743            lock (this.stateLock)744            {745                Debug.Assert(this.operation == operation, "Caller should verify that the operation to remove is the operation in progress");746 747                this.DisposeCancelOperation();748 749                if (this.operation != null)750                {751                    this.operation = null;752                }753 754                if (this.CimSession != null && this.ContextObject == null)755                {756                    DebugHelper.WriteLog("Dispose this proxy object @ RemoveOperation");757                    this.Dispose();758                }759            }760        }761 762        /// <summary>763        /// <para>764        /// Trigger an event that new action available765        /// </para>766        /// </summary>767        /// <param name="action"></param>768        protected void FireNewActionEvent(CimBaseAction action)769        {770            DebugHelper.WriteLogEx();771 772            CmdletActionEventArgs actionArgs = new(action);773            if (!PreNewActionEvent(actionArgs))774            {775                return;776            }777 778            EventHandler<CmdletActionEventArgs> temp = this.OnNewCmdletAction;779            if (temp != null)780            {781                temp(this.CimSession, actionArgs);782            }783            else784            {785                DebugHelper.WriteLog("Ignore action since OnNewCmdletAction is null.", 5);786            }787 788            this.PostNewActionEvent(actionArgs);789        }790 791        /// <summary>792        /// <para>793        /// Trigger an event that new operation is created794        /// </para>795        /// </summary>796        /// <param name="cancelOperation"></param>797        /// <param name="operation"></param>798        private void FireOperationCreatedEvent(799            IDisposable cancelOperation,800            IObservable<object> operation)801        {802            DebugHelper.WriteLogEx();803 804            OperationEventArgs args = new(805                cancelOperation, operation, false);806            this.OnOperationCreated?.Invoke(this.CimSession, args);807 808            this.PostOperationCreateEvent(args);809        }810 811        /// <summary>812        /// <para>813        /// Trigger an event that an operation is deleted814        /// </para>815        /// </summary>816        /// <param name="operation"></param>817        private void FireOperationDeletedEvent(818            IObservable<object> operation,819            bool success)820        {821            DebugHelper.WriteLogEx();822            this.WriteOperationCompleteMessage(this.operationName);823            OperationEventArgs args = new(824                null, operation, success);825            PreOperationDeleteEvent(args);826            this.OnOperationDeleted?.Invoke(this.CimSession, args);827 828            this.PostOperationDeleteEvent(args);829            this.RemoveOperation(operation);830            this.operationName = null;831        }832 833        #endregion834 835        #region PSExtension callback functions836 837        /// <summary>838        /// <para>839        /// WriteMessage callback840        /// </para>841        /// </summary>842        /// <param name="channel"></param>843        /// <param name="message"></param>844        internal void WriteMessage(uint channel, string message)845        {846            DebugHelper.WriteLogEx("Channel = {0} message = {1}", 0, channel, message);847            try848            {849                CimWriteMessage action = new(channel, message);850                this.FireNewActionEvent(action);851            }852            catch (Exception ex)853            {854                DebugHelper.WriteLogEx("{0}", 0, ex);855            }856        }857 858        /// <summary>859        /// <para>860        /// Write operation start verbose message861        /// </para>862        /// </summary>863        /// <param name="operation"></param>864        /// <param name="parameters"></param>865        internal void WriteOperationStartMessage(string operation, Hashtable parameterList)866        {867            DebugHelper.WriteLogEx();868            StringBuilder parameters = new();869            if (parameterList != null)870            {871                foreach (string key in parameterList.Keys)872                {873                    if (parameters.Length > 0)874                    {875                        parameters.Append(',');876                    }877 878                    parameters.Append(CultureInfo.CurrentUICulture, $@"'{key}' = {parameterList[key]}");879                }880            }881 882            string operationStartMessage = string.Format(CultureInfo.CurrentUICulture,883                CimCmdletStrings.CimOperationStart,884                operation,885                (parameters.Length == 0) ? "null" : parameters.ToString());886            WriteMessage((uint)CimWriteMessageChannel.Verbose, operationStartMessage);887        }888 889        /// <summary>890        /// <para>891        /// Write operation complete verbose message892        /// </para>893        /// </summary>894        /// <param name="operation"></param>895        internal void WriteOperationCompleteMessage(string operation)896        {897            DebugHelper.WriteLogEx();898            string operationCompleteMessage = string.Format(CultureInfo.CurrentUICulture,899                CimCmdletStrings.CimOperationCompleted,900                operation);901            WriteMessage((uint)CimWriteMessageChannel.Verbose, operationCompleteMessage);902        }903 904        /// <summary>905        /// <para>906        /// WriteProgress callback907        /// </para>908        /// </summary>909        /// <param name="activity"></param>910        /// <param name="currentOperation"></param>911        /// <param name="statusDescription"></param>912        /// <param name="percentageCompleted"></param>913        /// <param name="secondsRemaining"></param>914        public void WriteProgress(string activity,915            string currentOperation,916            string statusDescription,917            uint percentageCompleted,918            uint secondsRemaining)919        {920            DebugHelper.WriteLogEx("activity:{0}; currentOperation:{1}; percentageCompleted:{2}; secondsRemaining:{3}",921                0, activity, currentOperation, percentageCompleted, secondsRemaining);922 923            try924            {925                CimWriteProgress action = new(926                    activity,927                    (int)this.operationID,928                    currentOperation,929                    statusDescription,930                    percentageCompleted,931                    secondsRemaining);932                this.FireNewActionEvent(action);933            }934            catch (Exception ex)935            {936                DebugHelper.WriteLogEx("{0}", 0, ex);937            }938        }939 940        /// <summary>941        /// <para>942        /// WriteError callback943        /// </para>944        /// </summary>945        /// <param name="instance"></param>946        /// <returns></returns>947        public CimResponseType WriteError(CimInstance instance)948        {949            DebugHelper.WriteLogEx("Error:{0}", 0, instance);950            try951            {952                CimWriteError action = new(instance, this.invocationContextObject);953                this.FireNewActionEvent(action);954                return action.GetResponse();955            }956            catch (Exception ex)957            {958                DebugHelper.WriteLogEx("{0}", 0, ex);959                return CimResponseType.NoToAll;960            }961        }962 963        /// <summary>964        /// PromptUser callback.965        /// </summary>966        /// <param name="message"></param>967        /// <param name="prompt"></param>968        /// <returns></returns>969        public CimResponseType PromptUser(string message, CimPromptType prompt)970        {971            DebugHelper.WriteLogEx("message:{0} prompt:{1}", 0, message, prompt);972            try973            {974                CimPromptUser action = new(message, prompt);975                this.FireNewActionEvent(action);976                return action.GetResponse();977            }978            catch (Exception ex)979            {980                DebugHelper.WriteLogEx("{0}", 0, ex);981                return CimResponseType.NoToAll;982            }983        }984        #endregion985 986        #region Async result handler987 988        /// <summary>989        /// <para>990        /// Handle async event triggered by <see cref="CimResultObserver{T}"/>991        /// </para>992        /// </summary>993        /// <param name="observer">Object triggered the event.</param>994        /// <param name="resultArgs">Async result event argument.</param>995        internal void ResultEventHandler(996            object observer,997            AsyncResultEventArgsBase resultArgs)998        {999            DebugHelper.WriteLogEx();1000            switch (resultArgs.resultType)1001            {1002                case AsyncResultType.Completion:1003                    {1004                        DebugHelper.WriteLog("ResultEventHandler::Completion", 4);1005 1006                        AsyncResultCompleteEventArgs args = resultArgs as AsyncResultCompleteEventArgs;1007                        this.FireOperationDeletedEvent(args.observable, true);1008                    }1009 1010                    break;1011                case AsyncResultType.Exception:1012                    {1013                        AsyncResultErrorEventArgs args = resultArgs as AsyncResultErrorEventArgs;1014                        DebugHelper.WriteLog("ResultEventHandler::Exception {0}", 4, args.error);1015 1016                        using (CimWriteError action = new(args.error, this.invocationContextObject, args.context))1017                        {1018                            this.FireNewActionEvent(action);1019                        }1020 1021                        this.FireOperationDeletedEvent(args.observable, false);1022                    }1023 1024                    break;1025                case AsyncResultType.Result:1026                    {1027                        AsyncResultObjectEventArgs args = resultArgs as AsyncResultObjectEventArgs;1028                        DebugHelper.WriteLog("ResultEventHandler::Result {0}", 4, args.resultObject);1029                        object resultObject = args.resultObject;1030                        if (!this.isDefaultSession)1031                        {1032                            AddShowComputerNameMarker(resultObject);1033                        }1034 1035                        if (this.ObjectPreProcess != null)1036                        {1037                            resultObject = this.ObjectPreProcess.Process(resultObject);1038                        }1039#if DEBUG1040                        resultObject = PostProcessCimInstance(resultObject);1041#endif1042                        CimWriteResultObject action = new(resultObject, this.ContextObject);1043                        this.FireNewActionEvent(action);1044                    }1045 1046                    break;1047                default:1048                    break;1049            }1050        }1051 1052        /// <summary>1053        /// This method adds a note property to <paramref name="o"/>,1054        /// which will cause the default PowerShell formatting and output1055        /// to include PSComputerName column/property in the display.1056        /// </summary>1057        /// <param name="o"></param>1058        private static void AddShowComputerNameMarker(object o)1059        {1060            if (o == null)1061            {1062                return;1063            }1064 1065            PSObject pso = PSObject.AsPSObject(o);1066            if (pso.BaseObject is not CimInstance)1067            {1068                return;1069            }1070 1071            PSNoteProperty psShowComputerNameProperty = new(ConstValue.ShowComputerNameNoteProperty, true);1072            pso.Members.Add(psShowComputerNameProperty);1073        }1074 1075#if DEBUG1076        private static readonly bool isCliXmlTestabilityHookActive = GetIsCliXmlTestabilityHookActive();1077 1078        private static bool GetIsCliXmlTestabilityHookActive()1079        {1080            return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CDXML_CLIXML_TEST"));1081        }1082 1083        private static object PostProcessCimInstance(object resultObject)1084        {1085            DebugHelper.WriteLogEx();1086            if (isCliXmlTestabilityHookActive && (resultObject is CimInstance))1087            {1088                string serializedForm = PSSerializer.Serialize(resultObject as CimInstance, depth: 1);1089                object deserializedObject = PSSerializer.Deserialize(serializedForm);1090                object returnObject = (deserializedObject is PSObject) ? (deserializedObject as PSObject).BaseObject : deserializedObject;1091                DebugHelper.WriteLogEx("Deserialized object is {0}, type {1}", 1, returnObject, returnObject.GetType());1092                return returnObject;1093            }1094 1095            return resultObject;1096        }1097#endif1098        #endregion1099 1100        #region Async operations1101 1102        /// <summary>1103        /// <para>1104        /// create a cim instance asynchronously1105        /// </para>1106        /// </summary>1107        /// <param name="namespaceName"></param>1108        /// <param name="instance"></param>1109        public void CreateInstanceAsync(string namespaceName, CimInstance instance)1110        {1111            Debug.Assert(instance != null, "Caller should verify that instance != NULL.");1112            DebugHelper.WriteLogEx("EnableMethodResultStreaming = {0}", 0, this.OperationOptions.EnableMethodResultStreaming);1113            this.CheckAvailability();1114            this.TargetCimInstance = instance;1115            this.operationName = CimCmdletStrings.CimOperationNameCreateInstance;1116            this.operationParameters.Clear();1117            this.operationParameters.Add(@"namespaceName", namespaceName);1118            this.operationParameters.Add(@"instance", instance);1119            this.WriteOperationStartMessage(this.operationName, this.operationParameters);1120            CimAsyncResult<CimInstance> asyncResult = this.CimSession.CreateInstanceAsync(namespaceName, instance, this.OperationOptions);1121            ConsumeCimInstanceAsync(asyncResult, new CimResultContext(instance));1122        }1123 1124        /// <summary>1125        /// Delete a cim instance asynchronously.1126        /// </summary>1127        /// <param name="namespaceName"></param>1128        /// <param name="instance"></param>1129        public void DeleteInstanceAsync(string namespaceName, CimInstance instance)1130        {1131            Debug.Assert(instance != null, "Caller should verify that instance != NULL.");1132            DebugHelper.WriteLogEx("namespace = {0}; classname = {1};", 0, namespaceName, instance.CimSystemProperties.ClassName);1133            this.CheckAvailability();1134            this.TargetCimInstance = instance;1135            this.operationName = CimCmdletStrings.CimOperationNameDeleteInstance;1136            this.operationParameters.Clear();1137            this.operationParameters.Add(@"namespaceName", namespaceName);1138            this.operationParameters.Add(@"instance", instance);1139            this.WriteOperationStartMessage(this.operationName, this.operationParameters);1140            CimAsyncStatus asyncResult = this.CimSession.DeleteInstanceAsync(namespaceName, instance, this.OperationOptions);1141            ConsumeObjectAsync(asyncResult, new CimResultContext(instance));1142        }1143 1144        /// <summary>1145        /// Get cim instance asynchronously.1146        /// </summary>1147        /// <param name="namespaceName"></param>1148        /// <param name="instanceId"></param>1149        public void GetInstanceAsync(string namespaceName, CimInstance instance)1150        {1151            Debug.Assert(instance != null, "Caller should verify that instance != NULL.");1152            DebugHelper.WriteLogEx("namespace = {0}; classname = {1}; keyonly = {2}", 0, namespaceName, instance.CimSystemProperties.ClassName, this.OperationOptions.KeysOnly);1153            this.CheckAvailability();1154            this.TargetCimInstance = instance;1155            this.operationName = CimCmdletStrings.CimOperationNameGetInstance;1156            this.operationParameters.Clear();1157            this.operationParameters.Add(@"namespaceName", namespaceName);1158            this.operationParameters.Add(@"instance", instance);1159            this.WriteOperationStartMessage(this.operationName, this.operationParameters);1160            CimAsyncResult<CimInstance> asyncResult = this.CimSession.GetInstanceAsync(namespaceName, instance, this.OperationOptions);1161            ConsumeCimInstanceAsync(asyncResult, new CimResultContext(instance));1162        }1163 1164        /// <summary>1165        /// Modify cim instance asynchronously.1166        /// </summary>1167        /// <param name="namespaceName"></param>1168        /// <param name="instance"></param>1169        public void ModifyInstanceAsync(string namespaceName, CimInstance instance)1170        {1171            Debug.Assert(instance != null, "Caller should verify that instance != NULL.");1172            DebugHelper.WriteLogEx("namespace = {0}; classname = {1}", 0, namespaceName, instance.CimSystemProperties.ClassName);1173            this.CheckAvailability();1174            this.TargetCimInstance = instance;1175            this.operationName = CimCmdletStrings.CimOperationNameModifyInstance;1176            this.operationParameters.Clear();1177            this.operationParameters.Add(@"namespaceName", namespaceName);1178            this.operationParameters.Add(@"instance", instance);1179            this.WriteOperationStartMessage(this.operationName, this.operationParameters);1180            CimAsyncResult<CimInstance> asyncResult = this.CimSession.ModifyInstanceAsync(namespaceName, instance, this.OperationOptions);1181            ConsumeObjectAsync(asyncResult, new CimResultContext(instance));1182        }1183 1184        /// <summary>1185        /// Enumerate cim instance associated with the1186        /// given instance asynchronously.1187        /// </summary>1188        /// <param name="namespaceName"></param>1189        /// <param name="sourceInstance"></param>1190        /// <param name="associationClassName"></param>1191        /// <param name="resultClassName"></param>1192        /// <param name="sourceRole"></param>1193        /// <param name="resultRole"></param>1194        public void EnumerateAssociatedInstancesAsync(1195            string namespaceName,1196            CimInstance sourceInstance,1197            string associationClassName,1198            string resultClassName,1199            string sourceRole,1200            string resultRole)

Showing the first 1,200 of 2314 lines. Download the file for the rest.