PowerShell / PowerShellStandard

MIT License
158 stars 23 forks source link

Using PowershellStandard to determine dlls to import to script module? #71

Open JustinGrote opened 4 years ago

JustinGrote commented 4 years ago

Hello,

Been trying to figure out how to do this.

Say I have a script module that wants to use Microsoft.Extensions.Configuration. This nuget package, targeted for .NET standard 2.0, has some expected dependencies such as Microsoft.Extensions.Primitives, but down the nuspec tree there are also things like System.Memory.

I want to write a script module but I need to find which assemblies I need to include. For instance, exclude System.Memory if it is available in the Powershell Standard, to keep the module small.

Is there a way to generate, say, a list of assemblies that are in the Powershell Standard section and be able to "blacklist" them out somehow?

TylerLeonhardt commented 4 years ago

It's a good question but it has a complicated answer. Ideally what you would do is go through all the dlls that are sitting in $PSHOME and all the dlls in the publish directory of your module and exclude the ones that are already in $PSHOME however, this gets tricky because if you target multiple versions of PowerShell, the dll list might be different.

A perfect example of this is Newtonsoft.dll which exists in PowerShell Core, but not in Windows PowerShell. If you want users to also use your module in Windows PowerShell, then you also need to bundle Newtonsoft.dll.

Ideally, we'd have some tooling to help out with this scenario... but we haven't had the time to do so.

TylerLeonhardt commented 4 years ago

cc @SteveL-MSFT @JamesWTruher

JustinGrote commented 4 years ago

Thanks Tyler, I figured that was pretty much the story, my current plan was to do a dotnet build against the powershell library and get an inventory of assemblies, then compare that to the standard list and only grab the copies. This will work 90% of the time but there's a couple potential issues:

  1. Libraries/Assemblies that got rolled into mscorlib or otherwise abstracted
  2. Libraries with multiple versions, e.g. I need newtonsoft.json v10 but v6 is what comes with Powershell and it will only load one at a time. That's in another issue, and is solvable with bindings.

If I come up with some half-decent tooling I will reference it here.

On Mon, Oct 14, 2019 at 11:20 AM Tyler James Leonhardt < notifications@github.com> wrote:

It's a good question but it has a complicated answer. Ideally what you would do is go through all the dlls that are sitting in $PSHOME and all the dlls in the publish directory of your module and exclude the ones that are already in $PSHOME however, this gets tricky because if you target multiple versions of PowerShell, the dll list might be different.

A perfect example of this is Newtonsoft.dll which exists in PowerShell Core, but not in Windows PowerShell. If you want users to also use your module in Windows PowerShell, then you also need to bundle Newtonsoft.dll.

Ideally, we'd have some tooling to help out with this scenario... but we haven't had the time to do so.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/PowerShell/PowerShellStandard/issues/71?email_source=notifications&email_token=ADUNKUWR6VGRGEJ2JADTCK3QOSZ5RA5CNFSM4JASFPM2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBF4V4I#issuecomment-541838065, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADUNKUUPBUA3RAS3DZYETLTQOSZ5RANCNFSM4JASFPMQ .

JustinGrote commented 4 years ago

@TylerLeonhardt I made a pretty effective tool for this! It basically builds an empty dotnet project against the powershell standard with packagereferences to the required nuget packages, then copies over the DLLs.

https://gist.github.com/JustinGrote/5daa3d02be2ff9e913ae6b2a0f96769b

Todo still: Detect and resolve with assembly binding redirects if an older assembly exists natively. What I've run into most commonly: System.Runtime.CompilerServices.Unsafe

JustinGrote commented 4 years ago

I would say this is still something that PowershellStandard should cover, as teams such as PSGet do not appear to be leveraging it and still using manual methods to pare down the assembly list https://github.com/PowerShell/PowerShellGet/issues/104#issuecomment-607433179