From 2ed9abc99b9ea9caf13b09b1b64099a86405794d Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Thu, 25 Jul 2019 12:38:52 -0700 Subject: [PATCH] Enable `-sta` and `-mta` switches for pwsh (#10061) --- .../commands/management/WMIHelper.cs | 2 +- .../commands/utility/New-Object.cs | 10 --- .../host/msh/CommandLineParameterParser.cs | 34 ++++------ .../host/msh/ConsoleHost.cs | 28 ++------ .../CommandLineParameterParserStrings.resx | 6 ++ .../resources/ManagedEntranceStrings.resx | 14 +++- .../engine/InitialSessionState.cs | 5 -- .../engine/hostifaces/Connection.cs | 2 - .../engine/hostifaces/ConnectionBase.cs | 9 +-- .../engine/hostifaces/LocalConnection.cs | 44 ++++++------ .../engine/hostifaces/LocalPipeline.cs | 21 ++---- .../engine/hostifaces/PowerShell.cs | 18 ++--- .../engine/hostifaces/RunspacePool.cs | 2 - .../engine/hostifaces/RunspacePoolInternal.cs | 7 -- .../engine/remoting/client/remoterunspace.cs | 2 - .../remoting/commands/CustomShellCommands.cs | 9 +-- .../remoting/common/RunspaceConnectionInfo.cs | 11 --- .../common/WireDataFormat/EncodeAndDecode.cs | 15 +--- .../fanin/InitialSessionStateProvider.cs | 14 ++-- .../remoting/server/ServerPowerShellDriver.cs | 68 ------------------- .../server/ServerRunspacePoolDriver.cs | 65 ------------------ .../server/ServerSteppablePipelineDriver.cs | 35 ---------- .../remoting/server/serverremotesession.cs | 4 -- test/powershell/Host/ConsoleHost.Tests.ps1 | 62 +++++++++++++++-- 24 files changed, 134 insertions(+), 353 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/WMIHelper.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/WMIHelper.cs index b62811ffd6..a90a8971e0 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/WMIHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/WMIHelper.cs @@ -162,7 +162,7 @@ namespace Microsoft.PowerShell.Commands } thread.IsBackground = true; - // thread.SetApartmentState( ApartmentState.STA); + thread.SetApartmentState(ApartmentState.STA); thread.Start(); } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/New-Object.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/New-Object.cs index 6f5f8b2f33..3f7173184e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/New-Object.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/New-Object.cs @@ -395,7 +395,6 @@ namespace Microsoft.PowerShell.Commands return result; } -#if !CORECLR private class ComCreateInfo { public object objectCreated; @@ -435,7 +434,6 @@ namespace Microsoft.PowerShell.Commands info.success = false; } } -#endif private object CreateComObject() { @@ -459,13 +457,6 @@ namespace Microsoft.PowerShell.Commands // Check Error Code to see if Error is because of Com apartment Mismatch. if (e.HResult == RPC_E_CHANGED_MODE) { -#if CORECLR - ThrowTerminatingError( - new ErrorRecord( - new COMException(StringUtil.Format(NewObjectStrings.ApartmentNotSupported, e.Message), e), - "NoCOMClassIdentified", - ErrorCategory.ResourceUnavailable, null)); -#else createInfo = new ComCreateInfo(); Thread thread = new Thread(new ParameterizedThreadStart(STAComCreateThreadProc)); @@ -482,7 +473,6 @@ namespace Microsoft.PowerShell.Commands ThrowTerminatingError( new ErrorRecord(createInfo.e, "NoCOMClassIdentified", ErrorCategory.ResourceUnavailable, null)); -#endif } else { diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs index 4e7733bef2..de5d7215e8 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs @@ -173,10 +173,8 @@ namespace Microsoft.PowerShell private const int MaxPipePathLengthMacOS = 104; internal static string[] validParameters = { -#if STAMODE "sta", "mta", -#endif "command", "configurationname", "custompipename", @@ -644,7 +642,6 @@ namespace Microsoft.PowerShell } } -#if STAMODE internal bool StaMode { get @@ -655,14 +652,10 @@ namespace Microsoft.PowerShell } else { - // Nano doesn't support STA COM apartment, so on Nano powershell has to use MTA as the default. - // return false; - // Win8: 182409 PowerShell 3.0 should run in STA mode by default return true; } } } -#endif /// /// Processes all the command line parameters to ConsoleHost. Returns the exit code to be used to terminate the process, or @@ -944,10 +937,15 @@ namespace Microsoft.PowerShell break; } } -#if STAMODE - // explicit setting of the ApartmentState Not supported on NanoServer else if (MatchSwitch(switchKey, "sta", "s")) { + if (!Platform.IsWindowsDesktop) + { + WriteCommandLineError( + CommandLineParameterParserStrings.STANotImplemented); + break; + } + if (_staMode.HasValue) { // -sta and -mta are mutually exclusive. @@ -958,10 +956,15 @@ namespace Microsoft.PowerShell _staMode = true; } - // Win8: 182409 PowerShell 3.0 should run in STA mode by default..so, consequently adding the switch -mta. - // Not deleting -sta for backward compatability reasons else if (MatchSwitch(switchKey, "mta", "mta")) { + if (!Platform.IsWindowsDesktop) + { + WriteCommandLineError( + CommandLineParameterParserStrings.MTANotImplemented); + break; + } + if (_staMode.HasValue) { // -sta and -mta are mutually exclusive. @@ -972,7 +975,6 @@ namespace Microsoft.PowerShell _staMode = false; } -#endif else if (MatchSwitch(switchKey, "workingdirectory", "wo") || MatchSwitch(switchKey, "wd", "wd")) { ++i; @@ -1406,15 +1408,7 @@ namespace Microsoft.PowerShell private bool _abortStartup; private bool _skipUserInit; private string _customPipeName; -#if STAMODE - // Win8: 182409 PowerShell 3.0 should run in STA mode by default - // -sta and -mta are mutually exclusive..so tracking them using nullable boolean - // if true, then sta is specified on the command line. - // if false, then mta is specified on the command line. - // if null, then none is specified on the command line..use default in this case - // default is sta. private bool? _staMode = null; -#endif private bool _noExit = true; private bool _explicitReadCommandsFromStdin; private bool _noPrompt; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index c8d4b3488a..226e449713 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -1373,11 +1373,7 @@ namespace Microsoft.PowerShell // NTRAID#Windows Out Of Band Releases-915506-2005/09/09 // Removed HandleUnexpectedExceptions infrastructure -#if STAMODE exitCode = DoRunspaceLoop(cpp.InitialCommand, cpp.SkipProfiles, cpp.Args, cpp.StaMode, cpp.ConfigurationName); -#else - exitCode = DoRunspaceLoop(cpp.InitialCommand, cpp.SkipProfiles, cpp.Args, false, cpp.ConfigurationName); -#endif } while (false); @@ -1452,12 +1448,12 @@ namespace Microsoft.PowerShell _runspaceRef.Runspace.Close(); _runspaceRef = null; -#if STAMODE - if (staMode) // don't recycle the Runspace in STA mode + + if (staMode) { + // don't continue the session in STA mode ShouldEndSession = true; } -#endif } return ExitCode; @@ -1496,11 +1492,7 @@ namespace Microsoft.PowerShell { args = runspaceCreationArgs as RunspaceCreationEventArgs; Dbg.Assert(args != null, "Event Arguments to CreateRunspace should not be null"); -#if STAMODE DoCreateRunspace(args.InitialCommand, args.SkipProfiles, args.StaMode, args.ConfigurationName, args.InitialCommandArgs); -#else - DoCreateRunspace(args.InitialCommand, args.SkipProfiles, false, args.ConfigurationName, args.InitialCommandArgs); -#endif } catch (ConsoleHostStartupException startupException) { @@ -1618,17 +1610,11 @@ namespace Microsoft.PowerShell private void OpenConsoleRunspace(Runspace runspace, bool staMode) { -#if STAMODE - // staMode will have following values: - // On FullPS: 'true'/'false' = default('true'=STA) + possibility of overload through cmdline parameter '-mta' - // On NanoPS: always 'false' = default('false'=MTA) + NO possibility of overload through cmdline parameter '-mta' - // ThreadOptions should match on FullPS and NanoPS for corresponding ApartmentStates. - if (staMode) + if (staMode && Platform.IsWindowsDesktop) { - // we can't change ApartmentStates on CoreCLR runspace.ApartmentState = ApartmentState.STA; } -#endif + runspace.ThreadOptions = PSThreadOptions.ReuseThread; runspace.EngineActivityId = EtwActivity.GetActivityId(); @@ -2896,18 +2882,14 @@ namespace Microsoft.PowerShell { InitialCommand = initialCommand; SkipProfiles = skipProfiles; -#if STAMODE StaMode = staMode; -#endif ConfigurationName = configurationName; InitialCommandArgs = initialCommandArgs; } internal string InitialCommand { get; set; } internal bool SkipProfiles { get; set; } -#if STAMODE internal bool StaMode { get; set; } -#endif internal string ConfigurationName { get; set; } internal Collection InitialCommandArgs { get; set; } } diff --git a/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx b/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx index be8eb1683f..0cbbd09f0e 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx +++ b/src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx @@ -210,4 +210,10 @@ Cannot process the command because -WorkingDirectory requires an argument that is a directory path. + + Parameter -MTA is not supported on this platform. + + + Parameter -STA is not supported on this platform. + diff --git a/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx b/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx index fe14c5e740..074b926838 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx +++ b/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx @@ -131,8 +131,8 @@ Type 'help' to get help. [-ConfigurationName <string>] [-CustomPipeName <string>] [-EncodedCommand <Base64EncodedCommand>] [-ExecutionPolicy <ExecutionPolicy>] [-InputFormat {Text | XML}] - [-Interactive] [-LoadProfile] [-NoExit] [-NoLogo] [-NonInteractive] [-NoProfile] - [-OutputFormat {Text | XML}] [-SettingsFile <filePath>] [-Version] + [-Interactive] [-LoadProfile] [-MTA] [-NoExit] [-NoLogo] [-NonInteractive] [-NoProfile] + [-OutputFormat {Text | XML}] [-SettingsFile <filePath>] [-STA] [-Version] [-WindowStyle <style>] [-WorkingDirectory <directoryPath>] pwsh[.exe] -h | -Help | -? | /? @@ -298,6 +298,11 @@ All parameters are case-insensitive. Load the PowerShell profiles. This is the default behavior even if this is not specified. +-MTA + + Start the shell using a multi-threaded apartment. + Only available on Windows. + -NoExit | -noe Does not exit after running startup commands. @@ -334,6 +339,11 @@ Hides the copyright banner at startup. Example: "pwsh -SettingsFile c:\myproject\powershell.config.json" +-STA + + Start the shell using a single-threaded apartment. This is the default. + Only available on Windows. + -Version | -v Displays the version of PowerShell. Additional parameters are ignored. diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs index 46fd2b99a1..3a82abaef9 100644 --- a/src/System.Management.Automation/engine/InitialSessionState.cs +++ b/src/System.Management.Automation/engine/InitialSessionState.cs @@ -1671,9 +1671,7 @@ namespace System.Management.Automation.Runspaces ss.UseFullLanguageModeInDebugger = this.UseFullLanguageModeInDebugger; ss.ThreadOptions = this.ThreadOptions; ss.ThrowOnRunspaceOpenError = this.ThrowOnRunspaceOpenError; -#if !CORECLR // No ApartmentState In CoreCLR ss.ApartmentState = this.ApartmentState; -#endif foreach (ModuleSpecification modSpec in this.ModuleSpecificationsToImport) { @@ -1812,14 +1810,11 @@ namespace System.Management.Automation.Runspaces /// public bool UseFullLanguageModeInDebugger { get; set; } = false; -#if !CORECLR // No ApartmentState In CoreCLR /// /// ApartmentState of the thread used to execute commands. /// public ApartmentState ApartmentState { get; set; } = Runspace.DefaultApartmentState; -#endif - /// /// This property determines whether a new thread is created for each invocation of a command. /// diff --git a/src/System.Management.Automation/engine/hostifaces/Connection.cs b/src/System.Management.Automation/engine/hostifaces/Connection.cs index e4ced59fdd..f0b4a640f2 100644 --- a/src/System.Management.Automation/engine/hostifaces/Connection.cs +++ b/src/System.Management.Automation/engine/hostifaces/Connection.cs @@ -582,7 +582,6 @@ namespace System.Management.Automation.Runspaces } } -#if !CORECLR // No ApartmentState In CoreCLR internal const ApartmentState DefaultApartmentState = ApartmentState.Unknown; /// @@ -613,7 +612,6 @@ namespace System.Management.Automation.Runspaces } private ApartmentState apartmentState = Runspace.DefaultApartmentState; -#endif /// /// This property determines whether a new thread is create for each invocation. diff --git a/src/System.Management.Automation/engine/hostifaces/ConnectionBase.cs b/src/System.Management.Automation/engine/hostifaces/ConnectionBase.cs index 02622582f9..7a04c40cf7 100644 --- a/src/System.Management.Automation/engine/hostifaces/ConnectionBase.cs +++ b/src/System.Management.Automation/engine/hostifaces/ConnectionBase.cs @@ -77,10 +77,7 @@ namespace System.Management.Automation.Runspaces Host = host; InitialSessionState = initialSessionState.Clone(); this.ThreadOptions = initialSessionState.ThreadOptions; - -#if !CORECLR // No ApartmentState In CoreCLR this.ApartmentState = initialSessionState.ApartmentState; -#endif } /// @@ -126,10 +123,7 @@ namespace System.Management.Automation.Runspaces } this.ThreadOptions = initialSessionState.ThreadOptions; - -#if !CORECLR // No ApartmentState In CoreCLR this.ApartmentState = initialSessionState.ApartmentState; -#endif } /// @@ -920,7 +914,6 @@ namespace System.Management.Automation.Runspaces waitHandles[i] = runningPipelines[i].PipelineFinishedEvent; } -#if !CORECLR // No ApartmentState.STA In CoreCLR // WaitAll for multiple handles on a STA (single-thread apartment) thread is not supported as WaitAll will prevent the message pump to run if (runningPipelines.Length > 1 && Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) { @@ -940,7 +933,7 @@ namespace System.Management.Automation.Runspaces return waitAllIsDone.WaitOne(); } } -#endif + return WaitHandle.WaitAll(waitHandles); } else diff --git a/src/System.Management.Automation/engine/hostifaces/LocalConnection.cs b/src/System.Management.Automation/engine/hostifaces/LocalConnection.cs index 680e0e530b..796e6c4d18 100644 --- a/src/System.Management.Automation/engine/hostifaces/LocalConnection.cs +++ b/src/System.Management.Automation/engine/hostifaces/LocalConnection.cs @@ -146,32 +146,32 @@ namespace System.Management.Automation.Runspaces { lock (this.SyncRoot) { - if (value != _createThreadOptions) + if (value == _createThreadOptions) { - if (this.RunspaceStateInfo.State != RunspaceState.BeforeOpen) - { -#if CORECLR // No ApartmentState.STA Support In CoreCLR - bool allowed = value == PSThreadOptions.ReuseThread; -#else - // if the runspace is already opened we only allow changing the options if - // the apartment state is MTA and the new value is ReuseThread - bool allowed = (this.ApartmentState == ApartmentState.MTA || this.ApartmentState == ApartmentState.Unknown) // Unknown is the same as MTA - && - value == PSThreadOptions.ReuseThread; -#endif - - if (!allowed) - { - throw new InvalidOperationException(StringUtil.Format(RunspaceStrings.InvalidThreadOptionsChange)); - } - } - - _createThreadOptions = value; + return; } + + if (this.RunspaceStateInfo.State != RunspaceState.BeforeOpen) + { + if (!IsValidThreadOptionsConfiguration(value)) + { + throw new InvalidOperationException(StringUtil.Format(RunspaceStrings.InvalidThreadOptionsChange)); + } + } + + _createThreadOptions = value; } } } + private bool IsValidThreadOptionsConfiguration(PSThreadOptions options) + { + // If the runspace is already opened, we only allow changing options when: + // - The new value is ReuseThread, and + // - The apartment state is not STA + return options == PSThreadOptions.ReuseThread && this.ApartmentState != ApartmentState.STA; + } + private PSThreadOptions _createThreadOptions = PSThreadOptions.Default; /// @@ -770,11 +770,7 @@ namespace System.Management.Automation.Runspaces { if (_pipelineThread == null) { -#if CORECLR // No ApartmentState In CoreCLR - _pipelineThread = new PipelineThread(); -#else _pipelineThread = new PipelineThread(this.ApartmentState); -#endif } return _pipelineThread; diff --git a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs index 9753530cc2..94f3bfb2e4 100644 --- a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs +++ b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs @@ -179,8 +179,7 @@ namespace System.Management.Automation.Runspaces // and support impersonation flow as needed (Windows only). Thread invokeThread = new Thread(new ThreadStart(invokeThreadProcDelegate), DefaultPipelineStackSize); SetupInvokeThread(invokeThread, true); -#if !CORECLR - // No ApartmentState in CoreCLR + ApartmentState apartmentState; if (InvocationSettings != null && InvocationSettings.ApartmentState != ApartmentState.Unknown) @@ -192,11 +191,13 @@ namespace System.Management.Automation.Runspaces apartmentState = this.LocalRunspace.ApartmentState; // use the Runspace apartment state } - if (apartmentState != ApartmentState.Unknown) +#if !UNIX + if (apartmentState != ApartmentState.Unknown && !Platform.IsNanoServer && !Platform.IsIoT) { invokeThread.SetApartmentState(apartmentState); } #endif + invokeThread.Start(); break; @@ -1188,15 +1189,6 @@ namespace System.Management.Automation.Runspaces /// /// Creates the worker thread and waits for it to be ready. /// -#if CORECLR - internal PipelineThread() - { - _worker = new Thread(WorkerProc, LocalPipeline.DefaultPipelineStackSize); - _workItem = null; - _workItemReady = new AutoResetEvent(false); - _closed = false; - } -#else internal PipelineThread(ApartmentState apartmentState) { _worker = new Thread(WorkerProc, LocalPipeline.DefaultPipelineStackSize); @@ -1204,12 +1196,13 @@ namespace System.Management.Automation.Runspaces _workItemReady = new AutoResetEvent(false); _closed = false; - if (apartmentState != ApartmentState.Unknown) +#if !UNIX + if (apartmentState != ApartmentState.Unknown && !Platform.IsNanoServer && !Platform.IsIoT) { _worker.SetApartmentState(apartmentState); } - } #endif + } /// /// Returns the worker thread. diff --git a/src/System.Management.Automation/engine/hostifaces/PowerShell.cs b/src/System.Management.Automation/engine/hostifaces/PowerShell.cs index 4de461de3f..0517de0e17 100644 --- a/src/System.Management.Automation/engine/hostifaces/PowerShell.cs +++ b/src/System.Management.Automation/engine/hostifaces/PowerShell.cs @@ -328,9 +328,7 @@ namespace System.Management.Automation /// public PSInvocationSettings() { -#if !CORECLR // No ApartmentState In CoreCLR this.ApartmentState = ApartmentState.Unknown; -#endif _host = null; RemoteStreamOptions = 0; AddToHistory = false; @@ -339,13 +337,11 @@ namespace System.Management.Automation #endregion -#if !CORECLR // No ApartmentState In CoreCLR /// /// ApartmentState of the thread in which the command /// is executed. /// public ApartmentState ApartmentState { get; set; } -#endif /// /// Host to use with the Runspace when the command is @@ -4530,9 +4526,8 @@ namespace System.Management.Automation { if (pool != null) { -#if !CORECLR // No ApartmentState In CoreCLR VerifyThreadSettings(settings, pool.ApartmentState, pool.ThreadOptions, false); -#endif + // getting the runspace asynchronously so that Stop can be supported from a different // thread. _worker.GetRunspaceAsyncResult = pool.BeginGetRunspace(null, null); @@ -4544,9 +4539,8 @@ namespace System.Management.Automation rsToUse = _rsConnection as Runspace; if (rsToUse != null) { -#if !CORECLR // No ApartmentState In CoreCLR VerifyThreadSettings(settings, rsToUse.ApartmentState, rsToUse.ThreadOptions, false); -#endif + if (rsToUse.RunspaceStateInfo.State != RunspaceState.Opened) { string message = StringUtil.Format(PowerShellStrings.InvalidRunspaceState, RunspaceState.Opened, rsToUse.RunspaceStateInfo.State); @@ -4810,9 +4804,8 @@ namespace System.Management.Automation { if (pool != null) { -#if !CORECLR // No ApartmentState In CoreCLR VerifyThreadSettings(settings, pool.ApartmentState, pool.ThreadOptions, pool.IsRemote); -#endif + pool.AssertPoolIsOpen(); // for executing in a remote runspace pool case @@ -4888,9 +4881,8 @@ namespace System.Management.Automation LocalRunspace rs = _rsConnection as LocalRunspace; if (rs != null) { -#if !CORECLR // No ApartmentState In CoreCLR VerifyThreadSettings(settings, rs.ApartmentState, rs.ThreadOptions, false); -#endif + if (rs.RunspaceStateInfo.State != RunspaceState.Opened) { string message = StringUtil.Format(PowerShellStrings.InvalidRunspaceState, RunspaceState.Opened, rs.RunspaceStateInfo.State); @@ -4939,7 +4931,6 @@ namespace System.Management.Automation return _invokeAsyncResult; } -#if !CORECLR // No ApartmentState In CoreCLR /// /// Verifies the settings for ThreadOptions and ApartmentState. /// @@ -4974,7 +4965,6 @@ namespace System.Management.Automation } } } -#endif /// /// diff --git a/src/System.Management.Automation/engine/hostifaces/RunspacePool.cs b/src/System.Management.Automation/engine/hostifaces/RunspacePool.cs index 2b5781884f..541575099b 100644 --- a/src/System.Management.Automation/engine/hostifaces/RunspacePool.cs +++ b/src/System.Management.Automation/engine/hostifaces/RunspacePool.cs @@ -1259,7 +1259,6 @@ namespace System.Management.Automation.Runspaces } } -#if !CORECLR // No ApartmentState In CoreCLR /// /// ApartmentState of the thread used to execute commands within this RunspacePool. /// @@ -1286,7 +1285,6 @@ namespace System.Management.Automation.Runspaces _internalPool.ApartmentState = value; } } -#endif /// /// Gets Runspace asynchronously from the runspace pool. The caller diff --git a/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs b/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs index bae81e64e6..3215b8f2f6 100644 --- a/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs +++ b/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs @@ -132,10 +132,7 @@ namespace System.Management.Automation.Runspaces.Internal _initialSessionState = initialSessionState.Clone(); this.host = host; ThreadOptions = initialSessionState.ThreadOptions; -#if !CORECLR - // No ApartmentState In CoreCLR this.ApartmentState = initialSessionState.ApartmentState; -#endif pool = new Stack(); runspaceRequestQueue = new Queue(); ultimateRequestQueue = new Queue(); @@ -851,7 +848,6 @@ namespace System.Management.Automation.Runspaces.Internal /// internal PSThreadOptions ThreadOptions { get; set; } = PSThreadOptions.Default; -#if !CORECLR // No ApartmentState In CoreCLR /// /// The value of this property is propagated to all the Runspaces in this pool. /// @@ -859,7 +855,6 @@ namespace System.Management.Automation.Runspaces.Internal /// Any updates to the value of this property must be done before the RunspacePool is opened /// internal ApartmentState ApartmentState { get; set; } = Runspace.DefaultApartmentState; -#endif /// /// Gets Runspace asynchronously from the runspace pool. The caller @@ -1257,9 +1252,7 @@ namespace System.Management.Automation.Runspaces.Internal Runspace result = RunspaceFactory.CreateRunspaceFromSessionStateNoClone(host, _initialSessionState); result.ThreadOptions = this.ThreadOptions == PSThreadOptions.Default ? PSThreadOptions.ReuseThread : this.ThreadOptions; -#if !CORECLR // No ApartmentState In CoreCLR result.ApartmentState = this.ApartmentState; -#endif this.PropagateApplicationPrivateData(result); diff --git a/src/System.Management.Automation/engine/remoting/client/remoterunspace.cs b/src/System.Management.Automation/engine/remoting/client/remoterunspace.cs index 4a030da7e8..60f101d89f 100644 --- a/src/System.Management.Automation/engine/remoting/client/remoterunspace.cs +++ b/src/System.Management.Automation/engine/remoting/client/remoterunspace.cs @@ -554,9 +554,7 @@ namespace System.Management.Automation try { RunspacePool.ThreadOptions = this.ThreadOptions; -#if !CORECLR // No ApartmentState In CoreCLR RunspacePool.ApartmentState = this.ApartmentState; -#endif RunspacePool.Open(); } catch (InvalidRunspacePoolStateException e) diff --git a/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs b/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs index 986e2ae1eb..13f7d65c1b 100644 --- a/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs +++ b/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs @@ -8,6 +8,7 @@ using System.Globalization; using System.IO; using System.Security.AccessControl; using System.Text; +using System.Threading; using System.Management.Automation; using System.Management.Automation.Internal; @@ -1050,7 +1051,6 @@ else maxObjectSizeMB.Value, Environment.NewLine)); } -#if !CORECLR // No ApartmentState In CoreCLR if (threadAptState.HasValue) { initParameters.Append(string.Format(CultureInfo.InvariantCulture, @@ -1059,7 +1059,6 @@ else threadAptState.Value, Environment.NewLine)); } -#endif if (threadOptions.HasValue) { initParameters.Append(string.Format(CultureInfo.InvariantCulture, @@ -2041,7 +2040,6 @@ else internal PSCredential runAsCredential; internal bool isRunAsCredentialSpecified; -#if !CORECLR // No ApartmentState In CoreCLR /// /// ApartmentState of the Runspace created for the shell. /// @@ -2062,7 +2060,6 @@ else } internal ApartmentState? threadAptState; -#endif /// /// ThreadOptions of the Runspace created for the shell. @@ -3227,9 +3224,7 @@ Set-PSSessionConfiguration $args[0] $args[1] $args[2] $args[3] $args[4] $args[5] ConfigurationDataFromXML.MAXRCVDOBJSIZETOKEN, ConfigurationDataFromXML.MAXRCVDCMDSIZETOKEN, ConfigurationDataFromXML.THREADOPTIONSTOKEN, -#if !CORECLR // No ApartmentState In CoreCLR ConfigurationDataFromXML.THREADAPTSTATETOKEN, -#endif ConfigurationDataFromXML.PSVERSIONTOKEN, ConfigurationDataFromXML.MAXPSVERSIONTOKEN, ConfigurationDataFromXML.SESSIONCONFIGTOKEN, @@ -3854,12 +3849,10 @@ Set-PSSessionConfiguration $args[0] $args[1] $args[2] $args[3] $args[4] $args[5] result.Properties.Add(new PSNoteProperty(ConfigurationDataFromXML.MAXRCVDOBJSIZETOKEN, input)); } -#if !CORECLR // No ApartmentState In CoreCLR if (threadAptState.HasValue) { result.Properties.Add(new PSNoteProperty(ConfigurationDataFromXML.THREADAPTSTATETOKEN, threadAptState.Value)); } -#endif if (threadOptions.HasValue) { diff --git a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs index 3f19d2487f..5e7a88c949 100644 --- a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs +++ b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs @@ -3459,16 +3459,6 @@ namespace System.Management.Automation.Runspaces /// private void RunOnMTAThread(ThreadStart threadProc) { - // - // By default, non-OneCore PowerShell is launched with ApartmentState being STA. - // In this case, we need to create a separate thread, set its ApartmentState to MTA, - // and do the work. - // - // For OneCore PowerShell, its ApartmentState is always MTA. - // -#if CORECLR - threadProc(); -#else if (Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA) { threadProc(); @@ -3481,7 +3471,6 @@ namespace System.Management.Automation.Runspaces executionThread.Start(); executionThread.Join(); } -#endif } /// diff --git a/src/System.Management.Automation/engine/remoting/common/WireDataFormat/EncodeAndDecode.cs b/src/System.Management.Automation/engine/remoting/common/WireDataFormat/EncodeAndDecode.cs index c5a875f562..0ab8320853 100644 --- a/src/System.Management.Automation/engine/remoting/common/WireDataFormat/EncodeAndDecode.cs +++ b/src/System.Management.Automation/engine/remoting/common/WireDataFormat/EncodeAndDecode.cs @@ -677,11 +677,7 @@ namespace System.Management.Automation dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MinRunspaces, minRunspaces)); dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MaxRunspaces, maxRunspaces)); dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ThreadOptions, runspacePool.ThreadOptions)); -#if CORECLR // No ApartmentState In CoreCLR, default to MTA for outgoing objects - ApartmentState poolState = ApartmentState.MTA; -#else ApartmentState poolState = runspacePool.ApartmentState; -#endif dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ApartmentState, poolState)); dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ApplicationArguments, applicationArguments)); @@ -1113,11 +1109,7 @@ namespace System.Management.Automation hostInfo = new HostInfo(null); hostInfo.UseRunspaceHost = true; -#if CORECLR // No ApartmentState In CoreCLR, default to MTA for outgoing objects - ApartmentState passedApartmentState = ApartmentState.MTA; -#else ApartmentState passedApartmentState = rsPool.ApartmentState; -#endif dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ApartmentState, passedApartmentState)); dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.RemoteStreamOptions, RemoteStreamOptions.AddInvocationInfo)); dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.AddToHistory, false)); @@ -1130,11 +1122,7 @@ namespace System.Management.Automation hostInfo.UseRunspaceHost = true; } -#if CORECLR // No ApartmentState In CoreCLR, default to MTA for outgoing objects - ApartmentState passedApartmentState = ApartmentState.MTA; -#else ApartmentState passedApartmentState = settings.ApartmentState; -#endif dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ApartmentState, passedApartmentState)); dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.RemoteStreamOptions, settings.RemoteStreamOptions)); dataAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.AddToHistory, settings.AddToHistory)); @@ -2341,7 +2329,6 @@ namespace System.Management.Automation return GetPropertyValue(dataAsPSObject, RemoteDataNameStrings.IsNested); } -#if !CORECLR // No ApartmentState In CoreCLR /// /// Gets the invocation settings information from the message. /// @@ -2352,7 +2339,7 @@ namespace System.Management.Automation PSObject dataAsPSObject = PSObject.AsPSObject(data); return GetPropertyValue(dataAsPSObject, RemoteDataNameStrings.ApartmentState); } -#endif + /// /// Gets the stream options from the message. /// diff --git a/src/System.Management.Automation/engine/remoting/fanin/InitialSessionStateProvider.cs b/src/System.Management.Automation/engine/remoting/fanin/InitialSessionStateProvider.cs index 37718f9a5d..cb20f3e2e1 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/InitialSessionStateProvider.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/InitialSessionStateProvider.cs @@ -12,6 +12,7 @@ using System.Management.Automation.Internal; using System.Management.Automation.Runspaces; using System.Management.Automation.Tracing; using System.Reflection; +using System.Threading; using System.Xml; using Microsoft.PowerShell.Commands; @@ -44,9 +45,7 @@ namespace System.Management.Automation.Remoting internal const string MAXRCVDCMDSIZETOKEN = "psmaximumreceiveddatasizepercommandmb"; internal const string MAXRCVDCMDSIZETOKEN_CamelCase = "PSMaximumReceivedDataSizePerCommandMB"; internal const string THREADOPTIONSTOKEN = "pssessionthreadoptions"; -#if !CORECLR // No ApartmentState In CoreCLR internal const string THREADAPTSTATETOKEN = "pssessionthreadapartmentstate"; -#endif internal const string SESSIONCONFIGTOKEN = "sessionconfigurationdata"; internal const string PSVERSIONTOKEN = "PSVersion"; internal const string MAXPSVERSIONTOKEN = "MaxPSVersion"; @@ -68,10 +67,7 @@ namespace System.Management.Automation.Remoting internal int? MaxReceivedCommandSizeMB; // Used to set properties on the RunspacePool created for this shell. internal PSThreadOptions? ShellThreadOptions; - -#if !CORECLR // No ApartmentState In CoreCLR - internal Nullable ShellThreadApartmentState; -#endif + internal ApartmentState? ShellThreadApartmentState; internal PSSessionConfigurationData SessionConfigurationData; internal string ConfigFilePath; @@ -127,13 +123,11 @@ namespace System.Management.Automation.Remoting ShellThreadOptions = (PSThreadOptions)LanguagePrimitives.ConvertTo( optionValue, typeof(PSThreadOptions), CultureInfo.InvariantCulture); break; -#if !CORECLR // No ApartmentState In CoreCLR case THREADAPTSTATETOKEN: AssertValueNotAssigned(THREADAPTSTATETOKEN, ShellThreadApartmentState); - ShellThreadApartmentState = (System.Threading.ApartmentState)LanguagePrimitives.ConvertTo( - optionValue, typeof(System.Threading.ApartmentState), CultureInfo.InvariantCulture); + ShellThreadApartmentState = (ApartmentState)LanguagePrimitives.ConvertTo( + optionValue, typeof(ApartmentState), CultureInfo.InvariantCulture); break; -#endif case SESSIONCONFIGTOKEN: { AssertValueNotAssigned(SESSIONCONFIGTOKEN, SessionConfigurationData); diff --git a/src/System.Management.Automation/engine/remoting/server/ServerPowerShellDriver.cs b/src/System.Management.Automation/engine/remoting/server/ServerPowerShellDriver.cs index 08553a9b5a..8096a0e3f6 100644 --- a/src/System.Management.Automation/engine/remoting/server/ServerPowerShellDriver.cs +++ b/src/System.Management.Automation/engine/remoting/server/ServerPowerShellDriver.cs @@ -42,11 +42,8 @@ namespace System.Management.Automation // associated with this powershell private ServerRemoteHost _remoteHost; -#if !CORECLR - // No ApartmentState In CoreCLR // apartment state for this powershell private ApartmentState apartmentState; -#endif // Handles nested invocation of PS drivers. private IRSPDriverInvoke _psDriverInvoker; @@ -55,7 +52,6 @@ namespace System.Management.Automation #region Constructors -#if !CORECLR /// /// Default constructor for creating ServerPowerShellDrivers. /// @@ -85,66 +81,7 @@ namespace System.Management.Automation apartmentState, hostInfo, streamOptions, addToHistory, rsToUse, null) { } -#else - /// - /// Default constructor for creating ServerPowerShellDrivers. - /// - /// Decoded powershell object. - /// Extra pipeline to be run after completes. - /// Whether there is input for this powershell. - /// The client powershell id. - /// The client runspacepool id. - /// runspace pool driver - /// which is creating this powershell driver - /// host info using which the host for - /// this powershell will be constructed - /// Serialization options for the streams in this powershell. - /// - /// true if the command is to be added to history list of the runspace. false, otherwise. - /// - /// - /// If not null, this Runspace will be used to invoke Powershell. - /// If null, the RunspacePool pointed by will be used. - /// - internal ServerPowerShellDriver(PowerShell powershell, PowerShell extraPowerShell, bool noInput, Guid clientPowerShellId, - Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver, - HostInfo hostInfo, RemoteStreamOptions streamOptions, - bool addToHistory, Runspace rsToUse) - : this(powershell, extraPowerShell, noInput, clientPowerShellId, clientRunspacePoolId, runspacePoolDriver, - hostInfo, streamOptions, addToHistory, rsToUse, null) - { - } -#endif -#if CORECLR - /// - /// Default constructor for creating ServerPowerShellDrivers. - /// - /// Decoded powershell object. - /// Extra pipeline to be run after completes. - /// Whether there is input for this powershell. - /// The client powershell id. - /// The client runspacepool id. - /// runspace pool driver - /// which is creating this powershell driver - /// host info using which the host for - /// this powershell will be constructed - /// Serialization options for the streams in this powershell. - /// - /// true if the command is to be added to history list of the runspace. false, otherwise. - /// - /// - /// If not null, this Runspace will be used to invoke Powershell. - /// If null, the RunspacePool pointed by will be used. - /// - /// - /// If not null, this is used as another source of output sent to the client. - /// - internal ServerPowerShellDriver(PowerShell powershell, PowerShell extraPowerShell, bool noInput, Guid clientPowerShellId, - Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver, - HostInfo hostInfo, RemoteStreamOptions streamOptions, - bool addToHistory, Runspace rsToUse, PSDataCollection output) -#else /// /// Default constructor for creating ServerPowerShellDrivers. /// @@ -173,14 +110,11 @@ namespace System.Management.Automation Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver, ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions, bool addToHistory, Runspace rsToUse, PSDataCollection output) -#endif { InstanceId = clientPowerShellId; RunspacePoolId = clientRunspacePoolId; RemoteStreamOptions = streamOptions; -#if !CORECLR // No ApartmentState In CoreCLR this.apartmentState = apartmentState; -#endif LocalPowerShell = powershell; _extraPowerShell = extraPowerShell; _localPowerShellOutput = new PSDataCollection(); @@ -298,9 +232,7 @@ namespace System.Management.Automation } PSInvocationSettings settings = new PSInvocationSettings(); -#if !CORECLR // No ApartmentState In CoreCLR settings.ApartmentState = apartmentState; -#endif settings.Host = _remoteHost; // Flow the impersonation policy to pipeline execution thread diff --git a/src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs b/src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs index aa8a6dd136..2f6972dca3 100644 --- a/src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs +++ b/src/System.Management.Automation/engine/remoting/server/ServerRunspacePoolDriver.cs @@ -95,46 +95,6 @@ namespace System.Management.Automation #region Constructors -#if CORECLR // No ApartmentState In CoreCLR - /// - /// Creates the runspace pool driver. - /// - /// Client runspace pool id to associate. - /// transport manager associated with this - /// runspace pool driver - /// Maximum runspaces to open. - /// Minimum runspaces to open. - /// Threading options for the runspaces in the pool. - /// Host information about client side host. - /// - /// Contains: - /// 1. Script to run after a RunspacePool/Runspace is created in this session. - /// For RunspacePool case, every newly created Runspace (in the pool) will run - /// this script. - /// 2. ThreadOptions for RunspacePool/Runspace - /// 3. ThreadApartment for RunspacePool/Runspace - /// - /// Configuration of the runspace. - /// Application private data. - /// True if the driver is being created by an administrator. - /// Server capability reported to the client during negotiation (not the actual capability). - /// Client PowerShell version. - /// Optional endpoint configuration name to create a pushed configured runspace. - internal ServerRunspacePoolDriver( - Guid clientRunspacePoolId, - int minRunspaces, - int maxRunspaces, - PSThreadOptions threadOptions, - HostInfo hostInfo, - InitialSessionState initialSessionState, - PSPrimitiveDictionary applicationPrivateData, - ConfigurationDataFromXML configData, - AbstractServerSessionTransportManager transportManager, - bool isAdministrator, - RemoteSessionCapability serverCapability, - Version psClientVersion, - string configurationName) -#else /// /// Creates the runspace pool driver. /// @@ -175,7 +135,6 @@ namespace System.Management.Automation RemoteSessionCapability serverCapability, Version psClientVersion, string configurationName) -#endif { Dbg.Assert(configData != null, "ConfigurationData cannot be null"); @@ -213,7 +172,6 @@ namespace System.Management.Automation RunspacePool.ThreadOptions = threadOptions; } -#if !CORECLR // No ApartmentState In CoreCLR // Set Thread ApartmentState for this RunspacePool ApartmentState serverApartmentState = configData.ShellThreadApartmentState.HasValue ? configData.ShellThreadApartmentState.Value : Runspace.DefaultApartmentState; @@ -225,7 +183,6 @@ namespace System.Management.Automation { RunspacePool.ApartmentState = apartmentState; } -#endif // If we have a runspace pool with a single runspace then we can run nested pipelines on // on it in a single pipeline invoke thread. @@ -579,9 +536,7 @@ namespace System.Management.Automation Guid.Empty, this.InstanceId, this, -#if !CORECLR // No ApartmentState In CoreCLR args.Runspace.ApartmentState, -#endif hostInfo, RemoteStreamOptions.AddInvocationInfo, false, @@ -760,9 +715,7 @@ namespace System.Management.Automation // invoked from within the driver HostInfo hostInfo = RemotingDecoder.GetHostInfo(data.Data); -#if !CORECLR // No ApartmentState In CoreCLR ApartmentState apartmentState = RemotingDecoder.GetApartmentState(data.Data); -#endif RemoteStreamOptions streamOptions = RemotingDecoder.GetRemoteStreamOptions(data.Data); PowerShell powershell = RemotingDecoder.GetPowerShell(data.Data); @@ -824,9 +777,7 @@ namespace System.Management.Automation data.PowerShellId, data.RunspacePoolId, this, -#if !CORECLR // No ApartmentState In CoreCLR apartmentState, -#endif hostInfo, streamOptions, addToHistory, @@ -883,9 +834,7 @@ namespace System.Management.Automation data.PowerShellId, data.RunspacePoolId, this, -#if !CORECLR // No ApartmentState In CoreCLR apartmentState, -#endif hostInfo, streamOptions, addToHistory, @@ -904,9 +853,7 @@ namespace System.Management.Automation data.PowerShellId, data.RunspacePoolId, this, -#if !CORECLR // No ApartmentState In CoreCLR apartmentState, -#endif _remoteHost, hostInfo, streamOptions, @@ -937,9 +884,7 @@ namespace System.Management.Automation data.PowerShellId, data.RunspacePoolId, this, -#if !CORECLR // No ApartmentState In CoreCLR apartmentState, -#endif hostInfo, streamOptions, addToHistory, @@ -971,9 +916,7 @@ namespace System.Management.Automation data.PowerShellId, data.RunspacePoolId, this, -#if !CORECLR // No ApartmentState In CoreCLR apartmentState, -#endif hostInfo, streamOptions, addToHistory, @@ -1085,9 +1028,7 @@ namespace System.Management.Automation data.PowerShellId, data.RunspacePoolId, this, -#if !CORECLR // No ApartmentState In CoreCLR ApartmentState.Unknown, -#endif useRunspaceHost, 0 /* stream options */, false /* addToHistory */, @@ -1224,9 +1165,7 @@ namespace System.Management.Automation powershellId, runspacePoolId, this, -#if !CORECLR // No ApartmentState In CoreCLR ApartmentState.MTA, -#endif hostInfo, streamOptions, addToHistory, @@ -2519,9 +2458,7 @@ namespace System.Management.Automation Guid powershellId, Guid runspacePoolId, ServerRunspacePoolDriver runspacePoolDriver, -#if !CORECLR // No ApartmentState In CoreCLR ApartmentState apartmentState, -#endif ServerRemoteHost remoteHost, HostInfo hostInfo, RemoteStreamOptions streamOptions, @@ -2557,9 +2494,7 @@ namespace System.Management.Automation powershellId, runspacePoolId, runspacePoolDriver, -#if !CORECLR // No ApartmentState In CoreCLR apartmentState, -#endif hostInfo, streamOptions, addToHistory, diff --git a/src/System.Management.Automation/engine/remoting/server/ServerSteppablePipelineDriver.cs b/src/System.Management.Automation/engine/remoting/server/ServerSteppablePipelineDriver.cs index b87fc8c6c5..f94c5e3e39 100644 --- a/src/System.Management.Automation/engine/remoting/server/ServerSteppablePipelineDriver.cs +++ b/src/System.Management.Automation/engine/remoting/server/ServerSteppablePipelineDriver.cs @@ -74,9 +74,7 @@ namespace System.Management.Automation // was created private bool _addToHistory; // associated with this powershell -#if !CORECLR // No ApartmentState In CoreCLR private ApartmentState apartmentState; // apartment state for this powershell -#endif // pipeline that runs the actual command. private ServerSteppablePipelineSubscriber _eventSubscriber; @@ -84,36 +82,6 @@ namespace System.Management.Automation #endregion -#if CORECLR // No ApartmentState In CoreCLR - /// - /// Default constructor for creating ServerSteppablePipelineDriver...Used by server to concurrently - /// run 2 pipelines. - /// - /// Decoded powershell object. - /// Whether there is input for this powershell. - /// The client powershell id. - /// The client runspacepool id. - /// runspace pool driver - /// which is creating this powershell driver - /// host info using which the host for - /// this powershell will be constructed - /// Serialization options for the streams in this powershell. - /// - /// true if the command is to be added to history list of the runspace. false, otherwise. - /// - /// - /// If not null, this Runspace will be used to invoke Powershell. - /// If null, the RunspacePool pointed by will be used. - /// - /// - /// Steppable pipeline event subscriber - /// - /// Input collection of the PowerShell pipeline. - internal ServerSteppablePipelineDriver(PowerShell powershell, bool noInput, Guid clientPowerShellId, - Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver, - HostInfo hostInfo, RemoteStreamOptions streamOptions, - bool addToHistory, Runspace rsToUse, ServerSteppablePipelineSubscriber eventSubscriber, PSDataCollection powershellInput) -#else /// /// Default constructor for creating ServerSteppablePipelineDriver...Used by server to concurrently /// run 2 pipelines. @@ -143,15 +111,12 @@ namespace System.Management.Automation Guid clientRunspacePoolId, ServerRunspacePoolDriver runspacePoolDriver, ApartmentState apartmentState, HostInfo hostInfo, RemoteStreamOptions streamOptions, bool addToHistory, Runspace rsToUse, ServerSteppablePipelineSubscriber eventSubscriber, PSDataCollection powershellInput) -#endif { LocalPowerShell = powershell; InstanceId = clientPowerShellId; RunspacePoolId = clientRunspacePoolId; RemoteStreamOptions = streamOptions; -#if !CORECLR // No ApartmentState In CoreCLR this.apartmentState = apartmentState; -#endif NoInput = noInput; _addToHistory = addToHistory; _eventSubscriber = eventSubscriber; diff --git a/src/System.Management.Automation/engine/remoting/server/serverremotesession.cs b/src/System.Management.Automation/engine/remoting/server/serverremotesession.cs index 4459bd21c9..004f5fb00e 100644 --- a/src/System.Management.Automation/engine/remoting/server/serverremotesession.cs +++ b/src/System.Management.Automation/engine/remoting/server/serverremotesession.cs @@ -856,9 +856,7 @@ namespace System.Management.Automation.Remoting int minRunspaces = RemotingDecoder.GetMinRunspaces(rcvdData.Data); int maxRunspaces = RemotingDecoder.GetMaxRunspaces(rcvdData.Data); PSThreadOptions threadOptions = RemotingDecoder.GetThreadOptions(rcvdData.Data); -#if !CORECLR // No ApartmentState In CoreCLR ApartmentState apartmentState = RemotingDecoder.GetApartmentState(rcvdData.Data); -#endif HostInfo hostInfo = RemotingDecoder.GetHostInfo(rcvdData.Data); if (_runspacePoolDriver != null) @@ -878,9 +876,7 @@ namespace System.Management.Automation.Remoting minRunspaces, maxRunspaces, threadOptions, -#if !CORECLR // No ApartmentState In CoreCLR apartmentState, -#endif hostInfo, rsSessionStateToUse, applicationPrivateData, diff --git a/test/powershell/Host/ConsoleHost.Tests.ps1 b/test/powershell/Host/ConsoleHost.Tests.ps1 index 1e967dfa50..4bbc135770 100644 --- a/test/powershell/Host/ConsoleHost.Tests.ps1 +++ b/test/powershell/Host/ConsoleHost.Tests.ps1 @@ -240,7 +240,7 @@ Describe "ConsoleHost unit tests" -tags "Feature" { '@ $testFilePath = Join-Path $TestDrive "test.ps1" Set-Content -Path $testFilePath -Value $testScript - $observed = echo hello | pwsh $testFilePath e - + $observed = echo hello | pwsh -noprofile $testFilePath e - $observed | Should -BeExactly "h-llo" } } @@ -711,8 +711,62 @@ namespace StackTest { $longPipeName = [string]::new("A", 200) "`$pid" | & $powershell -CustomPipeName $longPipeName -c - - # 64 is the ExitCode for BadCommandLineParameter - $LASTEXITCODE | Should -Be 64 + $LASTEXITCODE | Should -Be $ExitCodeBadCommandLineParameter + } + } + + Context "ApartmentState WPF tests" -Tag Slow { + + It "WPF requires STA and will work" -Skip:(!$IsWindows -or [System.Management.Automation.Platform]::IsNanoServer) { + add-type -AssemblyName presentationframework + + $xaml = [xml]@" + + +"@ + + $reader = [System.Xml.XmlNodeReader]::new($xaml) + $Window = [System.Windows.Markup.XamlReader]::Load($reader) + # This will throw an exception if MTA + { $Window.Show() } | Should -Not -Throw + $Window.Close() + } + + } + + Context "ApartmentState tests" { + + It "Default apartment state for main thread is STA" -Skip:(!$IsWindows -or [System.Management.Automation.Platform]::IsNanoServer) { + [System.Threading.Thread]::CurrentThread.GetApartmentState() | Should -BeExactly "STA" + } + + It "Default apartment state for new runspace is MTA" -Skip:(!$IsWindows) { + $ps = [powershell]::Create() + $ps.AddScript({[System.Threading.Thread]::CurrentThread.GetApartmentState()}) + $ps.Invoke() | Should -BeExactly "MTA" + } + + It "Should be able to set apartment state to: " -Skip:(!$IsWindows -or [System.Management.Automation.Platform]::IsNanoServer) -TestCases @( + @{ apartment = "STA"; switch = "-sta" } + @{ apartment = "MTA"; switch = "-mta" } + ) { + param ($apartment, $switch) + + & $powershell $switch -noprofile -command "[System.Threading.Thread]::CurrentThread.GetApartmentState()" | Should -BeExactly $apartment + } + + It "Should fail to set apartment state to: " -Skip:($IsWindows -and ![System.Management.Automation.Platform]::IsNanoServer) -TestCases @( + @{ switch = "-sta" } + @{ switch = "-mta" } + ) { + param ($switch) + + & $powershell $switch -noprofile -command exit + $LASTEXITCODE | Should -Be $ExitCodeBadCommandLineParameter } } } @@ -855,7 +909,7 @@ Describe 'Pwsh startup in directories that contain wild cards' -Tag CI { param ( $dirname ) try { Push-Location -LiteralPath "${TESTDRIVE}/${dirname}" - $result = & $powershell -c '(Get-Item .).Name' + $result = & $powershell -noprofile -c '(Get-Item .).Name' $result | Should -BeExactly $dirname } finally {