Skip to content

Commit 30010f7

Browse files
authored
Set Runspaces to use STA when running in Windows PowerShell (#769)
1 parent a1ac5ef commit 30010f7

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

src/PowerShellEditorServices/Session/PowerShellContext.cs

+25
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
using System.Collections.ObjectModel;
99
using System.Globalization;
1010
using System.IO;
11+
using System.Runtime.InteropServices;
1112
using System.Linq;
1213
using System.Management.Automation.Host;
1314
using System.Management.Automation.Remoting;
1415
using System.Management.Automation.Runspaces;
16+
using System.Reflection;
1517
using System.Text;
1618
using System.Text.RegularExpressions;
1719
using System.Threading;
@@ -31,6 +33,21 @@ namespace Microsoft.PowerShell.EditorServices
3133
/// </summary>
3234
public class PowerShellContext : IDisposable, IHostSupportsInteractiveSession
3335
{
36+
private const string DotNetFrameworkDescription = ".NET Framework";
37+
38+
private static readonly Action<Runspace, ApartmentState> s_runspaceApartmentStateSetter;
39+
40+
static PowerShellContext()
41+
{
42+
// PowerShell ApartmentState APIs aren't available in PSStandard, so we need to use reflection
43+
if (RuntimeInformation.FrameworkDescription.Equals(DotNetFrameworkDescription))
44+
{
45+
MethodInfo setterInfo = typeof(Runspace).GetProperty("ApartmentState").GetSetMethod();
46+
Delegate setter = Delegate.CreateDelegate(typeof(Action<Runspace, ApartmentState>), firstArgument: null, method: setterInfo);
47+
s_runspaceApartmentStateSetter = (Action<Runspace, ApartmentState>)setter;
48+
}
49+
}
50+
3451
#region Fields
3552

3653
private readonly SemaphoreSlim resumeRequestHandle = AsyncUtils.CreateSimpleLockingSemaphore();
@@ -174,6 +191,14 @@ public static Runspace CreateRunspace(PSHost psHost)
174191
}
175192

176193
Runspace runspace = RunspaceFactory.CreateRunspace(psHost, initialSessionState);
194+
195+
// Windows PowerShell must be hosted in STA mode
196+
// This must be set on the runspace *before* it is opened
197+
if (RuntimeInformation.FrameworkDescription.Equals(DotNetFrameworkDescription))
198+
{
199+
s_runspaceApartmentStateSetter(runspace, ApartmentState.STA);
200+
}
201+
177202
runspace.ThreadOptions = PSThreadOptions.ReuseThread;
178203
runspace.Open();
179204

0 commit comments

Comments
 (0)