Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
psstreamobject.cs509 linesDownload Raw Back to common
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Management.Automation.Runspaces;5using System.Text;6using System.Threading;7 8using Dbg = System.Management.Automation.Diagnostics;9 10namespace System.Management.Automation.Remoting.Internal11{12    /// <summary>13    /// PSStreamObjectType is for internal (PowerShell) consumption and should not be treated as a public API.14    /// </summary>15    public enum PSStreamObjectType16    {17        /// <summary>18        /// </summary>19        Output = 1,20 21        /// <summary>22        /// </summary>23        Error = 2,24 25        /// <summary>26        /// </summary>27        MethodExecutor = 3,28 29        /// <summary>30        /// </summary>31        Warning = 4,32 33        /// <summary>34        /// </summary>35        BlockingError = 5,36 37        /// <summary>38        /// </summary>39        ShouldMethod = 6,40 41        /// <summary>42        /// </summary>43        WarningRecord = 7,44 45        /// <summary>46        /// </summary>47        Debug = 8,48 49        /// <summary>50        /// </summary>51        Progress = 9,52 53        /// <summary>54        /// </summary>55        Verbose = 10,56 57        /// <summary>58        /// </summary>59        Information = 11,60 61        /// <summary>62        /// </summary>63        Exception = 12,64    }65 66    /// <summary>67    /// Struct which describes whether an object written68    /// to an ObjectStream is of type - output, error,69    /// verbose, debug.70    /// PSStreamObject is for internal (PowerShell) consumption71    /// and should not be treated as a public API.72    /// </summary>73    public class PSStreamObject74    {75        /// <summary>76        /// </summary>77        public PSStreamObjectType ObjectType { get; set; }78 79        internal object Value { get; set; }80 81        internal Guid Id { get; set; }82 83        internal PSStreamObject(PSStreamObjectType objectType, object value, Guid id)84        {85            ObjectType = objectType;86            Value = value;87            Id = id;88        }89 90        /// <summary>91        /// </summary>92        /// <param name="objectType"></param>93        /// <param name="value"></param>94        public PSStreamObject(PSStreamObjectType objectType, object value)95            : this(objectType, value, Guid.Empty)96        {97        }98 99        /// <summary>100        /// Handle the object obtained from an ObjectStream's reader101        /// based on its type.102        /// </summary>103        /// <param name="cmdlet">Cmdlet to use for outputting the object.</param>104        /// <param name="overrideInquire">Used by Receive-Job to suppress inquire preference.</param>105        public void WriteStreamObject(Cmdlet cmdlet, bool overrideInquire = false)106        {107            if (cmdlet != null)108            {109                switch (this.ObjectType)110                {111                    case PSStreamObjectType.Output:112                        {113                            cmdlet.WriteObject(this.Value);114                        }115 116                        break;117 118                    case PSStreamObjectType.Error:119                        {120                            ErrorRecord errorRecord = (ErrorRecord)this.Value;121                            errorRecord.PreserveInvocationInfoOnce = true;122                            MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;123                            mshCommandRuntime?.WriteError(errorRecord, overrideInquire);124                        }125 126                        break;127 128                    case PSStreamObjectType.Debug:129                        {130                            string debug = (string)Value;131                            DebugRecord debugRecord = new DebugRecord(debug);132                            MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;133                            mshCommandRuntime?.WriteDebug(debugRecord, overrideInquire);134                        }135 136                        break;137 138                    case PSStreamObjectType.Warning:139                        {140                            string warning = (string)Value;141                            WarningRecord warningRecord = new WarningRecord(warning);142                            MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;143                            mshCommandRuntime?.WriteWarning(warningRecord, overrideInquire);144                        }145 146                        break;147 148                    case PSStreamObjectType.Verbose:149                        {150                            string verbose = (string)Value;151                            VerboseRecord verboseRecord = new VerboseRecord(verbose);152                            MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;153                            mshCommandRuntime?.WriteVerbose(verboseRecord, overrideInquire);154                        }155 156                        break;157 158                    case PSStreamObjectType.Progress:159                        {160                            MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;161                            mshCommandRuntime?.WriteProgress((ProgressRecord)Value, overrideInquire);162                        }163 164                        break;165 166                    case PSStreamObjectType.Information:167                        {168                            MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;169                            mshCommandRuntime?.WriteInformation((InformationRecord)Value, overrideInquire);170                        }171 172                        break;173 174                    case PSStreamObjectType.WarningRecord:175                        {176                            WarningRecord warningRecord = (WarningRecord)Value;177                            MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;178                            mshCommandRuntime?.AppendWarningVarList(warningRecord);179                        }180 181                        break;182 183                    case PSStreamObjectType.MethodExecutor:184                        {185                            Dbg.Assert(this.Value is ClientMethodExecutor,186                                       "Expected psstreamObject.value is ClientMethodExecutor");187                            ClientMethodExecutor methodExecutor = (ClientMethodExecutor)Value;188                            methodExecutor.Execute(cmdlet);189                        }190 191                        break;192 193                    case PSStreamObjectType.BlockingError:194                        {195                            CmdletMethodInvoker<object> methodInvoker = (CmdletMethodInvoker<object>)Value;196                            InvokeCmdletMethodAndWaitForResults(methodInvoker, cmdlet);197                        }198 199                        break;200 201                    case PSStreamObjectType.ShouldMethod:202                        {203                            CmdletMethodInvoker<bool> methodInvoker = (CmdletMethodInvoker<bool>)Value;204                            InvokeCmdletMethodAndWaitForResults(methodInvoker, cmdlet);205                        }206 207                        break;208 209                    case PSStreamObjectType.Exception:210                        {211                            Exception e = (Exception)Value;212                            throw e;213                        }214                }215            }216            else if (ObjectType == PSStreamObjectType.Exception)217            {218                Exception e = (Exception)Value;219                throw e;220            }221        }222 223        private static void GetIdentifierInfo(string message, out Guid jobInstanceId, out string computerName)224        {225            jobInstanceId = Guid.Empty;226            computerName = string.Empty;227 228            if (message == null)229            {230                return;231            }232 233            string[] parts = message.Split(':', 3);234 235            if (parts.Length != 3)236            {237                return;238            }239 240            if (!Guid.TryParse(parts[0], out jobInstanceId))241            {242                jobInstanceId = Guid.Empty;243            }244 245            computerName = parts[1];246        }247 248        /// <summary>249        /// Handle the object obtained from an ObjectStream's reader250        /// based on its type.251        /// </summary>252        /// <param name="cmdlet">Cmdlet to use for outputting the object.</param>253        /// <param name="instanceId"></param>254        /// <param name="overrideInquire">Suppresses prompt on messages with Inquire preference.255        /// Needed for Receive-Job</param>256        internal void WriteStreamObject(Cmdlet cmdlet, Guid instanceId, bool overrideInquire = false)257        {258            switch (ObjectType)259            {260                case PSStreamObjectType.Output:261                    {262                        if (instanceId != Guid.Empty)263                        {264                            PSObject o = Value as PSObject;265                            if (o != null)266                                AddSourceJobNoteProperty(o, instanceId);267                        }268 269                        cmdlet.WriteObject(Value);270                    }271 272                    break;273 274                case PSStreamObjectType.Error:275                    {276                        ErrorRecord errorRecord = (ErrorRecord)this.Value;277                        RemotingErrorRecord remoteErrorRecord = errorRecord as RemotingErrorRecord;278 279                        if (remoteErrorRecord == null)280                        {281                            // if we get a base ErrorRecord object, check if the computerName is282                            // populated in the RecommendedAction field283                            if (errorRecord.ErrorDetails != null && !string.IsNullOrEmpty(errorRecord.ErrorDetails.RecommendedAction))284                            {285                                string computerName;286                                Guid jobInstanceId;287                                GetIdentifierInfo(errorRecord.ErrorDetails.RecommendedAction,288                                                  out jobInstanceId, out computerName);289 290                                errorRecord = new RemotingErrorRecord(errorRecord,291                                                                      new OriginInfo(computerName, Guid.Empty,292                                                                                     jobInstanceId));293                            }294                        }295                        else296                        {297                            errorRecord = remoteErrorRecord;298                        }299 300                        errorRecord.PreserveInvocationInfoOnce = true;301                        MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;302                        mshCommandRuntime?.WriteError(errorRecord, overrideInquire);303                    }304 305                    break;306 307                case PSStreamObjectType.Warning:308                    {309                        string warning = (string)Value;310                        WarningRecord warningRecord = new WarningRecord(warning);311                        MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;312                        mshCommandRuntime?.WriteWarning(warningRecord, overrideInquire);313                    }314 315                    break;316 317                case PSStreamObjectType.Verbose:318                    {319                        string verbose = (string)Value;320                        VerboseRecord verboseRecord = new VerboseRecord(verbose);321                        MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;322                        mshCommandRuntime?.WriteVerbose(verboseRecord, overrideInquire);323                    }324 325                    break;326 327                case PSStreamObjectType.Progress:328                    {329                        ProgressRecord progressRecord = (ProgressRecord)Value;330 331                        RemotingProgressRecord remotingProgressRecord = progressRecord as RemotingProgressRecord;332                        if (remotingProgressRecord == null)333                        {334                            Guid jobInstanceId;335                            string computerName;336                            GetIdentifierInfo(progressRecord.CurrentOperation, out jobInstanceId,337                                              out computerName);338                            OriginInfo info = new OriginInfo(computerName, Guid.Empty, jobInstanceId);339                            progressRecord = new RemotingProgressRecord(progressRecord, info);340                        }341                        else342                        {343                            progressRecord = remotingProgressRecord;344                        }345 346                        MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;347                        mshCommandRuntime?.WriteProgress(progressRecord, overrideInquire);348                    }349 350                    break;351 352                case PSStreamObjectType.Debug:353                    {354                        string debug = (string)Value;355                        DebugRecord debugRecord = new DebugRecord(debug);356                        MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;357                        mshCommandRuntime?.WriteDebug(debugRecord, overrideInquire);358                    }359 360                    break;361 362                case PSStreamObjectType.Information:363                    {364                        InformationRecord informationRecord = (InformationRecord)this.Value;365                        RemotingInformationRecord remoteInformationRecord = informationRecord as RemotingInformationRecord;366 367                        if (remoteInformationRecord == null)368                        {369                            // if we get a base InformationRecord object, check if the computerName is370                            // populated in the Source field371                            if (!string.IsNullOrEmpty(informationRecord.Source))372                            {373                                string computerName;374                                Guid jobInstanceId;375                                GetIdentifierInfo(informationRecord.Source, out jobInstanceId, out computerName);376                                informationRecord = new RemotingInformationRecord(informationRecord,377                                                                      new OriginInfo(computerName, Guid.Empty,378                                                                                     jobInstanceId));379                            }380                        }381                        else382                        {383                            informationRecord = remoteInformationRecord;384                        }385 386                        MshCommandRuntime mshCommandRuntime = cmdlet.CommandRuntime as MshCommandRuntime;387                        mshCommandRuntime?.WriteInformation(informationRecord, overrideInquire);388                    }389 390                    break;391 392                case PSStreamObjectType.WarningRecord:393                case PSStreamObjectType.MethodExecutor:394                case PSStreamObjectType.BlockingError:395                case PSStreamObjectType.ShouldMethod:396                    {397                        WriteStreamObject(cmdlet, overrideInquire);398                    }399 400                    break;401            }402        }403 404        /// <summary>405        /// Handle the object obtained from an ObjectStream's reader406        /// based on its type.407        /// </summary>408        /// <param name="cmdlet">Cmdlet to use for outputting the object.</param>409        /// <param name="writeSourceIdentifier"></param>410        /// <param name="overrideInquire">Overrides the inquire preference, used in Receive-Job to suppress prompts.</param>411        internal void WriteStreamObject(Cmdlet cmdlet, bool writeSourceIdentifier, bool overrideInquire)412        {413            if (writeSourceIdentifier)414                WriteStreamObject(cmdlet, Id, overrideInquire);415            else416                WriteStreamObject(cmdlet, overrideInquire);417        }418 419        private static void InvokeCmdletMethodAndWaitForResults<T>(CmdletMethodInvoker<T> cmdletMethodInvoker, Cmdlet cmdlet)420        {421            Dbg.Assert(cmdletMethodInvoker != null, "Caller should verify cmdletMethodInvoker != null");422 423            cmdletMethodInvoker.MethodResult = default(T);424            try425            {426                T tmpMethodResult = cmdletMethodInvoker.Action(cmdlet);427                lock (cmdletMethodInvoker.SyncObject)428                {429                    cmdletMethodInvoker.MethodResult = tmpMethodResult;430                }431            }432            catch (Exception e)433            {434                lock (cmdletMethodInvoker.SyncObject)435                {436                    cmdletMethodInvoker.ExceptionThrownOnCmdletThread = e;437                }438 439                throw;440            }441            finally442            {443                cmdletMethodInvoker.Finished?.Set();444            }445        }446 447        internal static void AddSourceJobNoteProperty(PSObject psObj, Guid instanceId)448        {449            Dbg.Assert(psObj != null, "psObj is null trying to add a note property.");450            if (psObj.Properties[RemotingConstants.SourceJobInstanceId] != null)451            {452                psObj.Properties.Remove(RemotingConstants.SourceJobInstanceId);453            }454 455            psObj.Properties.Add(new PSNoteProperty(RemotingConstants.SourceJobInstanceId, instanceId));456        }457 458        internal static string CreateInformationalMessage(Guid instanceId, string message)459        {460            var newMessage = new StringBuilder(instanceId.ToString());461            newMessage.Append(':');462            newMessage.Append(message);463 464            return newMessage.ToString();465        }466 467        internal static ErrorRecord AddSourceTagToError(ErrorRecord errorRecord, Guid sourceId)468        {469            if (errorRecord == null)470            {471                return null;472            }473 474            errorRecord.ErrorDetails ??= new ErrorDetails(string.Empty);475            errorRecord.ErrorDetails.RecommendedAction = CreateInformationalMessage(sourceId, errorRecord.ErrorDetails.RecommendedAction);476 477            return errorRecord;478        }479    }480}481 482namespace System.Management.Automation.Remoting483{484    /// <summary>485    /// </summary>486    public class CmdletMethodInvoker<T>487    {488        /// <summary>489        /// </summary>490        public Func<Cmdlet, T> Action { get; set; }491 492        /// <summary>493        /// </summary>494        public Exception ExceptionThrownOnCmdletThread { get; set; }495 496        /// <summary>497        /// </summary>498        public ManualResetEventSlim Finished { get; set; }499 500        /// <summary>501        /// </summary>502        public object SyncObject { get; set; }503 504        /// <summary>505        /// </summary>506        public T MethodResult { get; set; }507    }508}509