C# 如何从C访问PowerShell主机#

C# 如何从C访问PowerShell主机#,c#,powershell,reflection,C#,Powershell,Reflection,在PowerShell配置文件中,可以识别PowerShell主机,以便为该主机的环境执行适当的设置。例如: if ($host.Name -eq 'ConsoleHost') { Import-Module PSReadline # differentiate verbose from warnings! $privData = (Get-Host).PrivateData $privData.VerboseForegroundColor = "cyan" }

在PowerShell配置文件中,可以识别PowerShell主机,以便为该主机的环境执行适当的设置。例如:

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
}
我希望能够从C#上下文中进行等效标识,主要是因为PowerShell ISE不支持
Console.ReadLine
,因此我想知道在当前PS主机的环境中使用它是否安全

我首先尝试从C#(per)中获取
get-Host
cmdlet的输出。在找到Microsoft.PowerShell.Commands.Utility程序集(在C:\Program Files(x86)\Reference Assemblys\Microsoft\WindowsPowerShell\3.0下)后,我可以编译此程序集,但它生成空

var cmd = new Microsoft.PowerShell.Commands.GetHostCommand();
var myHost = cmd.Invoke();
…虽然由于
InternalHost
类是(讽刺的是!)内部的,所以无法编译该类:

var cmd = new Microsoft.PowerShell.Commands.GetHostCommand();
var myHost = cmd.Invoke<System.Management.Automation.Internal.Host.InternalHost>();
当然,这会返回一个纯
对象,然后我需要将其转换为。。。哦,等等。。。它仍然是内在的!。。。因此,这不会编译:

string psHost = ((System.Management.Automation.Internal.Host.InternalHost)psVarObject).Name;
让我别无选择,只能在外部程序集上使用反射(恐怖!)

这是可行的,但并不理想,因为考虑任何第三方程序集都是一件脆弱的事情

关于(a)识别主机或(b)备份一点,能够使用主机自己的Read-host cmdlet从用户处获取键入的输入,您可以使用PSCmdlet类中的属性。如果要执行
读取主机

Host.UI.ReadLine()
当得到

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

您可以将其转换为
System.Management.Automation.Host.PSHost
,而不是
InternalHost

Bravo!当一个人知道正确的部分时,他能做的事情令人惊讶!
Host.UI.ReadLine()
var psVarObject = SessionState.PSVariable.GetValue("Host");