Repository navigation
Provide a way to host PowerShell in a CoreCLR application #2291
Copy link
Copy link
Closed
Labels
Issue-Metaan issue used to track multiple issuesan issue used to track multiple issuesWG-Maintainers-Buildspecific to affecting the buildspecific to affecting the build
Milestone
Description
This is follow-up from #2284
Steps to reproduce
Create a simple coreclr app that hosts powershell thru Microsoft.PowerShell.SDK
Note: the current function of Microsoft.PowerShell.SDK is to provide an ability to compile binary modules that then could be imported and used in PowerShell on any platform. This issue asks a question: should we allow the same nuget package to enable hosting scenario?
Program.cs
using System;
using System.Management.Automation;
class Program
{
static void Main(string[] args)
{
PowerShellAssemblyLoadContextInitializer.SetPowerShellAssemblyLoadContext(AppContext.BaseDirectory);
using (var ps = PowerShell.Create())
{
ps.AddScript("Get-Process | Out-String");
var result = ps.Invoke()[0];
Console.WriteLine(result.ToString());
}
}
}project.json
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"Microsoft.PowerShell.SDK" : "1.0.0-alpha10"
},
"imports": "dnxcore50"
}
}
}nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<!-- install packages to a custom path -->
<add key="repositoryPath" value="Packages"/>
</config>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="powershell-core" value="https://powershell.myget.org/F/powershell-core/api/v3/index.json" />
</packageSources>
</configuration>dotnet restore works fine, dotnet run doesn't
Expected behavior
You should be able to run and execute
Actual behavior
On Unix (note that 6.0.0-alpha10 package doesn't have libs compile under Unix configuration, so that's expected)
Unhandled Exception: System.TypeInitializationException: The type initializer for 'System.Management.Automation.Runspaces.RunspaceFactory' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'api-ms-win-eventing-provider-l1-1-0.dll': The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
at System.Management.Automation.Tracing.EtwActivity.UnsafeNativeMethods.EventActivityIdControl(ActivityControlCode controlCode, Guid& activityId)
at System.Management.Automation.Tracing.EtwActivity.GetActivityId()
at System.Management.Automation.Runspaces.RunspaceFactory..cctor()
--- End of inner exception stack trace ---
at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace()
at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync)
at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable input, PSDataCollection`1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.Invoke()
at Program.Main(String[] args)
On Windows
Unhandled Exception: System.Management.Automation.Runspaces.PSSnapInException: Cannot load Windows PowerShell snap-in Microsoft.PowerShell.Diagnostics because of the following error: Could not load file or assembly 'Microsoft.PowerShell.Commands'. The system cannot find the file specified.
at System.Management.Automation.Runspaces.RunspaceConfigForSingleShell.LoadMshSnapinAssembly(PSSnapInInfo mshsnapinInfo)
at System.Management.Automation.Runspaces.RunspaceConfigForSingleShell.LoadPSSnapIn(PSSnapInInfo mshsnapinInfo)
at System.Management.Automation.Runspaces.RunspaceConfigForSingleShell.LoadPSSnapIns(Collection`1 mshsnapinInfos, PSConsoleLoadException& warning)
at System.Management.Automation.Runspaces.RunspaceConfigForSingleShell.LoadConsole(PSConsoleLoadException& warning)
at System.Management.Automation.Runspaces.RunspaceConfigForSingleShell.CreateDefaultConfiguration()
at System.Management.Automation.Runspaces.RunspaceConfiguration.Create()
at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(PSHost host)
at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace()
at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync)
at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable input, PSDataCollection`1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.Invoke()
at Program.Main(String[] args)
Environment data
> $PSVersionTable
Name Value
---- -----
PSVersion 6.0.0-alpha
PSEdition Core
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 3.0.0.0
GitCommitId v6.0.0-alpha.10
CLRVersion
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Issue-Metaan issue used to track multiple issuesan issue used to track multiple issuesWG-Maintainers-Buildspecific to affecting the buildspecific to affecting the build
Activity
daviwil commentedon Sep 17, 2016
Hosting PowerShell in your own process is more difficult due to the necessity of loading PowerShell's AssemblyLoadContext before CoreCLR's, or at least this is the impression I came away with after talking to Dongbo Wang (@daxian-dbw). Dongbo should be able to tell you more about it.
vors commentedon Sep 17, 2016
My understanding is it doesn't have to be before loading coreclr. In https://github.com/PowerShell/PowerShell/blob/master/src/powershell/Program.cs we are doing exactly that: initializing ALC in the managed code.
I included a line
which I took from our XUnit tests, but it may need some alterations.
Actually, that's indeed could be the problem with windows version (improper ALC init).
daxian-dbw commentedon Sep 19, 2016
For a CoreCLR application to host powershell, if the powershell assemblies are in its TPA list, then it has to use one of the
Initialize*method to call into the actual entry point:You can find an example at https://github.com/PowerShell/PowerShell/blob/master/src/powershell/Program.cs#L27
SetPowerShellAssemblyLoadContextis for CoreCLR applications that don't have powershell assemblies in their TPA list, which are usually native CoreCLR hosts.Initialize*APIs are for CoreCLR applications that have powershell assemblies in their TPA list, which are usually managed hosts that leverage dotnet.exe.erwinwildenburg commentedon Sep 28, 2016
If I add the following code it works:
PowerShellAssemblyLoadContextInitializer.SetPowerShellAssemblyLoadContext("C:\\Program Files\\PowerShell\\6.0.0.10");Seems like the required dll's are not being copied to the bin folder.
For example:
iztokp commentedon Jan 19, 2017
Any hints on how to make this work on Linux (CentOS)?
[-]Provide a way to host powershell in coreclr application[/-][+]Provide a way to host Powershell in a CoreCLR application[/+][-]Provide a way to host Powershell in a CoreCLR application[/-][+]Provide a way to host PowerShell in a CoreCLR application[/+]daxian-dbw commentedon Mar 25, 2017
A documentation about hosting powershell core is added: https://github.com/PowerShell/PowerShell/tree/master/docs/host-powershell
Iztok Prelog (@iztokp) Unfortunately, as discussed here, all powershell NuGet packages that have been published so far only contain powershell assemblies built specifically for Windows. We need to publish NuGet packages that contain both Windows and Unix assemblies (#3417 is opened to track this), but
dotnet packdoesn't seem to support that.