我正在尝试致电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 都被加载。卸载该扩展后,所有模块均已正确加载,我不再需要手动导入模块。