I take it you mean each step is running on its own thread? Semaphores dont help you gaurentee order. All the do is protect say thread A accessing the same thing as thread B. Which order thread A and thread B run in is down to the scheduler. So it might happen A grabs the semaphore, B tries to and waits, A releases semaphore, B contnues to run. Or it might happen B grabs the semaphore, A tries to and waits, B releases semaphore, A contnues to run - its up to the scheduler (and of course your theads priority). If you want things to happen one after the other, run them on the same thread: void Foo( { Step1(); Step2(); Step3(); } etc. If you really want each step to happen on it's own thread, then you need to use events. Look up CreateEvent/SetEvent/ResetEvent If I have the wrong end of the stick, and what you are asking is you want ShellExecuteEx not to return until the spawned process has finished, you do it like this. SHELLEXECUTEINFO si; si.fMask = SEE_MASK_NOCLOSEPROCESS; si.etc etc ShellExecuteEx(&si); WaitForSingleObject(si.hProcess, INFINATE);