platyPS icon indicating copy to clipboard operation
platyPS copied to clipboard

YamlDotNet - Assembly with same name is already loaded

Open bgelens opened this issue 4 years ago • 14 comments

@SteveL-MSFT @rjmholt

As discussed in community call I raise this issue so hopefully something can be done with YamlDotNet dependency for v2 release.

Some ideas suggested in the call:

  • Update platyPS more ofter with higher version of YamlDotNet and release module more often so the update is shipped
  • Load YamlDotNet in different assembly load context

A simple repro:

Install and load Az.Aks 1.0.3 Try to load platyPS (0.14.0, latest at time of writing)

bgelens avatar Apr 16 '20 17:04 bgelens

cc @adityapatwardhan, we should consider a custom assembly load context for PlatyPS vNext

SteveL-MSFT avatar Apr 20 '20 17:04 SteveL-MSFT

Yup, absolutely.

adityapatwardhan avatar Jun 16 '20 01:06 adityapatwardhan

@SteveL-MSFT is there any example on how to achieve this? I'm currently struggling with trying to load a PS module which uses YamlDotNet

Install-Module -Name "FXPSYaml" -RequiredVersion "1.0.3" -Force -Verbose;
Import-Module -Name "FXPSYaml" -Force;

on an Azure DevOps hosted Ubuntu 18.04 agent, which appears to have the Az.Aks module installed.

ModuleType Version    PreRelease Name                                PSEdition
---------- -------    ---------- ----                                ---------
(...)
Script     1.3.0                 Az.Aks                              Core,Desk
(...)

mmisztal1980 avatar Nov 12 '20 00:11 mmisztal1980

is there any example on how to achieve this?

It must be done by the module itself. You can't load any module through a custom assembly load context.

One thing you could try is importing the module you're trying to use in a subprocess or through PS remoting.

There's a list of techniques you might be able to use in this blog post.

rjmholt avatar Nov 12 '20 00:11 rjmholt

@rjmholt Is it possible to force load an assembly in custom ALC if another version of the assembly is already loaded?

iSazonov avatar Nov 12 '20 06:11 iSazonov

@rjmholt I've tried Start-Job unsuccessfully, and New-PSSession

It appears that the latter is not permitted on an Azure DevOps Hosted Agent:

New-PSSession: /home/vsts/work/1/automation/azure/azure-devops/CloudTek-AzureDevOps.K8S.psm1:32
Line |
  32 |  $s = New-PSSession;
     |       ~~~~~~~~~~~~~
     | MI_RESULT_ACCESS_DENIED

Any other suggestions?

mmisztal1980 avatar Nov 14 '20 01:11 mmisztal1980

Is it possible to force load an assembly in custom ALC if another version of the assembly is already loaded?

Yes, but you can't force PowerShell or anything else to use that assembly. You can't break an existing binding. But if something would otherwise fail, you can use the resolve event to achieve what you want. Otherwise you can call the ALC assembly directly through reflection.

Any other suggestions?

Yes, the simplest thing to try is a subprocess:

pwsh -c 'Invoke-ConflictingCommand'

rjmholt avatar Nov 17 '20 22:11 rjmholt

Yes, but you can't force PowerShell or anything else to use that assembly. You can't break an existing binding.

@rjmholt Thanks! Scenario I ask. PowerShell loaded yaml.dll (version 1) in global. User does import-module Module. PowerShell read a manifest of the Module and I see two dlls - Module.dll and yaml.dll (version 2). Module.dll depends on yaml.dll (version 2). PowerShell creates new ALC and loads Module.dll and yaml.dll (version 2) in the ALC. Will Module work correctly?

iSazonov avatar Nov 18 '20 04:11 iSazonov

Will Module work correctly?

No, the main DLL of the module must be in the default ALC. PowerShell loads binary modules with Assembly.LoadFrom, which loads into the default ALC. Loading a DLL into another ALC will not affect the output of Assembly.LoadFrom (since that's the whole point of ALC isolation).

rjmholt avatar Nov 18 '20 17:11 rjmholt

Sorry, my question was not about how PowerShelll works. My question is about how type resolving works and how we could enhance PowerShell. Let's say PowerShell loads the module main dll into default ALC and other dll from the module in custom ALC?

iSazonov avatar Nov 18 '20 17:11 iSazonov

Let's say PowerShell loads the module main dll into default ALC and other dll from the module in custom ALC?

Yeah, I think it's possible. We've had some discussion in https://github.com/PowerShell/PowerShell/issues/12920 on how to do it, or indeed whether we should.

rjmholt avatar Nov 18 '20 18:11 rjmholt

Is there a work-around for this issue? I would like to use both platyPS and powershell-yaml. However I am unable to import both into the same session.

=====> PowerShell Integrated Console v2020.6.0 <=====
PS /home/codespace/workspace> Install-Module powershell-yaml
PS /home/codespace/workspace> Install-Module platyPS
PS /home/codespace/workspace> Import-Module powershell-yaml
PS /home/codespace/workspace> Import-Module platyPS
Import-Module: Assembly with same name is already loaded
PS /home/codespace/workspace> Import-Module platyPS -Verbose
VERBOSE: Loading module from path '/home/codespace/.local/share/powershell/Modules/platyPS/0.14.1/platyPS.psd1'.
VERBOSE: Loading 'Assembly' from path '/home/codespace/.local/share/powershell/Modules/platyPS/0.14.1/Markdown.MAML.dll'.
VERBOSE: Loading 'Executable' from path '/home/codespace/.local/share/powershell/Modules/platyPS/0.14.1/Markdown.MAML.dll'.
VERBOSE: Loading 'Assembly' from path '/home/codespace/.local/share/powershell/Modules/platyPS/0.14.1/YamlDotNet.dll'.
VERBOSE: Loading 'Executable' from path '/home/codespace/.local/share/powershell/Modules/platyPS/0.14.1/YamlDotNet.dll'.
Import-Module: Assembly with same name is already loaded

Stewartarmbrecht avatar Jan 18 '21 15:01 Stewartarmbrecht

@Stewartarmbrecht I look forward to this problem being fixed too. In the meantime, I believe I found a workaround: import-module platyps first; then import powershell-yaml (it failed the first time), and then import powershell-yaml again. Then I was able to successfully use the platyps functions.

pwm1234-sri avatar Aug 12 '22 14:08 pwm1234-sri

This issue was addressed by https://github.com/PowerShell/platyPS/pull/587 and https://github.com/PowerShell/platyPS/pull/588.

Now platyPS and powershell-yaml can work in the same session, with one caveat -- import powershell-yaml first, then platyPS. This is because of a bug in powershell-yaml, for which I opened the PR https://github.com/cloudbase/powershell-yaml/pull/87. ~However, it seems powershell-yaml is not being maintained anymore ...~ That was wrong, it's still being maintained :)

daxian-dbw avatar Sep 09 '22 21:09 daxian-dbw

Thanks @daxian-dbw the issue has be fixed.

adityapatwardhan avatar Nov 14 '22 18:11 adityapatwardhan