从 C# 调用 PowerShell cmdlet 会抛出 CommandNotFoundException

2024-03-23

我正在尝试致电Add-AppxPackage来自 C# 的 cmdlet。我找到了 MSDN 文章从 C# 代码运行 PowerShell http://msdn.microsoft.com/en-us/library/dd182449%28v=vs.85%29.aspx。我引用了 System.Management.Automation 程序集并尝试了以下代码片段,所有这些代码片段在尝试调用 powerShell.Invoke() 时都会导致相同的异常:

System.Management.Automation.CommandNotFoundException 未处理

术语“Add-AppxPackage”未被识别为 cmdlet 的名称, 函数、脚本文件或可运行程序。检查拼写 名称,或者如果包含路径,请验证路径是否正确并且 再试一次。

片段 1:

var powerShell = PowerShell.Create();
powerShell.AddCommand(string.Format("Add-AppxPackage '{0}'", appxFilePath));

foreach (PSObject result in powerShell.Invoke())
{
    Console.WriteLine(result);
}

我明白为什么这不起作用,因为我不应该在 AddCommand() 函数中提供参数。

片段2:

var powerShell = PowerShell.Create();
powerShell.AddCommand("Add-AppxPackage");
powerShell.AddParameter("Path", appxFilePath);

foreach (PSObject result in powerShell.Invoke())
{
    Console.WriteLine(result);
}

片段 3:

var powerShell = PowerShell.Create();
powerShell.AddCommand("Add-AppxPackage");
powerShell.AddArgument(appxFilePath);

foreach (PSObject result in powerShell.Invoke())
{
    Console.WriteLine(result);
}

我的 C# 项目的目标是 .Net 4.5,如果我执行 powerShell.AddCommand("Get-Host") ,它就可以工作,并且返回的版本是 4.0。 Add-AppxPackage 是在 PowerShell v3.0 中添加的,因此该命令肯定存在,并且如果我从 Windows PowerShell 命令提示符手动运行此命令,它可以正常工作。

有什么想法我在这里做错了吗?任何建议表示赞赏。

- 更新 -

I found 这个帖子 https://stackoverflow.com/questions/17067971/invoking-powershell-cmdlets-from-c-sharp and this one https://stackoverflow.com/questions/13251076/calling-powershell-from-c-sharp,并意识到有一个 AddScript() 函数,所以我尝试了这个:

片段 4:

var powerShell = PowerShell.Create();
powerShell.AddScript(string.Format("Add-AppxPackage '{0}'", appxFilePath));

var results = powerShell.Invoke();
foreach (PSObject result in results)
{
    Console.WriteLine(result);
}

它不会抛出异常,但它也不会安装metro应用程序,并且从powerShell.Invoke()返回的“结果”是空的,所以我仍然不知所措......

-- 更新2 --

所以我决定尝试创建一个新的 PowerShell 进程来运行我的命令,所以我尝试了以下方法:

Process.Start(new ProcessStartInfo("PowerShell", string.Format("-Command Add-AppxPackage '{0}'; $key = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyUp')", appxFilePath)));

但它仍然抛出相同的错误,即 Add-AppxPackage 不是可识别的 cmdlet。

ANSWER

如果您关注 robert.westerlund 的答案上的长评论线程,您会发现,由于某种原因,当从 Visual Studio 运行/启动时,PowerShell 并未包含直接从 PowerShell 命令提示符运行时所包含的所有 PSModulePaths,所以很多模块不存在。解决方案是使用以下命令找到我需要的模块(在我的例子中是 appx 模块)的绝对路径:

(Get-Module appx -ListAvailable).Path

然后在尝试调用其 cmdlet 之一之前导入该模块。这是对我有用的 C# 代码:

var powerShell = PowerShell.Create();
powerShell.AddScript(string.Format(@"Import-Module 'C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Appx\Appx.psd1'; Add-AppxPackage '{0}'", appxFilePath));
var results = powerShell.Invoke();

更新的答案

你可以看到从我打开的另一篇文章 https://stackoverflow.com/questions/22696155/powershell-does-not-load-all-psmodulepaths-when-running-from-visual-studio-cod,问题是 Visual Studio 扩展(在我的例子中是 StudioShell)中的错误导致并非所有 PSModulePaths 都被加载。卸载该扩展后,所有模块均已正确加载,我不再需要手动导入模块。


在 PowerShell 中,终止错误(停止执行)和非终止错误(仅写入错误流)之间存在区别。

如果您想在自己的函数中创建非终止错误,只需使用Write-Errorcmdlet。如果您想创建终止错误,请使用Throw关键词。如果您运行,您可以阅读有关这些概念的更多信息Get-Help Write-Error, Get-Help about_Throw and Get-Help about_Try_Catch_Finally.

使用Add-AppxPackage对于不存在的包是一个非终止错误,因此将被写入错误流,但不会抛出执行停止异常。以下代码尝试添加不存在的包,然后将错误写入控制台。

var powerShell = PowerShell.Create();
powerShell.AddScript("Add-AppxPackage NonExistingPackageName");

// Terminating errors will be thrown as exceptions when calling the Invoke method. 
// If we want to handle terminating errors, we should place the Invoke call inside a try-catch block.
var results = powerShell.Invoke();

// To check if a non terminating error has occurred, test the HadErrors property
if (powerShell.HadErrors)
{
    // The documentation for the Error property states that "The command invoked by the PowerShell 
    // object writes information to this stream whenever a nonterminating error occurs."
    foreach (var error in powerShell.Streams.Error)
    {
        Console.WriteLine("Error: " + error);
    }
}
else
{
    foreach(var package in results)
    {
        Console.WriteLine(package);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 C# 调用 PowerShell cmdlet 会抛出 CommandNotFoundException 的相关文章

  • 以编程方式读取 SQL Server 查询计划建议的 SQL 特定执行的索引?

    如果我在 SSMS 中运行此命令 set showplan xml on GO exec some procedure arg1 arg2 arg3 GO set showplan xml off GO 我获得查询执行中涉及的完整调用堆栈的
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • JNI 将 Char* 2D 数组传递给 JAVA 代码

    我想从 C 代码通过 JNI 层传递以下指针数组 char result MAXTEST MAXRESPONSE 12 12 8 3 29 70 5 2 42 42 在java代码中我写了以下声明 public static native
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • 在Linux中,找不到框架“.NETFramework,Version=v4.5”的参考程序集

    我已经设置了 Visual studio 来在我的 Ubuntu 机器上编译 C 代码 我将工作区 我的代码加载到 VS 我可以看到以下错误 The reference assemblies for framework NETFramewo
  • 通过 PowerShell 运行 .cmd 文件

    我正在尝试使用 PowerShell 在远程服务器上运行 cmd 文件 在我的 ps1 脚本中我尝试过 C MyDirectory MyCommand cmd 它会导致此错误 C MyDirectory MyCommand cmd is n
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • C++ int 前面加 0 会改变整个值

    我有一个非常奇怪的问题 如果我像这样声明一个 int int time 0110 然后将其显示到控制台返回的值为72 但是当我删除前面的 0 时int time 110 然后控制台显示110正如预期的那样 我想知道两件事 首先 为什么它在
  • 打印大型 WPF 用户控件

    我有一个巨大的数据 我想使用 WPF 打印 我发现WPF提供了一个PrintDialog PrintVisual用于打印派生的任何 WPF 控件的方法Visual class PrintVisual只会打印一页 因此我需要缩放控件以适合页面
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • 可访问性不一致:参数类型的可访问性低于方法

    我试图在两个表单之间传递一个对象 基本上是对当前登录用户的引用 目前 我在登录表单中有一些类似的内容 private ACTInterface oActInterface public void button1 Click object s
  • 堆栈是向上增长还是向下增长?

    我在 C 中有这段代码 int q 10 int s 5 int a 3 printf Address of a d n int a printf Address of a 1 d n int a 1 printf Address of a
  • 使用 omp_set_num_threads() 将线程数设置为 2,但 omp_get_num_threads() 返回 1

    我有以下使用 OpenMP 的 C C 代码 int nProcessors omp get max threads if argv 4 NULL printf argv 4 s n argv 4 nProcessors atoi argv
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐