[英]How can i invoke powershell that uses “graphical command window” (show-command) from c#
Collection<PSObject> PSOutput;
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript("Show-Command -name Get-Content -PassThru");
PSOutput = PowerShellInstance.Invoke();
}
此操作不返回任何輸出,但PowerShellInstance上存在錯誤,其錯誤流具有空引用異常
在Microsoft.PowerShell.Commands.ShowsInternal.ShowCommandHelper.GetHostWindow(PSCmdlet cmdlet)在Microsoft.PowerShell.Commands.ShowCommandInternal.ShowCommandHelper.CallShowDialog(PSCmdlet cmdlet)在Microsoft.PowerShell.Commands.ShowCommandInternal.ShowCommandHelper.ShowCommandWindow(PSCmdlet cmdbj,對象commandViewModelO ,Double windowWidth,Double windowHeight,Boolean passThrough)
將此添加到您的代碼中:
Collection<PSObject> PSOutput;
using (PowerShell PowerShellInstance = PowerShell.Create()) {
PowerShellInstance.AddScript("Show-Command -name Get-Content -PassThru");
PSOutput = PowerShellInstance.Invoke();
if (!PowerShellInstance.HadErrors ) {
foreach (var item in PSOutput) {
Console.WriteLine(item);
}
} else {
foreach (var item in PowerShellInstance.Streams.Error) {
Console.WriteLine(item);
Console.WriteLine(item.Exception.StackTrace);
}
}
}
返回此輸出
Object reference not set to an instance of an object.
at Microsoft.PowerShell.Commands.ShowCommandInternal.ShowCommandHelper.GetHostWindow(PSCmdlet cmdlet)
at Microsoft.PowerShell.Commands.ShowCommandInternal.ShowCommandHelper.CallShowDialog(PSCmdlet cmdlet)
at Microsoft.PowerShell.Commands.ShowCommandInternal.ShowCommandHelper.ShowCommandWindow(PSCmdlet cmdlet, Object commandViewModelObj, Double windowWidth, Double windowHeight, Boolean passThrough)
這幾乎表明沒有HostWindow對象,可以使用PS Management Objects來實現。
使用ILSpy檢查Microsoft.PowerShell.Commands.Utility.dll
的代碼,似乎Show-Command
cmdlet調用了一個ShowCommandProxy
對象,該對象正在尋找未設置的System.Management.Automation.Internal GraphicalHostReflectionWrapper
對象。
-更新-
我來看看這個問題: Runspace將忽略自定義PSHostUserInterface,這表明您將必須實現自己的PSHost( https://msdn.microsoft.com/zh-cn/library/system.management .automation.host.pshost(v = vs.85).aspx ),並實現自己的PSHostUserInterface
並最終實現自己的PSHostRawUserInterface
來處理所有I / O。
MS在這里有一個https://msdn.microsoft.com/zh-cn/library/ee706551(v=vs.85).aspx的示例,該示例執行自定義主機實現。
如果目標是獲取PowerShell CmdLet的參數,則可以使用Get-Command。 您將無法從C#中顯示PowerShell圖形窗口。
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
string cmdLetName = "Get-Content";
Collection<PSObject> PSOutput;
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddCommand("Get-Command");
PowerShellInstance.AddParameter("Name", cmdLetName);
PSOutput = PowerShellInstance.Invoke();
}
foreach(var item in PSOutput)
{
var cmdLetInfo = item.BaseObject as System.Management.Automation.CmdletInfo;
var defaultParamSet = cmdLetInfo.ParameterSets.Where(pSet => pSet.IsDefault == true).FirstOrDefault();
Console.WriteLine(String.Format("Default ParameterSet for {0}. (*) Denotes Mandatory", cmdLetName));
foreach (var param in defaultParamSet.Parameters.OrderByDescending(p => p.IsMandatory))
{
if (param.IsMandatory)
Console.WriteLine(String.Format("\t {0} (*)", param.Name));
else
Console.WriteLine(String.Format("\t {0}", param.Name)); ;
}
}
Console.ReadLine();
}
}
}
輸出:
Default ParameterSet for Get-Content. (*) Denotes Mandatory
Path (*)
ReadCount
TotalCount
Tail
Filter
Include
Exclude
Force
Credential
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
UseTransaction
Delimiter
Wait
Raw
Encoding
Stream
對我來說,這似乎是個蟲子。 Show-Command
在訪問其屬性之前不會檢查PrivateData
是否為null
。 要解決此問題,您需要實現自己的PSHost
並override
PrivateData
以返回不為null
對象:
Add-Type -TypeDefinition @‘
using System;
using System.Globalization;
using System.Management.Automation;
using System.Management.Automation.Host;
public class NotDefaultHost : PSHost {
private Guid instanceId = Guid.NewGuid();
private PSObject privateData = new PSObject();
public override CultureInfo CurrentCulture {
get {
return CultureInfo.CurrentCulture;
}
}
public override CultureInfo CurrentUICulture {
get {
return CultureInfo.CurrentUICulture;
}
}
public override Guid InstanceId {
get {
return instanceId;
}
}
public override string Name {
get {
return "NonDefaultHost";
}
}
public override PSObject PrivateData {
get {
return privateData;
}
}
public override PSHostUserInterface UI {
get {
return null;
}
}
public override Version Version {
get {
return new Version(1, 0);
}
}
public override void EnterNestedPrompt() {
throw new NotSupportedException();
}
public override void ExitNestedPrompt() {
throw new NotSupportedException();
}
public override void NotifyBeginApplication() { }
public override void NotifyEndApplication() { }
public override void SetShouldExit(int exitCode) { }
}
’@
$Runspace = [RunspaceFactory]::CreateRunspace((New-Object NotDefaultHost));
$Runspace.Open()
$PS=[PowerShell]::Create()
$PS.Runspace = $Runspace;
$PS.AddScript('Show-Command -Name Get-Content -PassThru').Invoke()
if($PS.HadErrors) {
'--- Errors: ---'
$PS.Streams.Error
}
$PS.Dispose()
$Runspace.Dispose()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.