Add documentation about hosting PowerShell Core#3409
Add documentation about hosting PowerShell Core#3409mirichmo merged 5 commits intoPowerShell:masterfrom
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.
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.
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.
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.
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.
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 ...
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.
TPA should be in parenthesis and follow --> Trusted Platform Assemblies (TPA)
| 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.
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.
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.
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.
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.
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.
Suggested rewording:
The following example demonstrates hosting PowerShell Core in a .Net Core Application:
There was a problem hiding this comment.
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.
There should be three sub-headings here:
- Hosting Windows PowerShell
- Hosting PowerShell in .Net Core
- Example .Net Core program
|
@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.
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.
Properly case "PowerShell"
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.
Properly case "PowerShell"
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.
No reason to use both backticks and single quotes. Backticks will do here.
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. |
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.
No single quotes needed
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, |
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'`. |
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. |
| ```powershell | ||
| dotnet restore .\MyApp\MyApp.csproj | ||
| dotnet publish .\MyApp -c release -r win10-x64 | ||
| ``` |
There was a problem hiding this comment.
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.
Also, is this the same on Linux with a different RID? Might that be worth calling out?
There was a problem hiding this comment.
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? |
New commits have been pushed to address the comments.
Fix #2291
Add documentation about how to host PowerShell Core in .NET Core application.