views:

1193

answers:

3

Imagine a DOS style .cmd file which is used to launch interdependent windowed applications in the right order.

Example: 1) Launch a server application by calling an exe with parameters. 2) Wait for the server to become initialized (or a fixed amount of time). 3) Launch client application by calling an exe with parameters.

What is the simplest way of accomplishing this kind of batch job in PowerShell?

A: 

To wait 10 seconds between launching the applications, try

launch-server-application serverparam1 serverparam2 ...
Start-Sleep -s 10
launch-client-application clientparam1 clientparam2 clientparam3 ...

If you want to create a script and have the arguments passed in, create a file called runlinkedapps.ps1 (or whatever) with these contents:

launch-server-application $args[0] $args[1]
Start-Sleep -s 10
launch-client-application $args[2] $args[3] $args[4]

Or however you choose to distribute the server and client parameters on the line you use to run runlinkedapps.ps1. If you want, you could even pass in the delay here, instead of hardcoding 10.

Remember, your .ps1 file need to be on your Path, or you'll have to specify its location when you run it. (Oh, and I've assumed that launch-server-application and launch-client-application are on your Path - if not, you'll need to specify the full path to them as well.)

Blair Conrad
+4  A: 

Remember that PowerShell can access .Net objects. The Start-Sleep as suggested by Blair Conrad can be replaced by a call to WaitForInputIdle of the server process so you know when the server is ready before starting the client.

$sp = get-process server-application
$sp.WaitForInputIdle()

You could also use Process.Start to start the process and have it return the exact Process. Then you don't need the get-process.

$sp = [diagnostics.process]::start("server-application", "params")
$sp.WaitForInputIdle()
$cp = [diagnostics.process]::start("client-application", "params")
Lars Truijens
+1  A: 

@Lars Truijens suggested

Remember that PowerShell can access .Net objects. The Start-Sleep as suggested by Blair Conrad can be replaced by a call to WaitForInputIdle of the server process so you know when the server is ready before starting the client.

This is more elegant than sleeping for a fixed (or supplied via parameter) amount of time. However, WaitForInputIdle

applies only to processes with a user interface and, therefore, a message loop.

so this may not work, depending on the characteristics of launch-server-application. However, as Lars pointed out to me, the question referred to a windowed application (which I missed when I read the question), so his solution is probably best.

Blair Conrad
Yes, you are right. However because the question stated windowed applications I assumed this is the case.
Lars Truijens
Excellent point, Lars. I read that as "Windows". Oops. Still, it may be useful information for someone, sometime...
Blair Conrad
If the process you are launching is a command line process you can use $sp.WaitForExit()
Omar Shahine