gpt4 book ai didi

c# - 如何在C#中获取PowerShell的Get-Command的 `Suggestion`?

转载 作者:行者123 更新时间:2023-12-03 01:03:09 26 4
gpt4 key购买 nike

如果我创建一个名为“dir.exe”的文件并运行PowerShell命令Get-Command dir -Type Application,则会出错,因为dir不是应用程序(尽管该文件存在):

gcm : The term 'dir' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:2
+ (gcm dir -Type Application)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (dir:String) [Get-Command], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand


Suggestion [3,General]: The command dir was not found, but does exist in the current location. Windows PowerShell does not load commands from the current location by default. If you trust this command, instead type: ".\dir". See "get-help about_Command_Precedence" for more details.

请注意底部的 Suggestion: Suggestion [3,General]: The command dir was not found, but does exist in the current location. Windows PowerShell does not load commands from the current location by default. If you trust this command, instead type: ".\dir". See "get-help about_Command_Precedence" for more details.
我正在尝试在我的C#代码中捕获该建议:
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management.Automation;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Helpers.Tests {
[TestClass]
public class PowerShellRunner_Tests {
[TestMethod]
public void GetCommand_Test() {
// create file called "dir.exe" to see how PowerShell handles
// "Get-Command dir -Type Application":
File.Create("dir.exe").Dispose();

using (PowerShell powerShell = PowerShell.Create()) {
powerShell.AddCommand("get-command")
.AddArgument("dir")
.AddParameter("Type", CommandTypes.Application.ToString());

// run "Get-Command dir -Type Application":
CommandInfo commandInfo = powerShell.Invoke<CommandInfo>().FirstOrDefault();

// get the error:
ErrorRecord error = powerShell.Streams.Error.FirstOrDefault();

// emit the "Suggestion":
Trace.WriteLine(error.ErrorDetails.RecommendedAction);
}
}
}
}

但是 error.ErrorDetailsnull。我如何获得该 Suggestion

(我正在尝试获取 where.exe的行为,但没有为此麻烦运行整个过程的麻烦)。

最佳答案

鉴于最终目标是模拟where.exe的行为,请尝试以下操作:

(Get-Command -Type Application .\dir, dir -ErrorAction Ignore).Path

请注意,使用 -Type Application将结果限制为可执行文件,并排除PowerShell内部命令(例如函数和别名)。

它将像 where.exe一样首先在当前目录中查找。
仅提供诸如 dir之类的名称, Get-Command不会在当前目录中查找,因为出于安全原因,PowerShell不允许仅按名称调用位于当前目录中的可执行文件。但是,使用相对路径 .\可以使 Get-Command找到这样的可执行文件。

但是,从 cmd.exe-假定 where.exe的行为-仅使用 dir.exe(仅按名称)调用仅当前目录的 dir即可。

如果输出只是一个路径,并且该路径是当前目录中的文件,则可以推断 dir可执行文件仅存在于当前目录中,这是PowerShell发出在调用时使用显式路径的建议的条件。 。
$fullPaths = (Get-Command -Type Application .\dir, dir -ErrorAction Ignore).Path
$emitSuggestion = $fullPaths.Count -eq 1 -and
(Test-Path ('.\' + (Split-Path -Leaf $fullPaths[0]))

注意:严格来说,您还应该排除当前目录恰好是 $env:PATH中列出的目录的情况: $env:PATH -split ';' -ne '' -notcontains (Split-Path -Parent $fullPaths[0])
您可以通过将建议的自定义版本通过 Write-Error写入错误流,或者最好使用 Write-Warning写入警告流,将其报告给C#代码。

要通过PowerShell SDK使用上述命令,最简单的方法是使用 .AddScript()方法。例如。:
powerShell.AddScript("(Get-Command -Type Application .\dir, dir -ErrorAction Ignore).Path");

关于捕获或隐藏PowerShell的建议:

不幸的是,您无法通过 以编程方式访问建议(从Windows PowerShell v5.1 / PowerShell Core 6.1.0开始编写):

就像您使用PowerShell SDK一样,涉及到PowerShell default host,它基本上不会发出建议。

只是控制台(终端)窗口中使用的 console host会发出建议,但即使在那里,建议也直接打印到屏幕上,绕过PowerShell的输出流系统。

简而言之: 建议仅在控制台窗口(终端)中显示,并且只能在控制台窗口中查看而不被捕获。

在控制台窗口中快速演示建议的行为(假设Windows,在当前目录中有一个名为 dir.exe的文件,而在 $env:PATH中也没有):
PS> & { try { Get-Command dir.exe } catch {} } *>$null

Suggestion [3,General]: The command dir.exe was not found, but does exist in the current location. Windows PowerShell does not load commands from the current location by default. If you trust this command, instead type: ".\dir.exe". See "get-help about_Command_Precedence" for more details.

如您所见,尽管尝试抑制所有输出( *>$null),该建议仍会显示在屏幕上,这也意味着 您无法捕获建议。

但是, 有一种使建议静音的方法,即使用-ErrorAction Ignore (PSv3 +);相比之下,使用 -ErrorAction SilentlyContinue时,建议仍会打印(!):
PS> & { try { Get-Command dir.exe -ErrorAction Ignore } catch {} } *>$null
# no output

关于c# - 如何在C#中获取PowerShell的Get-Command的 `Suggestion`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52975024/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com