如何从c#调用使用“图形命令窗口”(show-command)的powershell

时间:2016-06-27 15:22:11

标签: c# powershell

            Collection<PSObject> PSOutput;
            using (PowerShell PowerShellInstance = PowerShell.Create())
            {               
                PowerShellInstance.AddScript("Show-Command -name Get-Content -PassThru");
                PSOutput = PowerShellInstance.Invoke();             
            }

这返回没有输出,但PowerShellInstance上有一个错误,其错误流有一个空引用异常

  

在   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)

3 个答案:

答案 0 :(得分:0)

将此添加到您的代码中:

        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管理对象所期望的。

使用ILSpy检查Microsoft.PowerShell.Commands.Utility.dll中的代码,似乎Show-Command cmdlet调用正在查找System.Management.Automation.Internal ShowCommandProxy的{​​{1}}对象对象,未设置。

- 更新 -

我会看一下这个问题:Custom PSHostUserInterface is ignored by Runspace这表明你必须实现自己的PSHost(https://msdn.microsoft.com/en-us/library/system.management.automation.host.pshost(v=vs.85).aspx)并实现自己的GraphicalHostReflectionWrapper,最后你自己的PSHostUserInterface来处理所有的I / O.

MS在这里有一个示例https://msdn.microsoft.com/en-us/library/ee706551(v=vs.85).aspx来执行自定义主机实现。

答案 1 :(得分:0)

如果目标是获取PowerShell CmdLet的参数,则可以使用Get-Command。您将无法使用C#显示PowerShell图形窗口。

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

输出:

var relID: String = " "
var userID: String = ""

override func viewDidLoad() {
    super.viewDidLoad()
    userID = (FIRAuth.auth()?.currentUser?.uid)!

    Helper.helper.getRelID(userID) {
        (result: String) in
        let relID = result
    }

    print("after completion handler"+relID) // prints "after completion handler "
}

https://blogs.technet.microsoft.com/heyscriptingguy/2012/05/16/use-the-get-command-powershell-cmdlet-to-find-parameter-set-information/

答案 2 :(得分:0)

对我来说这看起来像个错误。在访问其属性之前,Show-Command未检查null PSHost。要解决此问题,您需要实现自己的overridePrivateData 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() 对象:

`e#!/usr/bin/env bash
cd /path/to/files
ls -l -S | sort -k 5 -n #sort file sizes in revers order
cksum /path/to/files/* |        #File duplication verification
  awk ' { if( $2 in arr) 
            {print "duplicates ", $3, arr[$2], "duplicate filesize = ", $2} 
              else 
            {arr[$2]=$3} }' 
`