MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Diagnostics.CodeAnalysis;5using System.Management.Automation.Runspaces;6 7namespace System.Management.Automation.Host8{9 /// <summary>10 /// Defines the properties and facilities providing by an application hosting PowerShell <see11 /// cref="System.Management.Automation.Runspaces.Runspace"/>.12 /// </summary>13 /// <remarks>14 /// A hosting application derives from this class and15 /// overrides the abstract methods and properties. The hosting application creates an instance of its derived class and16 /// passes it to the <see cref="System.Management.Automation.Runspaces.RunspaceFactory"/> CreateRunspace method.17 ///18 /// From the moment that the instance of the derived class (the "host class") is passed to CreateRunspace, the PowerShell runtime19 /// can call any of the methods of that class. The instance must not be destroyed until after the Runspace is closed.20 ///21 /// There is a 1:1 relationship between the instance of the host class and the Runspace instance to which it is passed. In22 /// other words, it is not legal to pass the same instance of the host class to more than one call to CreateRunspace. (It23 /// is perfectly legal to call CreateRunspace more than once, as long as each call is supplied a unique instance of the host24 /// class.)25 ///26 /// Methods of the host class can be called by the Runspace or any cmdlet or script executed in that Runspace in any order27 /// and from any thread. It is the responsibility of the hosting application to define the host class methods in a28 /// threadsafe fashion. An implementation of the host class should not depend on method execution order.29 ///30 /// The instance of the host class that is passed to a Runspace is exposed by the Runspace to the cmdlets, scripts, and31 /// providers that are executed in that Runspace. Scripts access the host class via the $Host built-in variable. Cmdlets32 /// access the host via the Host property of the Cmdlet base class.33 /// </remarks>34 /// <seealso cref="System.Management.Automation.Runspaces.Runspace"/>35 /// <seealso cref="System.Management.Automation.Host.PSHostUserInterface"/>36 /// <seealso cref="System.Management.Automation.Host.PSHostRawUserInterface"/>37 public abstract class PSHost38 {39 /// <summary>40 /// The powershell spec states that 128 is the maximum nesting depth.41 /// </summary>42 internal const int MaximumNestedPromptLevel = 128;43 44 internal static bool IsStdOutputRedirected;45 46 /// <summary>47 /// Protected constructor which does nothing. Provided per .Net design guidelines section 4.3.1.48 /// </summary>49 protected PSHost()50 {51 // do nothing52 }53 54 /// <summary>55 /// Gets the hosting application's identification in some user-friendly fashion. This name can be referenced by scripts and cmdlets56 /// to identify the host that is executing them. The format of the value is not defined, but a short, simple string is57 /// recommended.58 /// </summary>59 /// <remarks>60 /// In implementing this member, you should return some sort of informative string describing the nature61 /// your hosting application. For the default console host shipped by Microsoft this is ConsoleHost.62 /// </remarks>63 /// <value>64 /// The name identifier of the hosting application.65 /// </value>66 /// <example>67 /// <code>68 /// if ($Host.Name -ieq "ConsoleHost") { write-host "I'm running in the Console Host" }69 /// </code>70 /// </example>71 public abstract string Name72 {73 get;74 }75 76 /// <summary>77 /// Gets the version of the hosting application. This value should remain invariant for a particular build of the78 /// host. This value may be referenced by scripts and cmdlets.79 /// </summary>80 /// <remarks>81 /// When implementing this member, it should return the product version number for the product82 /// that is hosting the PowerShell engine.83 /// </remarks>84 /// <value>85 /// The version number of the hosting application.86 /// </value>87 public abstract System.Version Version88 {89 get;90 }91 92 /// <summary>93 /// Gets a GUID that uniquely identifies this instance of the host. The value should remain invariant for the lifetime of94 /// this instance.95 /// </summary>96 public abstract System.Guid InstanceId97 {98 get;99 }100 101 /// <summary>102 /// Gets the hosting application's implementation of the103 /// <see cref="System.Management.Automation.Host.PSHostUserInterface"/> abstract base class. A host104 /// that does not want to support user interaction should return null.105 /// </summary>106 /// <value>107 /// A reference to an instance of the hosting application's implementation of a class derived from108 /// <see cref="System.Management.Automation.Host.PSHostUserInterface"/>, or null to indicate that user109 /// interaction is not supported.110 /// </value>111 /// <remarks>112 /// The implementation of this routine should return an instance of the appropriate113 /// implementation of PSHostUserInterface for this application. As an alternative,114 /// for simple scenarios, just returning null is sufficient.115 /// </remarks>116 public abstract System.Management.Automation.Host.PSHostUserInterface UI117 {118 get;119 }120 121 /// <summary>122 /// Gets the host's culture: the culture that the runspace should use to set the CurrentCulture on new threads.123 /// </summary>124 /// <value>125 /// A CultureInfo object representing the host's current culture. Returning null is not allowed.126 /// </value>127 /// <remarks>128 /// The runspace will set the thread current culture to this value each time it starts a pipeline. Thus, cmdlets are129 /// encouraged to use Thread.CurrentThread.CurrentCulture.130 /// </remarks>131 public abstract System.Globalization.CultureInfo CurrentCulture132 {133 get;134 }135 136 /// <summary>137 /// Gets the host's UI culture: the culture that the runspace and cmdlets should use to do resource loading.138 ///139 /// The runspace will set the thread current ui culture to this value each time it starts a pipeline.140 /// </summary>141 /// <value>142 /// A CultureInfo object representing the host's current UI culture. Returning null is not allowed.143 /// </value>144 public abstract System.Globalization.CultureInfo CurrentUICulture145 {146 get;147 }148 149 /// <summary>150 /// Request by the engine to end the current engine runspace (to shut down and terminate the host's root runspace).151 /// </summary>152 /// <remarks>153 /// This method is called by the engine to request the host shutdown the engine. This is invoked by the exit keyword154 /// or by any other facility by which a runspace instance wishes to be shut down.155 ///156 /// To honor this request, the host should stop accepting and submitting commands to the engine and close the runspace.157 /// </remarks>158 /// <param name="exitCode">159 /// The exit code accompanying the exit keyword. Typically, after exiting a runspace, a host will also terminate. The160 /// exitCode parameter can be used to set the host's process exit code.161 /// </param>162 public abstract void SetShouldExit(int exitCode);163 164 /// <summary>165 /// Instructs the host to interrupt the currently running pipeline and start a new, "nested" input loop, where an input166 /// loop is the cycle of prompt, input, execute.167 /// </summary>168 /// <remarks>169 /// Typically called by the engine in response to some user action that suspends the currently executing pipeline, such170 /// as choosing the "suspend" option of a ConfirmProcessing call. Before calling this method, the engine should set171 /// various shell variables to the express the state of the interrupted input loop (current pipeline, current object in172 /// pipeline, depth of nested input loops, etc.)173 ///174 /// A non-interactive host may throw a "not implemented" exception here.175 ///176 /// If the UI property returns null, the engine should not call this method.177 /// <!--Was: ExecuteSubShell. "subshell" implies a new child engine, which is not the case here. This is called during the178 /// interruption of a pipeline to allow nested pipeline(s) to be run as a way to the user to suspend execution while he179 /// evaluates other commands. It does not create a truly new engine instance with new session state.-->180 /// </remarks>181 /// <seealso cref="System.Management.Automation.Host.PSHost.ExitNestedPrompt"/>182 public abstract void EnterNestedPrompt();183 184 /// <summary>185 /// Causes the host to end the currently running input loop. If the input loop was created by a prior call to186 /// EnterNestedPrompt, the enclosing pipeline will be resumed. If the current input loop is the top-most loop, then the187 /// host will act as though SetShouldExit was called.188 /// </summary>189 /// <remarks>190 /// Typically called by the engine in response to some user action that resumes a suspended pipeline, such as with the191 /// 'continue-command' intrinsic cmdlet. Before calling this method, the engine should clear out the loop-specific192 /// variables that were set when the loop was created.193 ///194 /// If the UI Property returns a null, the engine should not call this method.195 /// </remarks>196 /// <seealso cref="EnterNestedPrompt"/>197 public abstract void ExitNestedPrompt();198 199 /// <summary>200 /// Used to allow the host to pass private data through a Runspace to cmdlets running inside that Runspace's201 /// runspace. The type and nature of that data is entirely defined by the host, but there are some caveats:202 /// </summary>203 /// <returns>204 /// The default implementation returns null.205 /// </returns>206 /// <remarks>207 /// If the host is using an out-of-process Runspace, then the value of this property is serialized when crossing208 /// that process boundary in the same fashion as any object in a pipeline is serialized when crossing process boundaries.209 /// In this case, the BaseObject property of the value will be null.210 ///211 /// If the host is using an in-process Runspace, then the BaseObject property can be a non-null value a live object.212 /// No guarantees are made as to the app domain or thread that the BaseObject is accessed if it is accessed in the213 /// runspace. No guarantees of threadsafety or reentrancy are made. The object set in the BaseObject property of214 /// the value returned by this method is responsible for ensuring its own threadsafety and re-entrance safety.215 /// Note that thread(s) accessing that object may not necessarily be the same from one access to the next.216 ///217 /// The return value should have value-semantics: that is, changes to the state of the instance returned are not218 /// reflected across processes. Ex: if a cmdlet reads this property, then changes the state of the result, that219 /// change will not be visible to the host if the host is in another process. Therefore, the implementation of220 /// get for this property should always return a unique instance.221 /// </remarks>222 public virtual PSObject PrivateData223 {224 get225 {226 return null;227 }228 }229 230 /// <summary>231 /// Called by the engine to notify the host that it is about to execute a "legacy" command line application. A legacy232 /// application is defined as a console-mode executable that may do one or more of the following:233 /// . reads from stdin234 /// . writes to stdout235 /// . writes to stderr236 /// . uses any of the win32 console APIs.237 /// </summary>238 /// <remarks>239 /// Notifying the host allows the host to do such things as save off any state that might need to be restored when the240 /// legacy application terminates, set or remove break handler hooks, redirect stream handles, and so forth.241 ///242 /// The engine will always call this method and the NotifyEndApplication method in matching pairs.243 ///244 /// The engine may call this method several times in the course of a single pipeline. For instance, the pipeline:245 ///246 /// foo.exe | bar-cmdlet | baz.exe247 ///248 /// Will result in a sequence of calls similar to the following:249 /// NotifyBeginApplication - called once when foo.exe is started250 /// NotifyBeginApplication - called once when baz.exe is started251 /// NotifyEndApplication - called once when baz.exe terminates252 /// NotifyEndApplication - called once when foo.exe terminates253 ///254 /// Note that the order in which the NotifyEndApplication call follows the corresponding call to NotifyBeginApplication255 /// with respect to any other call to NotifyBeginApplication is not defined, and should not be depended upon. In other256 /// words, NotifyBeginApplication may be called several times before NotifyEndApplication is called. The only thing257 /// that is guaranteed is that there will be an equal number of calls to NotifyEndApplication as to258 /// NotifyBeginApplication.259 /// </remarks>260 /// <seealso cref="System.Management.Automation.Host.PSHost.NotifyEndApplication"/>261 public abstract void NotifyBeginApplication();262 263 /// <summary>264 /// Called by the engine to notify the host that the execution of a legacy command has completed.265 /// </summary>266 /// <seealso cref="System.Management.Automation.Host.PSHost.NotifyBeginApplication"/>267 public abstract void NotifyEndApplication();268 269 /// <summary>270 /// Used by hosting applications to notify PowerShell engine that it is271 /// being hosted in a console based application and the Pipeline execution272 /// thread should call SetThreadUILanguage(0). This property is currently273 /// used by ConsoleHost only and in future releases we may consider274 /// exposing this publicly.275 /// </summary>276 internal bool ShouldSetThreadUILanguageToZero { get; set; }277 278 /// <summary>279 /// This property enables and disables the host debugger if debugging is supported.280 /// </summary>281 public virtual bool DebuggerEnabled282 {283 get { return false; }284 285 set { throw new PSNotImplementedException(); }286 }287 }288 289 /// <summary>290 /// This interface needs to be implemented by PSHost objects that want to support the PushRunspace291 /// and PopRunspace functionality.292 /// </summary>293#nullable enable294 public interface IHostSupportsInteractiveSession295 {296 /// <summary>297 /// Called by the engine to notify the host that a runspace push has been requested.298 /// </summary>299 /// <param name="runspace">300 /// The runspace to push. This runspace must be a remote runspace and301 /// not a locally created runspace.302 /// </param>303 /// <exception cref="ArgumentException">The specified runspace is not a remote runspace.</exception>304 /// <seealso cref="System.Management.Automation.Host.IHostSupportsInteractiveSession.PushRunspace"/>305 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspace")]306 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "runspace")]307 void PushRunspace(Runspace runspace);308 309 /// <summary>310 /// Called by the engine to notify the host that a runspace pop has been requested.311 /// </summary>312 /// <seealso cref="System.Management.Automation.Host.IHostSupportsInteractiveSession.PopRunspace"/>313 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspace")]314 void PopRunspace();315 316 /// <summary>317 /// True if a runspace is pushed; false otherwise.318 /// </summary>319 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspace")]320 bool IsRunspacePushed { get; }321 322 /// <summary>323 /// Returns the current runspace associated with this host.324 /// </summary>325 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspace")]326 Runspace? Runspace { get; }327 }328}329 