2

In a PowerShell profile, one can identify the PowerShell host in order to do appropriate setup for that host's environment. For example:

if ($host.Name -eq 'ConsoleHost')
{
    Import-Module PSReadline
    # differentiate verbose from warnings!
    $privData = (Get-Host).PrivateData
    $privData.VerboseForegroundColor = "cyan"
}
elseif ($host.Name -like '*ISE Host')
{
    Start-Steroids
    Import-Module PsIseProjectExplorer
}

I would like to be able to do the equivalent identification from a C# context primarily because PowerShell ISE does not support Console.ReadLine so I want to know if it is safe to use it in the current PS host's environment.

I first explored trying to get the output of the Get-Host cmdlet from within C# (per Invoking a cmdlet within a cmdlet). After I located the Microsoft.PowerShell.Commands.Utility assembly (under C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0) I could compile this but it yielded null...

var cmd = new Microsoft.PowerShell.Commands.GetHostCommand();
var myHost = cmd.Invoke();

...while this would not compile due to the InternalHost class being (ironically!) internal:

var cmd = new Microsoft.PowerShell.Commands.GetHostCommand();
var myHost = cmd.Invoke<System.Management.Automation.Internal.Host.InternalHost>();

Next, I then modified my cmdlet to inherit from PSCmdlet rather than Cmdlet (to allow access to the SessionState), so I could then access the PS host object like this:

var psVarObject = SessionState.PSVariable.GetValue("Host");

Of course, that returns a pure Object, which I then needed to cast to... oh, wait... it's still internal!... so this would not compile:

string psHost = ((System.Management.Automation.Internal.Host.InternalHost)psVarObject).Name;

Leaving me no alternative but to use reflection on a foreign assembly (horrors!):

string psHost = (string)psVarObject.GetType().GetProperty("Name").GetValue(psVarObject, null);

That works, but is less than ideal, because reflecting upon any 3rd-party assembly is a fragile thing to do.

Any alternative ideas on either (a) identifying the host or, (b) backing up a bit, being able to use the host's own Read-Host cmdlet to get a typed input from a user?

0

2 Answers 2

3

You can just use Host property from PSCmdlet class. And if you want to do Read-Host:

Host.UI.ReadLine()
Sign up to request clarification or add additional context in comments.

1 Comment

Bravo! Amazing what one can do when one knows the right bits!
0

When getting

var psVarObject = SessionState.PSVariable.GetValue("Host");

You can cast it to System.Management.Automation.Host.PSHost instead of InternalHost

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.