运行 来自 C# 的 PowerShell 6 中的 PowerShell 脚本
Run PowerShell script in PowerShell 6 from C#
我有一个与 REST 服务器通信的 PowerShell 脚本。此脚本仅适用于 PowerShell 6。
我想从 C# 调用它,因为 C# 程序需要来自 REST 服务器的信息,我不想在 C# 中重写 REST 代码。
基本上,我想 运行 来自 C# 的 PowerShell 脚本。 但是,在 C# 中,PowerShell.Create();
创建一个使用 PowerShell 5 的 PowerShell
实例。
我已经替换了默认文件夹中的 pwsh.exe,到处删除了 PowerShell 5 等等,当我 shift+right click
在任何地方使用 "Run PowerShell here" 时,我得到了 PowerShell 6 window。但出于某种原因,C# 在使用 PowerShell
class.
时坚持使用 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,首先导入一个模块然后使用它。这是我的三次尝试,它们都应该做同样的事情 :调用 Get-JSONWebToken
(在 rest-api.psm1
中)并正确检索输出。
C# 版本 1,使用 PowerShell
class:
ps = PowerShell.Create();
//module import...
PSCommand cmd = ps.Commands.AddCommand("Get-JSONWebToken");
cmd.AddParameter("baseUri", baseUri);
cmd.AddParameter("apiToken", apiToken);
ps.Invoke();
由于某种原因,这在 PowerShell 5 上总是 运行s,因此无法使用。
C# 版本 2,使用 Process
代替
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 上的 运行s,但只输出我传递的参数,而不输出 Get-JSONWebToken
。
C# 版本 3:从 C#PS5 调用 PS6
PSCommand cmd = ps.Commands.AddCommand("C:/Program Files/PowerShell/6/pwsh.exe");
ScriptBlock sb = ScriptBlock.Create("Import-Module " + modulePath + "; Get-JSONWebToken " + apiToken + ";");
cmd.AddParameter("Command", sb);
ps.Invoke();
这根本不起作用:
Result: Usage: pwsh[.exe] [[-File] <filePath> [args]]
Result: [-Command { - | <script-block> [-args <arg-array>]
Result: | <string> [<CommandParameters>] } ]
Result: [-ConfigurationName <string>] [-CustomPipeName <string>]
...
...
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
这也只输出我从 C# 或 PS6 或 PS5
调用时传递的参数
这在技术上并不能解决问题,但我按照 @MindSwipe 的建议做了,并完全用 C# 重写了代码。这并非易事,但最终是一个很好的优雅解决方案。
如果您对如何正确解决这个问题有想法,请post在这里,因为我仍然对如何从 C# 调用 PowerShell 6 感兴趣。
我有一个与 REST 服务器通信的 PowerShell 脚本。此脚本仅适用于 PowerShell 6。 我想从 C# 调用它,因为 C# 程序需要来自 REST 服务器的信息,我不想在 C# 中重写 REST 代码。
基本上,我想 运行 来自 C# 的 PowerShell 脚本。 但是,在 C# 中,PowerShell.Create();
创建一个使用 PowerShell 5 的 PowerShell
实例。
我已经替换了默认文件夹中的 pwsh.exe,到处删除了 PowerShell 5 等等,当我 shift+right click
在任何地方使用 "Run PowerShell here" 时,我得到了 PowerShell 6 window。但出于某种原因,C# 在使用 PowerShell
class.
这是我要重用的 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,首先导入一个模块然后使用它。这是我的三次尝试,它们都应该做同样的事情 :调用 Get-JSONWebToken
(在 rest-api.psm1
中)并正确检索输出。
C# 版本 1,使用 PowerShell
class:
ps = PowerShell.Create();
//module import...
PSCommand cmd = ps.Commands.AddCommand("Get-JSONWebToken");
cmd.AddParameter("baseUri", baseUri);
cmd.AddParameter("apiToken", apiToken);
ps.Invoke();
由于某种原因,这在 PowerShell 5 上总是 运行s,因此无法使用。
C# 版本 2,使用 Process
代替
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 上的 运行s,但只输出我传递的参数,而不输出 Get-JSONWebToken
。
C# 版本 3:从 C#PS5 调用 PS6
PSCommand cmd = ps.Commands.AddCommand("C:/Program Files/PowerShell/6/pwsh.exe");
ScriptBlock sb = ScriptBlock.Create("Import-Module " + modulePath + "; Get-JSONWebToken " + apiToken + ";");
cmd.AddParameter("Command", sb);
ps.Invoke();
这根本不起作用:
Result: Usage: pwsh[.exe] [[-File] <filePath> [args]]
Result: [-Command { - | <script-block> [-args <arg-array>]
Result: | <string> [<CommandParameters>] } ]
Result: [-ConfigurationName <string>] [-CustomPipeName <string>]
...
...
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
这也只输出我从 C# 或 PS6 或 PS5
调用时传递的参数这在技术上并不能解决问题,但我按照 @MindSwipe 的建议做了,并完全用 C# 重写了代码。这并非易事,但最终是一个很好的优雅解决方案。
如果您对如何正确解决这个问题有想法,请post在这里,因为我仍然对如何从 C# 调用 PowerShell 6 感兴趣。