Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从C运行PowerShell 6中的PowerShell脚本#_C#_Powershell_Start Process - Fatal编程技术网

C# 从C运行PowerShell 6中的PowerShell脚本#

C# 从C运行PowerShell 6中的PowerShell脚本#,c#,powershell,start-process,C#,Powershell,Start Process,我有一个与REST服务器通信的PowerShell脚本。此脚本仅适用于PowerShell 6。 我想从C#调用它,因为C#程序需要来自REST服务器的信息,我不想在C#中重写REST代码 所以基本上,我想从C#运行一个PowerShell脚本但是,在C#中,PowerShell.Create()创建一个使用PowerShell 5的PowerShell实例 我已经替换了默认文件夹中的pwsh.exe,删除了PowerShell 5 everywhere等。当我shift+右键单击anywher

我有一个与REST服务器通信的PowerShell脚本。此脚本仅适用于PowerShell 6。 我想从C#调用它,因为C#程序需要来自REST服务器的信息,我不想在C#中重写REST代码

所以基本上,我想从C#运行一个PowerShell脚本但是,在C#中,
PowerShell.Create()
创建一个使用PowerShell 5的
PowerShell
实例
我已经替换了默认文件夹中的pwsh.exe,删除了PowerShell 5 everywhere等。当我
shift+右键单击
anywhere使用“在此处运行PowerShell”时,我会看到一个PowerShell 6窗口。但出于某种原因,C#在使用
PowerShell
类时坚持使用PowerShell 5

这是我要重用的PowerShell代码:

function Get-JSONWebToken {
    param (
      [Parameter(Mandatory=$True)][string] $BaseUri,
      [Parameter(Mandatory=$True)][string] $ApiToken
    )
    if ($PSVersionTable.PSVersion.Major -lt 6) {
        $version = $PSVersionTable.PSVersion
        Throw "Your PowerShell version is: $version. Please upgrade to PowerShell 6 or above"
    }

    $uri = "$BaseUri/auth/token"    
    $bodyJson = ConvertTo-Json @{token = $ApiToken} -Compress

    Write-Host "Authenticating ..."
    try {
        $response = Invoke-RestMethod `
            -Uri $uri `
            -Method Post `
            -ContentType "application/json" `
            -Body $bodyJson
        $jwtToken = $response.token
        $secureToken = ConvertTo-SecureString $jwtToken -AsPlainText -Force
        return $secureToken    
    }
    catch {
        #handle error
    }
}
所以现在我尝试手动调用PowerShell 6,先导入一个模块,然后再使用它。下面是我的三次尝试,它们都应该做相同的事情:调用
获取JSONWebToken
(在
rest api.psm1
中)并正确检索输出

C#version 1,使用
PowerShell
类:

ps=PowerShell.Create();
//模块导入。。。
PSCommand cmd=ps.Commands.AddCommand(“Get-JSONWebToken”);
cmd.AddParameter(“baseUri”,baseUri);
cmd.AddParameter(“apiToken”,apiToken);
ps.Invoke();
由于某些原因,它始终在PowerShell 5上运行,因此无法使用

C#version 2,改用
过程

         Process ps6 = new Process();
         ps6.StartInfo = new ProcessStartInfo {
             FileName = "C:/Program Files/PowerShell/6/pwsh.exe",
             Arguments = "-Command {\n" +
                           "Import-Module " + modulePath + ";\n" +
                           "Get-JSONWebToken " + apiToken + ";\n" +
                         "}",
             UseShellExecute = false,
             RedirectStandardOutput = true,
             RedirectStandardError = true,
             CreateNoWindow = false
         };
         ps6.Start()
这在PowerShell 6上运行,但只输出我传递的参数,而不输出
Get JSONWebToken

C#version 3:从C从PS5调用PS6#

这根本不起作用:

Result: Usage: pwsh[.exe] [[-File] <filePath> [args]]
Result:                   [-Command { - | <script-block> [-args <arg-array>]
Result:                                 | <string> [<CommandParameters>] } ]
Result:                   [-ConfigurationName <string>] [-CustomPipeName <string>]
...
...
Result:用法:pwsh[.exe][[-File][args]]
结果:[-Command{-|[-args]
结果:|[]}]
结果:[-ConfigurationName][-CustomPipeName]
...
...
PowerShell版本

        $pinfo = New-Object System.Diagnostics.ProcessStartInfo
        $pinfo.FileName = $Ps6Path
        $pinfo.RedirectStandardError = $true
        $pinfo.RedirectStandardOutput = $true
        $pinfo.CreateNoWindow = $false
        $pinfo.Arguments = "-Command {Import-Module <myPath>\rest-api.psm1; Get-JSONWebToken 123inputStringExample;}"

        $p = New-Object System.Diagnostics.Process
        $p.StartInfo = $pinfo
        $p.Start() | Out-Null
        $p.WaitForExit()
        $stdout = $p.StandardOutput.ReadToEnd()
        $stderr = $p.StandardError.ReadToEnd()
        Write-Host "stdout: $stdout"
        Write-Host "stderr: $stderr"
        Write-Host "exit code: " + $p.ExitCode
$pinfo=新对象System.Diagnostics.ProcessStartInfo
$pinfo.FileName=$Ps6Path
$pinfo.RedirectStandardError=$true
$pinfo.RedirectStandardOutput=$true
$pinfo.CreateNoWindow=$false
$pinfo.Arguments=“-Command{Import Module\rest-api.psm1;Get JSONWebToken 123inputStringExample;}”
$p=新对象System.Diagnostics.Process
$p.StartInfo=$pinfo
$p.Start()|输出为空
$p.WaitForExit()
$stdout=$p.StandardOutput.ReadToEnd()
$stderr=$p.StandardError.ReadToEnd()
写入主机“stdout:$stdout”
写入主机“stderr:$stderr”
写入主机“退出代码:”+$p.ExitCode

这也只输出我在从C#或从PS6或PS5调用时传递的参数,这在技术上并不能解决问题,但我按照建议做了,并完全用C#重写了代码。这不是一个简单的问题,但最终它是一个很好的解决方案


如果您对如何正确解决这个问题有想法,请在这里发布,因为我仍然对如何从C#调用PowerShell 6上的东西感兴趣。

用任何.NET语言重写PowerShell脚本都非常简单,因为PS1脚本可以直接调用.NET Framework代码。除此之外,试一试?@MindSwipe如何?参见第二段:“PowerShell.Create();创建一个使用PowerShell 5的PowerShell实例。”。关于重写:我正在使用
Invoke RestMethod
,但我在C#中还没有找到一个同样易于使用的挂件,因此我有兴趣调用PS脚本。我们是在看不同版本的页面还是完全不同的页面?Create方法文档声明:Create()构造一个空的PowerShell实例;在调用此实例之前必须添加脚本或命令能否将PowerShell脚本添加到问题中?通过谷歌搜索Invoke-rest方法,我发现它与通过HttpClient@MindSwipe所有这些代码段都是为了实现同一目标而进行的不同尝试,我编辑了我的问题,以澄清这一点。那么PowerShell构造函数呢?我发现在创建实例时没有(简单的)方法来指定PowerShell版本,如果这就是您引用文档的原因的话。
        $pinfo = New-Object System.Diagnostics.ProcessStartInfo
        $pinfo.FileName = $Ps6Path
        $pinfo.RedirectStandardError = $true
        $pinfo.RedirectStandardOutput = $true
        $pinfo.CreateNoWindow = $false
        $pinfo.Arguments = "-Command {Import-Module <myPath>\rest-api.psm1; Get-JSONWebToken 123inputStringExample;}"

        $p = New-Object System.Diagnostics.Process
        $p.StartInfo = $pinfo
        $p.Start() | Out-Null
        $p.WaitForExit()
        $stdout = $p.StandardOutput.ReadToEnd()
        $stderr = $p.StandardError.ReadToEnd()
        Write-Host "stdout: $stdout"
        Write-Host "stderr: $stderr"
        Write-Host "exit code: " + $p.ExitCode