Casting problems in Visual Studio Code Windows Powershell 5.1 terminal

Offen
#4,426 4 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
28/100
Issue-Typ
Bug
Klarheit
Größtenteils klar
Aktivitätsstatus
Veraltet
Tech-Stack
powershell, typescript, vscode

Rechercherichtung

Beginnen Sie mit der Ausführung des Inline-Reproduktionsskripts mit den referenzierten v7.0.0 Microsoft.Extensions DLLs im Windows PowerShell 5.1-Terminal und vergleichen Sie es anschließend mit den aufgeführten funktionierenden Konsolen. Untersuchen Sie die Einrichtung des Terminals und der PowerShell-Sitzung der Erweiterung, um festzustellen, warum dieselben generischen Typen inkompatibel geladen werden. Als abgeschlossen gilt die Aufgabe, wenn das ausschließlich in VS Code auftretende Verhalten erklärt und ein reproduzierbarer Pfad für die gemeldeten Konstruktoren und Casts dokumentiert oder behoben wurde.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

Bug: PowerShell 5.1 Issue-Bug
Prerequisites
  • I have written a descriptive issue title.
  • I have searched all open and closed issues to ensure it has not already been reported.
  • I have read the troubleshooting guide.
  • I am sure this issue is with the extension itself and does not reproduce in a standalone PowerShell instance.
  • I have verified that I am using the latest version of Visual Studio Code and the PowerShell extension.
  • If this is a security issue, I have read the security issue reporting guidance.
Summary

I have had these casting problems several times. Now I am taking the time to document them. They were always error messages like "Type A cannot be converted to type A". But only in the Windows Powershell 5.1 terminal.

Also, the example script below in "Steps to Reproduce" does not work in the Windows Powershell 5.1 terminal only.

Expected:

info: int[0]
      Hello from Windows Powershell

But I get this:

PS C:\GithubIssue> . 'C:\GithubIssue\Github VS Code.ps1'
Cannot find an overload for "new" and the argument count: "1".
At C:\GithubIssue\Github VS Code.ps1:26 char:1
+ $loggerFactory = [Microsoft.Extensions.Logging.LoggerFactory]::new(
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException  
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest
 
Cannot find an overload for "new" and the argument count: "1".
At C:\GithubIssue\Github VS Code.ps1:61 char:5
+     [Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider]::new ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
    + CategoryInfo          : NotSpecified: (:) [], MethodException        
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest
 
Constructor not found.
Constructor not found.
Microsoft.Extensions.Options.IOptionsMonitor`1[[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions, Microsoft.Extensions.Logging.Console, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]]
Microsoft.Extensions.Options.OptionsMonitor`1[[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions, Microsoft.Extensions.Logging.Console, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]]
Exception calling "Invoke" with "1" argument(s): "Object of type 
'Microsoft.Extensions.Options.OptionsMonitor`1[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]' cannot be converted to type 
'Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]'."
At C:\GithubIssue\Github VS Code.ps1:86 char:5
+     $foolMe = $constructor.Invoke(@($optionsMonitor))
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException
 
Exception calling "Invoke" with "1" argument(s): "Object of type 
'Microsoft.Extensions.Options.OptionsMonitor`1[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]' cannot be converted to type 
'Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]'."
At C:\GithubIssue\Github VS Code.ps1:90 char:5
+     $foolMe = $constructor.Invoke(@($cast))
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException
 
Exception calling "Invoke" with "1" argument(s): "Object of type 
'Microsoft.Extensions.Options.OptionsMonitor`1[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]' cannot be converted to type 
'Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]'."
At C:\GithubIssue\Github VS Code.ps1:94 char:5
+     $foolMe = $constructor.Invoke(@($cast))
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException

The crucial error is:

 "Object of type 
'Microsoft.Extensions.Options.OptionsMonitor`1[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]' cannot be converted to type 
'Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]'."

Why does this happen and how can I avoid it?

I know that one type is an interface. But for one thing, Powershell doesn't know the difference. On the other hand, why does it work in a Windows Powershell 5.1 console, but not in the Windows Powershell 5.1 terminal of VS Code?

PowerShell Version
PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.19041.2364
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.2364
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
Visual Studio Code Version
PS C:\> code --version
1.75.1
441438abd1ac652551dbe4d408dfcec8a499b8bf
x64
Extension Version
PS C:\> code --list-extensions --show-versions | Select-String powershell

ms-vscode.powershell@2023.1.0
tobysmith568.run-in-powershell@1.1.1
Steps to Reproduce
# This works fine in
# Windows Powershell 5.1 console
# Powershell Core 7.3.2 console
# Visual Studio Code Powershell Core 7.3.2 terminal
# BUT NOT IN
# Visual Studio Code Windows Powershell 5.1 terminal

Add-Type -Path "$PSScriptRoot\v7.0.0\Microsoft.Extensions.Logging.dll"
Add-Type -Path "$PSScriptRoot\v7.0.0\Microsoft.Extensions.Logging.Console.dll"
Add-Type -Path "$PSScriptRoot\v7.0.0\Microsoft.Extensions.Options.dll"


$configureNamedOptions = [Microsoft.Extensions.Options.ConfigureNamedOptions[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]]::new('', $null)

$optionsFactory = [Microsoft.Extensions.Options.OptionsFactory[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]]::new(
    [Microsoft.Extensions.Options.ConfigureNamedOptions[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions][]] @($configureNamedOptions), 
    [System.Collections.Generic.List[Microsoft.Extensions.Options.IPostConfigureOptions[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]]]::new()
)

$optionsMonitor = [Microsoft.Extensions.Options.OptionsMonitor[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]]::new(
    $optionsFactory,
    [System.Collections.Generic.List[Microsoft.Extensions.Options.IOptionsChangeTokenSource[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]]]::new(),
    [Microsoft.Extensions.Options.OptionsCache[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]]::new()
)

$loggerFactory = [Microsoft.Extensions.Logging.LoggerFactory]::new(
    [Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider[]] @([Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider]::new($optionsMonitor)),
    [Microsoft.Extensions.Logging.LoggerFilterOptions] @{ MinLevel = [Microsoft.Extensions.Logging.LogLevel]::Trace }
)

if ($null -ne $loggerFactory) {
    $method = [Microsoft.Extensions.Logging.LoggerFactoryExtensions].GetMethod('CreateLogger',
        [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::Public, $null, 
        [Type[]]@([Microsoft.Extensions.Logging.ILoggerFactory]), $null
    )

    $method = $method.MakeGenericMethod(@([int]))
    $logger = $method.Invoke($null, @($loggerFactory))

    $method = [Microsoft.Extensions.Logging.LoggerExtensions].GetMethod('LogInformation',
        [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::Public, 
        $null, 
        [Type[]]@([Microsoft.Extensions.Logging.ILogger], [string], [object[]]), 
        $null
    )

    $loggerFactory.Dispose()
}

if ($null -ne $logger) {
    if ($PSVersionTable.PSVersion.Major -gt 5) {
        $method.Invoke($null, @($logger, "Hello from Powershell Core", $null))
    }
    else {
        $method.Invoke($null, @($logger, "Hello from Windows Powershell", $null))
    }
}

### Try to narrow down the error ####################################################################
if ($null -eq $loggerFactory) {
    # Get original error message.
    [Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider]::new($optionsMonitor)
    # Get a better error message.

    $constructor = [Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider].GetConstructor( 
        [Type[]]@([Microsoft.Extensions.Options.OptionsMonitor[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions]], [string], [object[]])
    )

    if ($null -eq $constructor) {
        Write-Host -F Yellow 'Constructor not found.'
    }
    # Let's try FullName.
    $constructor = [Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider].GetConstructor( 
        [Type[]]@([Microsoft.Extensions.Options.IOptionsMonitor[[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions, Microsoft.Extensions.Logging.Console, Version = 7.0.0.0, Culture = neutral, PublicKeyToken = adb9793829ddae60]]], [string], [object[]])
    )

    if ($null -eq $constructor) {
        Write-Host -F Yellow 'Constructor not found.'
    }

    #But it exists!
    $constructor = [Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider].GetConstructors()[0]
    $constructor.GetParameters().ParameterType.FullName
    $optionsMonitor.GetType().FullName

    # Try constructor.
    $foolMe = $constructor.Invoke(@($optionsMonitor))

    # Ok, try to cast it.
    $cast = [Microsoft.Extensions.Options.IOptionsMonitor[[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions, Microsoft.Extensions.Logging.Console, Version = 7.0.0.0, Culture = neutral, PublicKeyToken = adb9793829ddae60]]] $optionsMonitor
    $foolMe = $constructor.Invoke(@($cast))

    # Ok, try to cast it again.
    $cast = $optionsMonitor -as [Microsoft.Extensions.Options.IOptionsMonitor[[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions, Microsoft.Extensions.Logging.Console, Version = 7.0.0.0, Culture = neutral, PublicKeyToken = adb9793829ddae60]]]
    $foolMe = $constructor.Invoke(@($cast))

    # I give up.
}
Visuals

No response

Logs

No response

Vorherrschende Sprache
TypeScript
Sterne
1.9k
Forks
548
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus PowerShell/vscode-powershell

Alle Issues in PowerShell/vscode-powershell

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.