views:

1087

answers:

3

Hi, I've got a scipt executing in C# using the powershell async execution code on code project here:

http://www.codeproject.com/KB/threads/AsyncPowerShell.aspx?display=PrintAll&fid=407636&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2130851#xx2130851xx

I need to return the $lastexitcode and Jean-Paul describes how you can use a custom pshost class to return it. I can't find any method or property in pshost that returns the exit code.

This engine I have needs to ensure that script executes correctly.

Any help would be appreciated.

regards Bob.

Its the $lastexitcode and the $? variables I need to bring back.

Hi, Finally answered.
I found out about the $host variable. It implements a callback into the host, specifically a custom PSHost object, enabling you to return the $lastexitcode. Here is a link to an explanation of $host.

http://mshforfun.blogspot.com/2006/08/do-you-know-there-is-host-variable.html

It seems to be obscure, badly documented, as usual with powershell docs. Using point 4, calling $host.SetShouldExit(1) returns 1 to the SetShouldExit method of pshost, as described here.

http://msdn.microsoft.com/en-us/library/system.management.automation.host.pshost.setshouldexit(VS.85).aspx

Its really depends on defining your own exit code defintion. 0 and 1 suffixes I guess.

regards Bob.

+1  A: 

You can write in your script code that will check the $lastexitcode and will throw an exception if the exitcode is not what you excepted.
Exceptions are easier to catch.

Shay Erlichmen
Aw right ok. I've had a look at Trap. I'll check it out. I'm assume it returns in to the c# runtime, returned through the errors collection.
scope_creep
Hi Shay, is possible say throw an exception if the $? code is false.
scope_creep
you mean something like: if ($lastexitcode -eq 0) throw (new-object system.Exception("Error")
Shay Erlichmen
Howdy Shey,Thanks for the help.Bob.
scope_creep
+1  A: 

Here is a function you can try:

function run-process ($cmd, $params) {
$p = new-object System.Diagnostics.Process
$p.StartInfo = new-object System.Diagnostics.ProcessStartInfo
$exitcode = $false 
$p.StartInfo.FileName = $cmd
$p.StartInfo.Arguments = $params
$p.StartInfo.UseShellExecute = $shell
$p.StartInfo.WindowStyle = 1; #hidden.  Comment out this line to show output in separate console
$null = $p.Start()
$p.WaitForExit()
$exitcode = $p.ExitCode
$p.Dispose() 
return $exitcode
}

Hope that helps

Lance Robinson
Excellent mate. I'm still thinking the powershell, well is shell, and not .net, which is clearly is. thats solved one of my two main problems. Thanks.
scope_creep
Thanks Lance. .
scope_creep
A: 

I believe you are making a mountain out of a molehill by using this code project. Asynchronous execution is very easy to do in C#.

PowerShell psCmd = PowerShell.Create().AddScript({Invoke-YourScriptAndReturnLastExitCode});
IAsyncResult result = psCmd.BeginInvoke();
// wait for finish
psCmd.EndInvoke(result);

Also, looking at your question on that project, it looks like you are trying to use TFS in PowerShell. You can consider the following additional pieces of information:

  1. TFS has cmdlets
  2. Many other people have worked TFS cmdlets, i.e. PSTFS
  3. You can always copy the tfs executable wherever you need it, which sidesteps at least part of your scripts pain.

Hope this helps

Start-Automating
Hi MediaAndMicrocode, I never used lances code. I used a similar method to the one above, except much more robust, where I used a producer/consumer queue where each queue entry is a pshell execution block with the queue being services by several threads. A thread dequeues a execution block and selects 1 of several pshell execution engines, depending if they were blocked or not by an Autoresetevent. It works fine, is performant and is exactly what I was looking for. Thanks for the help.Bob.
scope_creep