1

I am calling Powershell scripts from C# using Process.Start(). How do I capture exceptions that are raised by the Powershell script in the C# code?

techjourneyman
  • 1,701
  • 3
  • 33
  • 53
  • you cant, see this answer: http://stackoverflow.com/questions/320767/how-to-catch-exceptions-from-processes-in-c-sharp/320779#320779 – Davide Piras Oct 27 '11 at 14:59

3 Answers3

5

Hosting the PowerShell engine in C# is pretty simple. This code uses a bit dated API but it still works and gives you an idea of what is involved:

string cmd = @"Get-ChildItem $home\Documents -recurse | " +
              "Where {!$_.PSIsContainer -and ($_.LastWriteTime -gt (Get-Date).AddDays(-7))} | " +
              "Sort Fullname | Foreach {$_.Fullname}";

Runspace runspace = null;
Pipeline pipeline = null;

try
{
    runspace = RunspaceFactory.CreateRunspace();
    runspace.Open();
    pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript(cmd);
    Collection<PSObject> results = pipeline.Invoke();
    foreach (PSObject obj in results)
    {
        // Consume the results
        Debug.WriteLine(obj);    
    }
}
catch (Exception ex)
{
    Debug.WriteLine(ex);
}
finally
{
    if (pipeline != null) pipeline.Dispose();
    if (runspace != null) runspace.Dispose();
}
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • Great. Thanks. I am getting the following exception while trying to run a one-liner script with just a write-host in it: **Cannot invoke this function because the current host does not implement it.** – techjourneyman Oct 27 '11 at 17:17
  • 2
    Yeah you won't be able to use Write-Host unless you implement a PowerShell host. It is a reasonable chunk of code. You can either avoid *-Host cmdlets and use Write-Output instead. Or for a sample host impl, look here: http://rkeithhill.wordpress.com/2010/09/21/make-ps1exewrapper/ Click on the SkyDrive link to download (don't try to copy from the blog post). – Keith Hill Oct 27 '11 at 19:12
  • Just a note, you don't need to pass `cmd` to `runspace.CreatePipeline`. – Tahir Hassan Nov 06 '12 at 10:49
  • Oops, that was a tad redundant. :-) Thanks for pointing that out. – Keith Hill Nov 07 '12 at 21:30
3

Apologies, I can't work out how to comment on Keith's answer.

Do you not need to check if (pipeline.error.Count > 0) and then make use of pipeline.error.Read() ?

I've been led to believe the try/catch you have won't handle any errors that occur at the runspace level.

RichardD
  • 315
  • 1
  • 4
  • 11
2

If you want to interact with powershell you should not use process.start but instead host powershell.

rerun
  • 25,014
  • 6
  • 48
  • 78
  • 1
    This doesn't mean creating a complete PowerShell Host: you just need a [`Runspace`](http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.runspace(VS.85).aspx) instance. – Richard Oct 27 '11 at 15:10