As you may know, I was one of the first developers who jumped on board and started working on an alternative PowerShell host (actually, I’m also the first to create a WPF-based host, and the first to create one that was open source … but enough about me).
Recently I’ve picked back up on that project, and am just about ready to release what I hope will be the last “pre-release” of PoshConsole before I declare it to be “beta” quality and start doing more regular releases.
The coolest features of PoshConsole, the ones that are really revolutionary, involve exposing the WPF surface to scripts and cmdlets so that you can actually have graphical output in the console — not popups, and not just for fun… but stuff like putting bar graphs behind the size columns in Get-ChildItem for folders, and the memory columns in Get-Process, etc… anyway.
So I’ve been writing a few scripts to show off the possibilities of PoshConsole, and was thinking about even posting them on the PoshCode.org PowerShell Script Repository, but I wanted a way to make clear that they’d only work in PoshConsole.
A little investigation later, and it was clear that PowerShell has a built in feature for this:
#requires -ShellId PoshConsole … except, it doesn’t work. Actually, it doesn’t work for two reasons:
- PowerShell always ignores
#requires -ShellId Anything
- No other PowerShell host implements ShellId as far as I can see
The ShellId is a read-only property of the RunspaceConfiguration, so to implement it in your PowerShell host you have to create your own RunspaceConfiguration class inheriting from the abstract base class. The problem is, there are some expensive side-effects:
- You have to configure the available .net Assemblies, Cmdlets, Format files, Initialization Scripts, Providers, Scripts, and Type files …
- Having your own ShellId means you don’t inherit anything from PowerShell.exe (like for instance, the ExecutionPolicy)
- Some cmdlets just don’t seem to work (Add-PSSnapin is just failing on me with “Object reference not set to an instance of an object”)
So … to sum up: PowerShell ignores #require -ShellId, and I can’t find another host (including Microsoft’s “Graphical PowerShell” and the latest and greatest PowerShell Plus Professional) that bothers to set the ShellId. Can anyone tell me a reason why I should bother with this?
Oh, and, can anyone give me some information about why Add-PSSnapin might be failing when I do set the ShellId?
ShellId IS too big a burden.
After further investigation, it turns out that the reason Add-PSSnapin fails is because it uses a method
AddPsSnapIn which is part of the RunspaceConfiguration (that you had to create yourself to set the ShellId), and you can’t implement that method (in fact, you can’t seem to override it with “new” either, I’ll have to look into that a little more).
In any case, the method has to return a PSSnapInInfo object, and since there are no public constructors for PSSnapinInfo objects, you’re sore-out-of-luck. It appears you would literally have to reverse engineer the whole “PSSnapin” system and create your own cmdlets and functionality around it to try to keep your host compatible with the main PowerShell. No wonder nobody’s done this…
I guess I’ll just go back to using Microsoft.PowerShell as my ShellId, I don’t know what I was thinking.