Skip to content

Commit bda319a

Browse files
rjmholtTylerLeonhardt
authored andcommitted
Set Runspaces to use STA when running in Windows PowerShell (PowerShell#769)
1 parent ab1913b commit bda319a

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
@@ -9,10 +9,12 @@
99
using System.ComponentModel;
1010
using System.Globalization;
1111
using System.IO;
12+
using System.Runtime.InteropServices;
1213
using System.Linq;
1314
using System.Management.Automation.Host;
1415
using System.Management.Automation.Remoting;
1516
using System.Management.Automation.Runspaces;
17+
using System.Reflection;
1618
using System.Text;
1719
using System.Text.RegularExpressions;
1820
using System.Threading;
@@ -32,6 +34,21 @@ namespace Microsoft.PowerShell.EditorServices
3234
/// </summary>
3335
public class PowerShellContext : IDisposable, IHostSupportsInteractiveSession
3436
{
37+
private const string DotNetFrameworkDescription = ".NET Framework";
38+
39+
private static readonly Action<Runspace, ApartmentState> s_runspaceApartmentStateSetter;
40+
41+
static PowerShellContext()
42+
{
43+
// PowerShell ApartmentState APIs aren't available in PSStandard, so we need to use reflection
44+
if (RuntimeInformation.FrameworkDescription.Equals(DotNetFrameworkDescription))
45+
{
46+
MethodInfo setterInfo = typeof(Runspace).GetProperty("ApartmentState").GetSetMethod();
47+
Delegate setter = Delegate.CreateDelegate(typeof(Action<Runspace, ApartmentState>), firstArgument: null, method: setterInfo);
48+
s_runspaceApartmentStateSetter = (Action<Runspace, ApartmentState>)setter;
49+
}
50+
}
51+
3552
#region Fields
3653

3754
private readonly SemaphoreSlim resumeRequestHandle = AsyncUtils.CreateSimpleLockingSemaphore();
@@ -175,6 +192,14 @@ public static Runspace CreateRunspace(PSHost psHost)
175192
}
176193

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

0 commit comments

Comments
 (0)