[英]How to access PowerShell host from C#
In a PowerShell profile, one can identify the PowerShell host in order to do appropriate setup for that host's environment. 在PowerShell配置文件中,可以标识PowerShell主机,以便针对该主机的环境进行适当的设置。 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. 我希望能够从C#上下文中进行等效标识,这主要是因为PowerShell ISE不支持
Console.ReadLine
因此我想知道在当前PS主机环境中使用它是否安全。
I first explored trying to get the output of the Get-Host
cmdlet from within C# (per Invoking a cmdlet within a cmdlet ). 我首先探讨了如何尝试从C#中
Get-Host
cmdlet的输出(在cmdlet中调用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... 找到Microsoft.PowerShell.Commands.Utility程序集(在C:\\ Program Files(x86)\\ Reference Assemblies \\ Microsoft \\ WindowsPowerShell \\ 3.0下)之后,我可以编译该程序,但它会产生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: ...虽然由于
InternalHost
类是InternalHost
(讽刺!),所以无法编译:
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: 接下来,然后我将cmdlet修改为从
PSCmdlet
继承,而不是从Cmdlet
继承(以允许访问SessionState
),这样便可以像这样访问PS主机对象:
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: 当然,这将返回一个纯
Object
,然后我需要将其强制转换为...哦,等等...它仍然是内部的!...因此无法编译:
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? 关于(a)识别主机,或(b)进行一些备份,能够使用主机自己的Read-Host cmdlet从用户那里获得有类型的输入,是否还有其他想法?
When getting 当得到
var psVarObject = SessionState.PSVariable.GetValue("Host");
You can cast it to System.Management.Automation.Host.PSHost
instead of InternalHost
您可以将其
System.Management.Automation.Host.PSHost
为System.Management.Automation.Host.PSHost
而不是InternalHost
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.