简体   繁体   English

使用 C# 中的参数运行 PowerShell 命令

[英]Run PowerShell command with parameters in C#

I am trying to run a PowerShell command and having problems with it.我正在尝试运行 PowerShell 命令并遇到问题。 Here is the code:这是代码:

PowerShell ps = PowerShell.Create();
ps.AddScript("ipfs 'pin ls'");
var result = await ps.InvokeAsync();
string response = "";
foreach (var entry in result)
{
    response += entry.BaseObject.ToString() + "/";
}

What am I doing wrong?我究竟做错了什么? Thanks谢谢

First of all, I would highly recommend to ask more than just "This is my code; What am I doing wrong?".首先,我强烈建议问的不仅仅是“这是我的代码;我做错了什么?”。

For instance:例如:

  • Which NuGet package with which version have you installed to use PowerShell within C#?哪个NuGet package你安装了哪个版本才能在C#中使用PowerShell? (There are quite a few...) (有好几个……)
  • What does the error say?错误说明了什么? (DLL not found? PS-Execution-Policy denying the execution? ...) (未找到 DLL?PS-Execution-Policy 拒绝执行?...)
  • Which additional using statements have you added in your code?您在代码中添加了哪些额外using语句?

As a well-intentioned advice:作为善意的建议:
You can (and probably should) read the guidelines for asking questions here .您可以(并且可能应该)在此处阅读提问指南
(Poorly asked questions often gets closed.) (问得不好的问题通常会被关闭。)


N.netheless, this is what I did: N.尽管如此,这就是我所做的:
Copied your code and pasted it in VS 2022, installed the Package System.Management.Automation (7.2.3) and tried to build and debug it with .NET 6.0 .复制您的代码并将其粘贴到 VS 2022 中,安装 Package System.Management.Automation (7.2.3)并尝试使用.NET 6.0构建和调试它。

Then this error came up:然后出现了这个错误:
System.Management.Automation.Runspaces.PSSnapInException : System.Management.Automation.Runspaces.PSSnapInException
"Cannot load PowerShell snap-in Microsoft.PowerShell.Diagnostics because of the following error: Could not load file or assembly 'X:\TestProject\bin\Debug.net6.0-windows\runtimes\win\lib.net6.0\Microsoft.PowerShell.Commands.Diagnostics.dll'. “无法加载 PowerShell 管理单元 Microsoft.PowerShell.Diagnostics,因为以下错误:无法加载文件或程序集 'X:\TestProject\bin\Debug.net6.0-windows\runtimes\win\lib.net6.0\ Microsoft.PowerShell.Commands.Diagnostics.dll'。

[Solution] [解决方案]
To sum up, I had to install the following NuGet packages, just for stopping the application complaining about missing DLLs:总而言之,我必须安装以下 NuGet 包,只是为了停止抱怨缺少 DLL 的应用程序:

  • System.Management.Automation (7.2.3) (already mentioned above) System.Management.Automation (7.2.3) (上面已经提到)
  • Microsoft.PowerShell.Commands.Diagnostics (7.2.3)
  • Microsoft.PowerShell.ConsoleHost (7.2.3)
  • Microsoft.PowerShell.Commands.Utility (7.2.3)
  • Microsoft.PowerShell.Commands.Management (7.2.3)
  • Microsoft.WSMan.Management (7.2.3)

Finally, the application did not crash.最后,应用程序没有崩溃。

However, the output was empty.但是,output 是空的。
So I executed ipfs 'pin ls' directly from PowerShell and I got an error.所以我直接从 PowerShell 执行ipfs 'pin ls'就报错了。 ( "ipfs not recognized as a name of a cmdlet, method or script." ) “ipfs 未被识别为 cmdlet、方法或脚本的名称。”

Then I changed the command to something, PowerShell should know:然后我将命令更改为一些东西,PowerShell 应该知道:

  • dir (as an alias of Get-ChildItem ): Worked. dir (作为Get-ChildItem的别名):有效。
  • ipconfig (short-term for C:\Windows\System32\ipconfig.exe ): Worked. ipconfigC:\Windows\System32\ipconfig.exe的简称):有效。

What I did not experience in this case, but in the past:我在这种情况下没有经历过,但在过去:
If there shows up an error concerning the execution policy, you could execute the following command:如果出现关于执行策略的错误,您可以执行以下命令:

// Create instance
var PsInstance = PowerShell.Create();
// Allow execution of any scripts for the current user
// (does not require administrator privileges)
var policy = PsInstance.AddCommand("Set-ExecutionPolicy")
               .AddArgument("Unrestricted")
               .AddParameter("Scope", "CurrentUser")
               .Invoke();
// Wipe the command pipeline to avoid executing the previous command
// everytime .Invoke() will be invoked.
PsInstance.Commands.Clear();
// continue with your code here...

Besides the PowerShell topic:除了 PowerShell 主题:
If ipfs is an executable, I would recommend to directly invoke it using Process.Start with additional parameters, as Seva Alekseyev already commented below your question.如果ipfs是可执行文件,我建议使用带有附加参数的Process.Start直接调用它,因为 Seva Alekseyev 已经在您的问题下方发表了评论。
In my option, it would be a much better solution with way less overhead and dependencies and much better performance, since you will get rid of PowerShell as an additional (and unnecessary) layer between your code and the third party application.在我的选择中,这将是一个更好的解决方案,具有更少的开销和依赖性以及更好的性能,因为您将摆脱 PowerShell 作为代码和第三方应用程序之间的附加(和不必要的)层。
(I hope you get what I mean.) (我希望你明白我的意思。)

In case you want to keep this design for eg reading ps1 files and dynamically loading and executing them in your PowerShell session (what is absolutely valid), then I would highly recommend to protect the ps1 files for unauthorized modifications, especially if your application will be executed with administrator privileges.如果您想保留此设计,例如读取ps1文件并在您的 PowerShell session 中动态加载和执行它们(绝对有效),那么我强烈建议保护ps1文件以防止未经授权的修改,特别是如果您的应用程序将以管理员权限执行。 The easiest way might be ACLs on file system level, I guess.我想,最简单的方法可能是文件系统级别的 ACL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM