• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2411
  • Last Modified:

ShellExecute block until executable is launched

Hi,

I'm currently using ShellExecute to execute an exe. I am looking for a way to make sure that the ShellExecute call does not return until the call has been completed..

ie : if you use ShellExecute as

long r = (long) ShellExecute(NULL,_T("open"),"myexe.exe", NULL, NULL, SW_SHOWNORMAL);

It will launch the myexe.exe but will not wait for it to complete. Is there any way for it to wait ?
0
oddbin
Asked:
oddbin
1 Solution
 
grg99Commented:
I suspect ShellExecute returns you  a process ID, so you can probably do a processwait or processinquiry until that process goes away?

0
 
Anthony2000Commented:
Here is an older solution that might work for you. Its basically the same as grg99's.
http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_20258300.html
0
 
LudvikJerabekCommented:
#include <windows.h>
#include <shellapi.h>
#include <tchar.h>

//      Function returns TRUE on success, and FALSE on failure
//      dwRet - is set to the process return code on success, and the result of GetLastError() on failure
//  nShow - is SW_SHOW ect...
//  tcWorkingDir - string of the working directory
//      tcExe - is the excutable name
//      tcArgs - are arguments to the executable
BOOL ShellExecuteWait( DWORD& dwRet , int nShow , TCHAR* tcExe , TCHAR* tcWorkingDir = NULL , TCHAR* tcArgs = NULL  )
{
      BOOL bRet = FALSE;
      SHELLEXECUTEINFO sexi = {0};
      sexi.cbSize = sizeof( SHELLEXECUTEINFO );
      // No Parent ( Note this is just for the example )
      sexi.hwnd = NULL;
      // Set flag so the hProcess handle is initialized by the call to ShellExecuteEx
      sexi.fMask = SEE_MASK_NOCLOSEPROCESS;
      sexi.lpDirectory = tcWorkingDir;
      sexi.lpFile = tcExe;
      sexi.lpParameters = tcArgs;
      sexi.nShow = nShow;
      
      // Returns Non-Zero on success
      if( ::ShellExecuteEx( &sexi ) )
      {
            DWORD dwSignaled = ::WaitForSingleObject( sexi.hProcess , INFINITE );
            // WAIT_OBJECT_0 is success for the event trigger
            if ( dwSignaled == WAIT_OBJECT_0 )
            {
                  // Returns Non-Zero on success
                  if( ::GetExitCodeProcess( sexi.hProcess , &dwRet ) )
                  {
                        bRet = TRUE;
                  }
            }
      }
      dwRet = ::GetLastError( );
      return bRet;
}
void main()
{
      DWORD dwRet;
      ShellExecuteWait( dwRet , SW_SHOW , _T("notepad.exe") , _T("C:\\windows") , _T("C:\\test.txt") );
}
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now