-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Add documentation about hosting PowerShell Core #3409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
This is really cool! Quick question: does this tie the application to a specific version of PowerShell Core? Specifically, if I build against Microsoft.PowerShell.SDK of a specific version, is there any way I could get my application to load assemblies from a newer version of PowerShell Core if I have its filesystem path? I'm asking because I'm re-evaluating whether I could make PowerShell Editor Services a standalone process again, not a module running inside of powershell.exe. |
|
@daviwil When you build your application this way, a specific version (depending on the package version you use) of PowerShell Core assemblies will be published to your publish folder. But your application is not necessarily tied to them. You can just replace them with a newer version of PS Core assemblies, and your application should continue to work as long as the new PS Core assemblies are targeting the same set of .NET Core packages. There is one problem, though -- we haven't published any powershell core packages for Linux/OSX yet. There is a workaround. Build your application using the existing powershell core NuGet packages, but replace the powershell assemblies with those from a Linux/OSX package. That hopefully would work. |
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>netstandard1.6</TargetFramework> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please clarify why "netstandard1.6", not "netcoreapp1.1" as in docs/host-powershell/sample-dotnet1.1/MyApp/MyApp.csproj ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Becuase Logic.dll is an assembly Library while MyApp.exe is an executable. If you inspect the dependencies of Microsoft.NetCore.App, you will see that it depends on NetStandard.Library and also include the runtime and host related packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
docs/host-powershell/README.md
Outdated
| ### Overview | ||
|
|
||
| Due to the lack of necessary APIs for manipulating assemblies in .NET Core 1.1 and prior, | ||
| PowerShell Core needs to control assembly loading via our customized `AssemblyLoadContext` in order to do tasks like type resolution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a link to the file here?
docs/host-powershell/README.md
Outdated
| `SetPowerShellAssemblyLoadContext` and `InitializeAndCallEntryMethod`. | ||
| They are for different scenarios: | ||
|
|
||
| - For `SetPowerShellAssemblyLoadContext`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see the topic set apart from the rest of the sentence to make it a little more obvious that it is the topic of the bullet point. Something like:
SetPowerShellAssemblyLoadContext- It is designed to ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
docs/host-powershell/README.md
Outdated
| They are for different scenarios: | ||
|
|
||
| - For `SetPowerShellAssemblyLoadContext`, | ||
| it's designed to be used by a native host whose TPA (Trusted Platform Assemblies) list doesn't include powershell assemblies, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TPA should be in parenthesis and follow --> Trusted Platform Assemblies (TPA)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
| When using this API, `PowerShellAssemblyLoadContextInitializer` will set up a new load context to handle all assemblies. | ||
| PowerShell Core itself also uses this API for [bootstrapping][]. | ||
|
|
||
| This documentation only covers the `InitializeAndCallEntryMethod` API, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Links to additional background information would be helpful as well. Did the .Net team write up any documentation on consuming these two APIs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We own those 2 APIs. They are exposed from PowerShellAssemblyLoadContextInitializer.
docs/host-powershell/README.md
Outdated
|
|
||
| ### Example | ||
|
|
||
| The following code is how you host Windows PowerShell in an application. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested rewording:
This example demonstrates how to host Windows PowerShell in an application. Business logic should be inserted within the Main method.
Another thought: What about linking to the MSDN documentation for this? It is a supported scenario for Windows PowerShell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't intend to introduce how to host Windows PowerShell in full .NET application.
The code about hosting Windows PowerShell is used as a comparison to show what you need to do in .NET Core for the same purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I reworded it as you suggested.
| The entry point `'Main'` method shall do one thing only -- let the powershell load context load `'Logic.dll'` and start the execution of the business logic. | ||
| Once the execution starts this way, all further assembly loading requests will be handled by the powershell load context. | ||
|
|
||
| So the above example needs to be altered as follows in a .NET Core application: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested rewording:
The following example demonstrates hosting PowerShell Core in a .Net Core Application:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. The code about hosting windows powershell is used as a comparison to show how this familiar code should be altered when it comes to .NET Core 1.1.
docs/host-powershell/README.md
Outdated
| This documentation only covers the `InitializeAndCallEntryMethod` API, | ||
| as it's what you need when building a .NET Core application with .NET CLI. | ||
|
|
||
| ### Example |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be three sub-headings here:
- Hosting Windows PowerShell
- Hosting PowerShell in .Net Core
- Example .Net Core program
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
|
@daxian-dbw thanks for the explanation! Seems like it would be more complex go have my own process hosting PowerShell so I think I'll stick with my current model of being hosted inside of powershell.exe :) |
|
@mirichmo I addressed your comments. Could you please take another look? |
joeyaiello
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few small changes, otherwise looks really useful to me.
docs/host-powershell/README.md
Outdated
| They are for different scenarios: | ||
|
|
||
| - `SetPowerShellAssemblyLoadContext` - It's designed to be used by a native host | ||
| whose Trusted Platform Assemblies (TPA) do not include powershell assemblies, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properly case "PowerShell"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
docs/host-powershell/README.md
Outdated
| Then PowerShell Core will depend on the default load context to handle TPA and the `Resolving` event to handle other assemblies. | ||
|
|
||
| - `InitializeAndCallEntryMethod` - It's designed to be used with `dotnet.exe` | ||
| where the TPA list includes powershell assemblies. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properly case "PowerShell"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
docs/host-powershell/README.md
Outdated
| ### Comparison - Hosting Windows PowerShell vs. Hosting PowerShell Core | ||
|
|
||
| The following code demonstrates how to host Windows PowerShell in an application. | ||
| As shown below, you can insert your business logic code directly in the `'Main'` method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason to use both backticks and single quotes. Backticks will do here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
docs/host-powershell/README.md
Outdated
| } | ||
| ``` | ||
|
|
||
| However, when it comes to hosting PowerShell Core, there will be a layer of redirection for the powershell load context to take effect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"PowerShell" casing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
docs/host-powershell/README.md
Outdated
| ``` | ||
|
|
||
| However, when it comes to hosting PowerShell Core, there will be a layer of redirection for the powershell load context to take effect. | ||
| In a .NET Core application, the entry point assembly that contains the `'Main'` method is loaded in the default load context, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No single quotes needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
docs/host-powershell/README.md
Outdated
| In a .NET Core application, the entry point assembly that contains the `'Main'` method is loaded in the default load context, | ||
| and thus all assemblies referenced by the entry point assembly, implicitly or explicitly, will also be loaded into the default load context. | ||
|
|
||
| In order to have the powershell load context to control assembly loading for the execution of an application, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PowerShell casing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
docs/host-powershell/README.md
Outdated
| and thus all assemblies referenced by the entry point assembly, implicitly or explicitly, will also be loaded into the default load context. | ||
|
|
||
| In order to have the powershell load context to control assembly loading for the execution of an application, | ||
| the business logic code needs to be extracted out of the entry point assembly and put into a different assembly, say `'Logic.dll'`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No single quotes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
docs/host-powershell/README.md
Outdated
|
|
||
| In order to have the powershell load context to control assembly loading for the execution of an application, | ||
| the business logic code needs to be extracted out of the entry point assembly and put into a different assembly, say `'Logic.dll'`. | ||
| The entry point `'Main'` method shall do one thing only -- let the powershell load context load `'Logic.dll'` and start the execution of the business logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No single quotes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
| ```powershell | ||
| dotnet restore .\MyApp\MyApp.csproj | ||
| dotnet publish .\MyApp -c release -r win10-x64 | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has this document assumed that the user has installed dotnet-cli? Might it be worth putting a pointer to environment instructions (preferably not owned by us) at the top of the document?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, is this the same on Linux with a different RID? Might that be worth calling out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, as discussed above, 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, but dotnet pack doesn't seem to support that.
#3417 is opened to track this.
|
@joeyaiello @mirichmo All comments have been addressed. Can you please take another look? |
joeyaiello
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
New commits have been pushed to address the comments.
Fix #2291
Add documentation about how to host PowerShell Core in .NET Core application.