Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Running Programs & Waiting For Them To Finish

Running Programs & Waiting For Them To Finish

Scheduled Pinned Locked Moved C / C++ / MFC
questionc++help
13 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Jason Teagle

    I want to run one program from my code in two ways; (a) run it and wait until it closes, and (b) run it, and then later on check if it is still running and if so, shut it down. I use ShellExecute() to run it (successfully), giving me an HINSTANCE. I was under the impression that MsgWaitForMultipleObjects() would be able to wait until the program had finished, so I used this: MsgWaitForMultupleObjects(1,(HANDLE *)&hInst, TRUE, INFINITE, 0); but it doesn't wait, it just goes right on to the next statement. I also tried QS_ALLINPUT originally for the last parameter; no change. I'm not quite sure what that last parameter does exactly. So, how do I wait for that program to finish? WaitForSingleObject() says it is not advised to use it in case the run program creates other threads (or something like that, it's all too deep for me), which is why I used MsgWait...(). Also, in 16-bit MFC you could call GetModuleUsage() to find out if the hInst was still running... how do I do this in 32-bit MFC? Also, how do I get a handle to the main window of that EXE from that hInst? Lastly, some functions such as GetModuleFileNameEx() require a module handle AND a process handle... MSDN says a module is an EXE or DLL, so if my hInst is an EXE, how on Earth do I get the process handle it belongs to? Or are they one and the same in this case? Help! :)

    T Offline
    T Offline
    Tomasz Sowinski
    wrote on last edited by
    #4

    > so if my hInst is an EXE, how on Earth do I get the > process handle it belongs to? On Earth you use GetCurrentProcess. Not sure about other celestial bodies. ;) Cheers, Tomasz Sowinski -- http://www.shooltz.com.pl

    J 1 Reply Last reply
    0
    • T Tomasz Sowinski

      Use ShellExecuteEX. It takes the address of a SHELLEXECUTEINFO structure as parameter. SHELLEXECUTEINFO has the hProcess member which you can pass to WaitForSingleObject or TerminateProcess. You can also use CreateProcess instead of ShellExecuteEx. Tomasz Sowinski -- http://www.shooltz.com.pl

      J Offline
      J Offline
      Jason Teagle
      wrote on last edited by
      #5

      ShellExecuteEx() certainly gave me the process handle - excellent. The problem I am left with now is that this program that I run needs to talk to my app using user-defined messages (through SendMessage() ). If I call WaitForSingleObject(), the second app is stuck. I tried using MsgWaitForMultipleObjects() with the process handle (which now waits as expected) and the final parameter of 0 - but the second app got stuck again. I tried QS_INPUT as the final parameter, which I believe means that my app (the one waiting) should still process any incoming messages as normal while it is waiting for the second app... but it still blocks. My only theory is that I have to call MsgWait...() from the actual window which will process those messages (it is currently being called from a window embedded in the main window, and not a direct descendant). Anyone know why I can't get my app to still process messages while waiting for that other app to exit?

      T S 2 Replies Last reply
      0
      • C Carlos Antollini

        Okay, Tomasz said you how get the hProcess... If you want to Know if the application is still running, you need to use the following. DWORD dwExitCode; GetExitCodeProcess(hProcess, &dwExitCode); If the application is still running dwExitCode returns STILL_ACTIVE Cheers!!! :) Carlos Antollini.

        J Offline
        J Offline
        Jason Teagle
        wrote on last edited by
        #6

        It worked perfectly, thanks!

        1 Reply Last reply
        0
        • T Tomasz Sowinski

          > so if my hInst is an EXE, how on Earth do I get the > process handle it belongs to? On Earth you use GetCurrentProcess. Not sure about other celestial bodies. ;) Cheers, Tomasz Sowinski -- http://www.shooltz.com.pl

          J Offline
          J Offline
          Jason Teagle
          wrote on last edited by
          #7

          Oops, I guess I was rambling on a bit there - I wanted to get the process of ANOTHER EXE, the one that I run from my code - GetCurrentProcess() is for the process of MY app, the original one - you already gave me the right answer, and that is to run the other EXE with ShellExecuteEx(), which gives the process handle.

          1 Reply Last reply
          0
          • J Jason Teagle

            ShellExecuteEx() certainly gave me the process handle - excellent. The problem I am left with now is that this program that I run needs to talk to my app using user-defined messages (through SendMessage() ). If I call WaitForSingleObject(), the second app is stuck. I tried using MsgWaitForMultipleObjects() with the process handle (which now waits as expected) and the final parameter of 0 - but the second app got stuck again. I tried QS_INPUT as the final parameter, which I believe means that my app (the one waiting) should still process any incoming messages as normal while it is waiting for the second app... but it still blocks. My only theory is that I have to call MsgWait...() from the actual window which will process those messages (it is currently being called from a window embedded in the main window, and not a direct descendant). Anyone know why I can't get my app to still process messages while waiting for that other app to exit?

            T Offline
            T Offline
            Tomasz Sowinski
            wrote on last edited by
            #8

            > If I call WaitForSingleObject(), the second app is stuck I'm not sure what do you mean by 'second app' - the one which called ShellExecuteEx, or the child process? Anyway, I'd move ShellExecuteEx and WaitForSingleObect to a separate thread - this way your message pump will work without any problems. When child process ends and WaitForSingleObject finishes, just call PostMessage to ensure that your main thread (the one with message pump) knows about it. Tomasz Sowinski -- http://www.shooltz.com.pl

            J 1 Reply Last reply
            0
            • T Tomasz Sowinski

              > If I call WaitForSingleObject(), the second app is stuck I'm not sure what do you mean by 'second app' - the one which called ShellExecuteEx, or the child process? Anyway, I'd move ShellExecuteEx and WaitForSingleObect to a separate thread - this way your message pump will work without any problems. When child process ends and WaitForSingleObject finishes, just call PostMessage to ensure that your main thread (the one with message pump) knows about it. Tomasz Sowinski -- http://www.shooltz.com.pl

              J Offline
              J Offline
              Jason Teagle
              wrote on last edited by
              #9

              If I have to tell the main thread that the other app ended, doesn't that defeat the whole point of WaitForSingleObject()? I want the code to hang around waiting for this second app (child process) before it continues, with the exception of processing the special messages. Actually, that is another issue - how can it process ONLY non-UI messages? I don't want to allow buttons to be clicked, things to be typed, the app to be closed, etc. I DO want timers to go off, repainting to be done, and my special messages to be processed... Perhaps I need to disable the main window of my application so the user can't interact, instead of trying to wait? That would still allow my special messages to be processed by the main frame (I think), and would solve this issue. But I still want to know how to do it properly...

              T 1 Reply Last reply
              0
              • J Jason Teagle

                If I have to tell the main thread that the other app ended, doesn't that defeat the whole point of WaitForSingleObject()? I want the code to hang around waiting for this second app (child process) before it continues, with the exception of processing the special messages. Actually, that is another issue - how can it process ONLY non-UI messages? I don't want to allow buttons to be clicked, things to be typed, the app to be closed, etc. I DO want timers to go off, repainting to be done, and my special messages to be processed... Perhaps I need to disable the main window of my application so the user can't interact, instead of trying to wait? That would still allow my special messages to be processed by the main frame (I think), and would solve this issue. But I still want to know how to do it properly...

                T Offline
                T Offline
                Tomasz Sowinski
                wrote on last edited by
                #10

                Your secondary thread will be in wait state in WaitForSingleObject until child process ends. Threads in wait state use no processor time - the impact on system resources will be minimal. It's the most "economical" way to wait for other process to finish. Disabling the main window is OK - if you deal with CFrameWnd derivatives, try BeginModalState/EndModalState. Tomasz Sowinski -- http://www.shooltz.com.pl

                1 Reply Last reply
                0
                • J Jason Teagle

                  ShellExecuteEx() certainly gave me the process handle - excellent. The problem I am left with now is that this program that I run needs to talk to my app using user-defined messages (through SendMessage() ). If I call WaitForSingleObject(), the second app is stuck. I tried using MsgWaitForMultipleObjects() with the process handle (which now waits as expected) and the final parameter of 0 - but the second app got stuck again. I tried QS_INPUT as the final parameter, which I believe means that my app (the one waiting) should still process any incoming messages as normal while it is waiting for the second app... but it still blocks. My only theory is that I have to call MsgWait...() from the actual window which will process those messages (it is currently being called from a window embedded in the main window, and not a direct descendant). Anyone know why I can't get my app to still process messages while waiting for that other app to exit?

                  S Offline
                  S Offline
                  Stephen Kellett
                  wrote on last edited by
                  #11

                  I think you've done WaitFor...() in the same thread as your windows message loop. If you want to do a wait and still process messages, you'll need to do that wait in another thread, and then when the wait completes post a message to your main thread (the one with the message loop) so that the main thread can do what it needs to do. Stephen Kellett -- C++/Java/Win NT/Unix variants Memory leaks/corruptions/performance/system problems. UK based. Problems with RSI/WRULD? Contact me for advice.

                  J 1 Reply Last reply
                  0
                  • S Stephen Kellett

                    I think you've done WaitFor...() in the same thread as your windows message loop. If you want to do a wait and still process messages, you'll need to do that wait in another thread, and then when the wait completes post a message to your main thread (the one with the message loop) so that the main thread can do what it needs to do. Stephen Kellett -- C++/Java/Win NT/Unix variants Memory leaks/corruptions/performance/system problems. UK based. Problems with RSI/WRULD? Contact me for advice.

                    J Offline
                    J Offline
                    Jason Teagle
                    wrote on last edited by
                    #12

                    I only want special messages and the most basic ones to be let through. I want WM_TIMER and WM_PAINT, and a couple of user defined messages. This is because the spawned process needs to use those special messages to get data from my app. I don't want the user to be able to interact with my program while the spawned process is running. I was under the impression that MsgWaitForMultipleObjects() could perform a wait while letting messages through, but that seems to do the same as WaitForSingleObject() - it stops message processing. Any ideas?

                    realJSOPR 1 Reply Last reply
                    0
                    • J Jason Teagle

                      I only want special messages and the most basic ones to be let through. I want WM_TIMER and WM_PAINT, and a couple of user defined messages. This is because the spawned process needs to use those special messages to get data from my app. I don't want the user to be able to interact with my program while the spawned process is running. I was under the impression that MsgWaitForMultipleObjects() could perform a wait while letting messages through, but that seems to do the same as WaitForSingleObject() - it stops message processing. Any ideas?

                      realJSOPR Offline
                      realJSOPR Offline
                      realJSOP
                      wrote on last edited by
                      #13

                      Try something along this line:

                      LPSTR cmdLine;
                      // set your commandline here
                      
                      PROCESS\_INFORMATION ProcessInfo;
                      STARTUPINFO StartupInfo = {0};
                      StartupInfo.cb          = sizeof(STARTUPINFO);
                      
                      if (::CreateProcess(NULL, cmdLine, NULL, NULL, FALSE,
                                          0, NULL, NULL, &StartupInfo, &ProcessInfo))
                      {
                      	DWORD dwStatus = STILL\_ACTIVE;
                      	while (dwStatus == STILL\_ACTIVE)
                      	{
                      		::GetExitCodeProcess(ProcessInfo.hProcess, &dwStatus);
                      		Sleep(1000);
                      	}
                      
                      	CloseHandle(ProcessInfo.hProcess);
                      	CloseHandle(ProcessInfo.hThread);
                      
                      }
                      

                      You may need/want to use peekMessage and TranslateMessage inside the while loop in order to intercept messages.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups