0

I am trying to run a PowerShell script inside C# using .NET 4.6 I have tried to install the PowerShell NuGet but it doesn´t target .NET 4.6 Is there another way I could execute the PowerShell script?

I needed to specify powershell.exe to be able to run the script. But now I have another problem the PowerShell window closes immediately so I am not able to see the error message. I am using the following command

var s = Process.Start(@"Powershell.exe", $@"-noexit  -ExecutionPolicy Bypass -file ""MyScript.ps1; MyFunction"" ""{arguments}""");
s.WaitForExit();
doorman
  • 15,707
  • 22
  • 80
  • 145
  • 1
    Can you add some of the code you're using? – Dan Schnau Jan 09 '18 at 14:34
  • Hi @DanSchnau see the updated code... – doorman Jan 09 '18 at 16:01
  • @doorman Powershell does work in .NET 4.6. What did you try and what was the problem? If what you said was true *nobody* would be able to use it - 4.6 is a binary replacement for all previous 4.x versions. – Panagiotis Kanavos Jan 09 '18 at 16:52
  • Hi @PanagiotisKanavos basically I tried adding the Powershell Nuget package but it won´t install. Complains that it´s not targeted for 4.6 – doorman Jan 09 '18 at 16:54
  • @doorman what NuGet package? System.Management.Automation.dll is installed locally, eg in `C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0`. There may be multiple instances if you have different versions installed on the same machine – Panagiotis Kanavos Jan 09 '18 at 16:57
  • This one... https://www.nuget.org/packages/PowerShell/1.0.0 – doorman Jan 09 '18 at 16:59
  • @doorman if you refer to https://www.nuget.org/packages/System.Management.Automation/ the description clearly says this is an *unofficial* version which hasn't been updated since 2013. Add the library directly – Panagiotis Kanavos Jan 09 '18 at 16:59
  • @doorman did you check the author of this package? Are you *sure* you didn't just install a Trojan on your machine? That package has nothing to do with Powershell or Microsoft – Panagiotis Kanavos Jan 09 '18 at 17:00
  • No I didn´t check that, I assumed this was the main powershell package. – doorman Jan 09 '18 at 17:03
  • 1
    @doorman the author is some random guy, the package has *no* downloads to speak of - even the unofficial package from 2013 has 400K downloads. Why don't you try one of the dozens of tutorials on Powershell, eg [Executing Powershell Scripts from C#](https://blogs.msdn.microsoft.com/kebab/2014/04/28/executing-powershell-scripts-from-c/) or [Windows Powershell Host QuickStart](https://msdn.microsoft.com/en-us/library/dn569260(v=vs.85).aspx) from MSDN? – Panagiotis Kanavos Jan 09 '18 at 17:07
  • Thanks, I will have a better look.. – doorman Jan 09 '18 at 17:08
  • So I ended up using the automation library. https://stackoverflow.com/questions/48192219/calling-powershell-ps1-file-using-system-management-automation – doorman Jan 10 '18 at 20:22

1 Answers1

1

Yes, you can run it as you run any external program. System.Diagnostics.Process will help you out.

Here is a code example from Microsoft community:

using System.Diagnostics;

namespace ConsoleApplication2
{
 class Program
 {
  static void Main(string[] args)
  {
   Process myProcess = new Process();

   myProcess.StartInfo.FileName = @"ConsoleApplication1.exe";
   myProcess.StartInfo.UseShellExecute = false;
   myProcess.StartInfo.RedirectStandardOutput = true;
   myProcess.StartInfo.RedirectStandardInput = true;

   myProcess.Start();

   string redirectedOutput=string.Empty;
   while ((redirectedOutput += (char)myProcess.StandardOutput.Read()) != "Enter File Name:") ;

   myProcess.StandardInput.WriteLine("passedFileName.txt");

   myProcess.WaitForExit();

   //verifying that the job was successfull or not?!
   Process.Start("explorer.exe", "passedFileName.txt");
  }
 }
}

ConsoleApplication1.exe should be replaced with YourApplication.ps1

Why would you ever use System.Diagnostics.Process rather than System.Management.Automation which is recommended? Because powershell is slow and if you ever need to replace it, using System.Diagnostics.Process will allow doing it immediately.

henrycarteruk
  • 12,708
  • 2
  • 36
  • 40
Mindaugas Bernatavičius
  • 3,757
  • 4
  • 31
  • 58
  • Hi Mindaugas, thanks for your help. I updated my question, do you know how I can prevent the powershell window from closing, or how I can get the error that occurs in the script? – doorman Jan 09 '18 at 15:44
  • 1
    If the problem is in Powershell code, run the script on it's own w/o the calling code. To see the output / error message just call it from Powershell shell. Run > poershell > navigate the the scipt dir > run that Powershell script. It will print out the error. – Mindaugas Bernatavičius Jan 09 '18 at 16:28
  • Hi Mindaugas, when I call it from the powershell like this powershell -executionPolicy bypass -noexit -file "myproject.ps1 myfunction" it complains that the file does not have a .ps1 extension. Is this the right way to trigger a function in a ps file? – doorman Jan 09 '18 at 16:38
  • There's no reason to use Process.Start at all because you *can* create a Powershell Pipeline in .NET. – Panagiotis Kanavos Jan 09 '18 at 16:51
  • Hi @PanagiotisKanavos could you give an example using .NET 4.6? – doorman Jan 09 '18 at 16:53
  • @doorman every single one of them. What did you try and what was the problem? Did you add the System.Management.Automation dll? – Panagiotis Kanavos Jan 09 '18 at 16:53
  • @PanagiotisKanavos so far I only tried using Process – doorman Jan 09 '18 at 16:55
  • Go w/ the .NET Powershell native approach only if you will stick to powershell. It is often that opwershell is only the initial approach and then when you rewrite it into something else you might need to rewrite the C# interface to your PS scripts as well. – Mindaugas Bernatavičius Jan 10 '18 at 08:23