Skip to content

Commit 575ae89

Browse files
committed
Set Runspaces to use STA when running in Windows PowerShell (PowerShell#769)
Update PSStandard dependency (PowerShell#771)
1 parent 449cc21 commit 575ae89

File tree

3 files changed

+26
-6
lines changed

3 files changed

+26
-6
lines changed

src/PowerShellEditorServices/PowerShellEditorServices.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
</PropertyGroup>
1414
<ItemGroup>
1515
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
16-
<PackageReference Include="PowerShellStandard.Library" Version="5.1.0-preview-06" PrivateAssets="All"/>
16+
<PackageReference Include="PowerShellStandard.Library" Version="5.1.0-RC1" PrivateAssets="All"/>
1717
<PackageReference Include="UnixConsoleEcho" Version="0.1.0" />
1818
<PackageReference Include="Serilog" Version="2.7.1" />
1919
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />

src/PowerShellEditorServices/Session/InvocationEventQueue.cs

-5
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,6 @@ private void OnInvokerUnsubscribed(object sender, PSEventUnsubscribedEventArgs e
225225
CreateInvocationSubscriber();
226226
}
227227

228-
private void OnInvokerUnsubscribed(object sender, PSEventArgs e)
229-
{
230-
CreateInvocationSubscriber();
231-
}
232-
233228
private void SetSubscriberExecutionThreadWithReflection(PSEventSubscriber subscriber)
234229
{
235230
// We need to create the PowerShell object in the same thread so we can get a nested

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;
@@ -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)