PoshCode / Pansies

Powershell ANSI Escape Sequences, functions for colored output, etc.
MIT License
146 stars 14 forks source link

PowerShell 5.1 - Pansies breaks tab completion for .net types #12

Closed ebachert closed 3 years ago

ebachert commented 5 years ago

Steps to repro: Windows 10 1803 PowerShell 5.1

Open new PowerShell session, type [System. and then hit Tab Tab You will notice that PowerShell enumerates and displays all .NET types without issue.

Now, execute the following: Install-Module Pansies -AllowClobber -AllowPrerelease -Force Install-Module PSReadline -AllowClobber -AllowPrerelease -Force

Restart PowerShell session.

Import-Module Pansies Import-Theme Dark

Try enumerating .NET types by typing [System. and then hit Tab Tab ...and nothing...

Any ideas?

Jaykul commented 5 years ago

As far as PSReadLine, yes -- the pre-release of Pansies only works with the pre-release of PSReadLine (that's part of the reason why it's still a pre-release).

I can't be bothered to try to implement the parameter set for the old PSReadLine -- so I'm waiting for this new one to finally be released. In fact, it has caused me to decide to make this an extension point so that other modules (or users of other modules) can implement their own theme support (that's the other reason why it's still a pre-release).

The tab-expansion break is exasperating -- I had noticed it (and it's been driving me nuts), but I hadn't figured out which thing broke it. I will dig into that and get it fixed.

ebachert commented 5 years ago

Modified the title, as you're absolutely correct. Given that these are 'pre-release' modules (Pansies and PSReadline) for PoSH 5.1, I removed that from the title. However, you may want to add a dependency to the Pansies module for PSReadline @2.0.0, or at least call that out in the documentation somewhere?

I'm digging into why .NET type enums break as well, I'll let you know if I find anything useful.

Thanks for your prompt response and attention to this! Greatly appreciated, as I absolutely LOVE your module!!

ebachert commented 5 years ago

Not sure if this will help you at all @Jaykul but here is the output of what assemblies are loaded (using the 'ClassExplorer' module) while .NET enums work properly vs. not working at all:

WORKING: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.ConsoleHost\v4.0_3.0.0.031bf3856ad364e35\Microsoft.PowerShell.ConsoleHost.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0b77a5c561934e089\System.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0b77a5c561934e089\System.Core.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.031bf3856ad364e35\System.Management.Automation.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Management.Infrastructure\v4.0_1.0.0.031bf3856ad364e35\Microsoft.Management.Infrastructure.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Management\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Management.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.DirectoryServices\v4.0_4.0.0.0b03f5f7f11d50a3a\System.DirectoryServices.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0b77a5c561934e089\System.Xml.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Numerics\v4.0_4.0.0.0b77a5c561934e089\System.Numerics.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0b77a5c561934e089\System.Data.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.Security\v4.0_3.0.0.031bf3856ad364e35\Microsoft.PowerShell.Security.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Transactions\v4.0_4.0.0.0b77a5c561934e089\System.Transactions.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Configuration.dll C:\Program Files\WindowsPowerShell\Modules\PSReadline\2.0.0\Microsoft.PowerShell.PSReadLine2.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Runtime.InteropServices.RuntimeInformation\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Runtime.InteropServices.RuntimeInformation.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.CSharp\v4.0_4.0.0.0b03f5f7f11d50a3a\Microsoft.CSharp.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Utility\v4.0_3.0.0.031bf3856ad364e35\Microsoft.PowerShell.Commands.Utility.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration.Install\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Configuration.Install.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Security\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Security.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Data.SqlXml\v4.0_4.0.0.0b77a5c561934e089\System.Data.SqlXml.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Web.Extensions\v4.0_4.0.0.031bf3856ad364e35\System.Web.Extensions.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Web.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml.Linq\v4.0_4.0.0.0b77a5c561934e089\System.Xml.Linq.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Management\v4.0_3.0.0.0__31bf3856ad364e35\Microsoft.PowerShell.Commands.Management.dll C:\Program Files\WindowsPowerShell\Modules\ClassExplorer\1.1.0\bin\Desktop\ClassExplorer.dll

NOT WORKING: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.ConsoleHost\v4.0_3.0.0.031bf3856ad364e35\Microsoft.PowerShell.ConsoleHost.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0b77a5c561934e089\System.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0b77a5c561934e089\System.Core.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.031bf3856ad364e35\System.Management.Automation.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Management.Infrastructure\v4.0_1.0.0.031bf3856ad364e35\Microsoft.Management.Infrastructure.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Management\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Management.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.DirectoryServices\v4.0_4.0.0.0b03f5f7f11d50a3a\System.DirectoryServices.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0b77a5c561934e089\System.Xml.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Numerics\v4.0_4.0.0.0b77a5c561934e089\System.Numerics.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0b77a5c561934e089\System.Data.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.Security\v4.0_3.0.0.031bf3856ad364e35\Microsoft.PowerShell.Security.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Transactions\v4.0_4.0.0.0b77a5c561934e089\System.Transactions.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Configuration.dll C:\Program Files\WindowsPowerShell\Modules\PSReadline\2.0.0\Microsoft.PowerShell.PSReadLine2.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Runtime.InteropServices.RuntimeInformation\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Runtime.InteropServices.RuntimeInformation.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.CSharp\v4.0_4.0.0.0b03f5f7f11d50a3a\Microsoft.CSharp.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Utility\v4.0_3.0.0.031bf3856ad364e35\Microsoft.PowerShell.Commands.Utility.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration.Install\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Configuration.Install.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Security\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Security.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Data.SqlXml\v4.0_4.0.0.0b77a5c561934e089\System.Data.SqlXml.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Web.Extensions\v4.0_4.0.0.031bf3856ad364e35\System.Web.Extensions.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Web.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml.Linq\v4.0_4.0.0.0b77a5c561934e089\System.Xml.Linq.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Management\v4.0_3.0.0.031bf3856ad364e35\Microsoft.PowerShell.Commands.Management.dll C:\Program Files\WindowsPowerShell\Modules\ClassExplorer\1.1.0\bin\Desktop\ClassExplorer.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.ServiceModel\v4.0_4.0.0.0b77a5c561934e089\System.ServiceModel.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Web.ApplicationServices\v4.0_4.0.0.031bf3856ad364e35\System.Web.ApplicationServices.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.ServiceModel.Activation\v4.0_4.0.0.031bf3856ad364e35\System.ServiceModel.Activation.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Runtime.Serialization\v4.0_4.0.0.0b77a5c561934e089\System.Runtime.Serialization.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Web.Services\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Web.Services.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Drawing.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.ComponentModel.DataAnnotations\v4.0_4.0.0.031bf3856ad364e35\System.ComponentModel.DataAnnotations.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Runtime.Caching\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Runtime.Caching.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Build.Framework\v4.0_4.0.0.0b03f5f7f11d50a3a\Microsoft.Build.Framework.dll C:\Program Files\WindowsPowerShell\Modules\Pansies\1.4.0\lib\Pansies.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\netstandard\v4.0_2.0.0.0cc7b13ffcd2ddd51\netstandard.dll C:\Program Files\WindowsPowerShell\Modules\Pansies\1.4.0\lib\ColorMine.dll C:\Program Files\WindowsPowerShell\Modules\Pansies\1.4.0\lib\CodeOwls.PowerShell.Provider.dll C:\Program Files\WindowsPowerShell\Modules\Pansies\1.4.0\lib\CodeOwls.PowerShell.Paths.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.ServiceModel.Internals\v4.0_4.0.0.031bf3856ad364e35\System.ServiceModel.Internals.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.IdentityModel\v4.0_4.0.0.0b77a5c561934e089\System.IdentityModel.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0b03f5f7f11d50a3a\System.EnterpriseServices.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xaml\v4.0_4.0.0.0b77a5c561934e089\System.Xaml.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Net.Http\v4.0_4.0.0.0b03f5f7f11d50a3a\System.Net.Http.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Runtime.DurableInstancing\v4.0_4.0.0.031bf3856ad364e35\System.Runtime.DurableInstancing.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\SMDiagnostics\v4.0_4.0.0.0b77a5c561934e089\SMDiagnostics.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xaml.Hosting\v4.0_4.0.0.0__31bf3856ad364e35\System.Xaml.Hosting.dll C:\Program Files\WindowsPowerShell\Modules\Pansies\1.4.0\lib\Microsoft.Win32.Registry.dll

ebachert commented 5 years ago

@Jaykul got a callstack for ya'... I was able to attach the VSCode PowerShell debugger to my ConEmu PowerShell process and recreate the issue, which immediately threw an error in the VSCode debugger:

30: [Parameter(ParameterSetName = 'AstInputSet', Position = 3)] 31: [Hashtable] $options = $null 32: ) 33: 34: End 35:* { 36: if ($psCmdlet.ParameterSetName -eq 'ScriptInputSet') 37: { 38: return [System.Management.Automation.CommandCompletion]::CompleteInput( 39: <#inputScript#> $inputScript, 40: <#cursorColumn#> $cursorColumn, 41: <#options#> $options) 42: } 43: else 44: { 45: return [System.Management.Automation.CommandCompletion]::CompleteInput(

And a bit more info I was able to pull from VSCode debugger:

" at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) at System.Reflection.Assembly.GetTypes() at System.Management.Automation.CompletionCompleters.<>c.b__111_1(Assembly assembly) at System.Linq.Enumerable.d__17`2.MoveNext() at System.Management.Automation.CompletionCompleters.InitializeTypeCache() at System.Management.Automation.CompletionCompleters.CompleteType(CompletionContext context, String prefix, String suffix) at System.Management.Automation.CompletionAnalysis.GetResultHelper(CompletionContext completionContext, Int32& replacementIndex, Int32& replacementLength, Boolean isQuotedString) at System.Management.Automation.CompletionAnalysis.GetResults(PowerShell powerShell, Int32& replacementIndex, Int32& replacementLength) at System.Management.Automation.CommandCompletion.CompleteInputImpl(Ast ast, Token[] tokens, IScriptPosition positionOfCursor, Hashtable options) at CallSite.Target(Closure , CallSite , Type , Object , Object , Object )"

"Exception calling "CompleteInput" with "3" argument(s): "Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.""

ebachert commented 5 years ago

@Jaykul Upon further research, it appears that the issue only presents itself when executing the 'Import-Theme' cmdlet. Simply loading the Pansies and/or Configuration module into the current PSSession/AppDomain does not cause .NET Type enums to break. They only become unusable AFTER you've executed 'Import-Theme'

UPDATE If you import the theme using 'Import-Theme Dark -SkipDefault' then .NET type enums still work without issue!!! So, it apparently has something to do with setting the 'Default' colors when you execute 'Import-Theme'.

Jaykul commented 5 years ago

That made it very easy to repro (although I still don't know why it's happening).

Start powershell -noprofile (has to be the old Windows PowerShell)

Import-Module Pansies -MinimumVersion 1.4.0 # Needs to be the current pre-release
# Prove this works:
[System.Management.Automation.CommandCompletion]::CompleteInput("[Microsoft.Win", 14, @{})

# This won't change anything, but it loads some assemblies, so let's track what
$Before = [AppDomain]::CurrentDomain.GetAssemblies().FullName

$P = [PoshCode.Pansies.Console.WindowsHelper]::GetDefaultConsolePalette()
[PoshCode.Pansies.Console.WindowsHelper]::SetDefaultConsolePalette($P)

$After = [AppDomain]::CurrentDomain.GetAssemblies().FullName

# This will now throw an exception, which is the root cause of why tab-completion doesn't work:
try {
    [System.Management.Automation.CommandCompletion]::CompleteInput("[Microsoft.Win", 14, @{})
} catch {
   $_.Exception.InnerException.LoaderExceptions
}
$End = [AppDomain]::CurrentDomain.GetAssemblies().FullName

The loader exception is this, three times over:

Could not load file or assembly 'System.Security.AccessControl, Version=4.1.1.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

I'm still trying to figure out why it's doing that.

For what it's worth, after running the code above:

> $After.Where{$_ -notin $Before}
Microsoft.Win32.Registry, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

> $End.Where{$_ -notin $Before}
Microsoft.Win32.Registry, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Jaykul commented 5 years ago

It looks like I missed shipping a dependency of Microsoft.Win32.Registry --obviously I don't need that dependency (my code works fine)-- but PowerShell is enumerating all the types in the assembly that I did ship, and that is causing a problem.

This feels like a really stupid bug in PowerShell --and needing to ship an assembly that I don't need seems like a really stupid fix for it-- but I think I can fix it by just changing the build script.

Of course, I probably need to pull the Windows-only stuff out of Pansies into it's own module...

ebachert commented 5 years ago

Thank you, I tried to make it as easy as possible for you to troubleshoot, as I know how frustrating it is when someone just says "it doesn't work, fix it!"...

Glad you were able to find the root cause, although the fix does sound quite ridiculous....if there is anything further you need or if there is anything I can do to help, please let me know.

Jaykul commented 5 years ago

Fwiw, the bug is fixed in PowerShell 6 ;-)

Jaykul commented 3 years ago

This is also fixed because I've removed the windows-only stuff