Wednesday, February 13, 2008

Team Build hangs when using Pstools and the Exec task

In my new position they have given me deployment. Basically after the build and unit tests are run, they want the code deployed to the servers. We're running under IIS 7 so I've decided to write the deployment logic using AppCmd from the IIS 7 team. It looks like a very nice tool!

To execute the series of AppCmd commands (actually we've grouped them into a batch file that we call) we're using yet another Microsoft technology called Pstools. In this suite of tools there is psexec which allows you to execute remote commands. After we got past some odd domain --> workgroup permission errors, it works pretty well. The command we use is something like this "c:\tools\pstools\psexec /accepteula \\server cmd.exe /c c:\deploy\install.bat 0.0.25"

Back in our TFSBuild.proj file we're using the Exec task to execute this. Unfortunately the Exec task hangs. "Gonzobent" has submitted a wonderful write-up on this to Connect. I added my two cents in as well.

To get around this (as we need to so our deployment efforts can continue) we put the "non-interactive" switch (i.e. -d) on the psexec command. So now the command looks like this "c:\tools\pstools\psexec -d /accepteula \\server cmd.exe /c c:\deploy\install.bat 0.0.25". This is not ideal as we don't get any output back in the Team Build log file to see if the deployment works or not. We just assume it does - since I wrote it ;)

As I put in my comments on Connect, I think psexec is sending back MSBuild information it's not expecting. We ran into this a few years ago when we wrote a homegrown build system which had a Java application as it's Built Client. When a user ran a Ant script that failed, the system would just hang. There is a good article here that examples how we fixed it. We basically thread reading the output and error.

If anyone has any other work around ideas, please let us know.


Richard said...

If it's any consolation, I'm running into exactly the same problem, ant exec calling psexec calling a batch file on the remote machine and psexec hanging. If I do the same psexec command from a command prompt it works perfectly every time.

Grenade said...

For what it's worth: If psexec is called using the -d option, psexec will set the return code to the PID of the command it launched.

This means that MSBuild will assume an error code has been returned when in fact it's just the process id of whatever psexec fired up remotely. So it's valid to add an IgnoreExitCode attribute to your MSBuild Exec tag like so:

<Exec Command="psexec -d /accepteula ... IgnoreExitCode="true" />