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#? (There are quite a few...)
- What does the error say? (DLL not found? PS-Execution-Policy denying the execution? ...)
- Which additional
using
statements have you added in your code?
As a well-intentioned advice:
You can (and probably should) read the guidelines for asking questions here.
(Poorly asked questions often gets closed.)
Nonetheless, this is what I did:
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
.
Then this error came up:
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'.
[Solution]
To sum up, I had to install the following NuGet packages, just for stopping the application complaining about missing DLLs:
System.Management.Automation (7.2.3)
(already mentioned above)
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.
So I executed ipfs 'pin ls'
directly from PowerShell and I got an error. ("ipfs not recognized as a name of a cmdlet, method or script.")
Then I changed the command to something, PowerShell should know:
dir
(as an alias of Get-ChildItem
): Worked.
ipconfig
(short-term for C:\Windows\System32\ipconfig.exe
): Worked.
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:
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.
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.
(I hope you get what I mean.)
In case you want to keep this design for e.g. 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. The easiest way might be ACLs on file system level, I guess.