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. Using ShellExecute or CreateProcess caller lose its focus

Using ShellExecute or CreateProcess caller lose its focus

Scheduled Pinned Locked Moved C / C++ / MFC
c++comhelptutorialannouncement
25 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.
  • S Offline
    S Offline
    sdancer75
    wrote on last edited by
    #1

    I want to call an external application (created by me) using ShellExecute or CreateProcess. It is just an update application for the main app. The problem is, what ever I tried I failed to get window focus back to my main app when the process (update app) is terminated. I created a simple MFC/SDI app that calls window's notepad under "C:\windows\notepad.exe" which suffers from the same problem, just to show you what I mean. I need the parent window -which is the main app- to be disabled (like a modal dialog box behaviour) until the new app -update application- will finish its job. PS:If I do not disable the main window with EnableWindow(FALSE) I have paint corruption with windows XP and back when I move the update application. Here an example: http://www.filedropper.com/shellexecutecreateprocesstestapp[^]

    sdancer75

    Richard Andrew x64R J V 3 Replies Last reply
    0
    • S sdancer75

      I want to call an external application (created by me) using ShellExecute or CreateProcess. It is just an update application for the main app. The problem is, what ever I tried I failed to get window focus back to my main app when the process (update app) is terminated. I created a simple MFC/SDI app that calls window's notepad under "C:\windows\notepad.exe" which suffers from the same problem, just to show you what I mean. I need the parent window -which is the main app- to be disabled (like a modal dialog box behaviour) until the new app -update application- will finish its job. PS:If I do not disable the main window with EnableWindow(FALSE) I have paint corruption with windows XP and back when I move the update application. Here an example: http://www.filedropper.com/shellexecutecreateprocesstestapp[^]

      sdancer75

      Richard Andrew x64R Offline
      Richard Andrew x64R Offline
      Richard Andrew x64
      wrote on last edited by
      #2

      You could wait on the process handle returned by ShellExecute or CreateProcess, this will let you know when the child process has exited. Then you could use BringWindowToTop to bring your main application window to the foreground.

      The difficult we do right away... ...the impossible takes slightly longer.

      S 1 Reply Last reply
      0
      • Richard Andrew x64R Richard Andrew x64

        You could wait on the process handle returned by ShellExecute or CreateProcess, this will let you know when the child process has exited. Then you could use BringWindowToTop to bring your main application window to the foreground.

        The difficult we do right away... ...the impossible takes slightly longer.

        S Offline
        S Offline
        sdancer75
        wrote on last edited by
        #3

        Thank you for your answer. As you can see in the code I am using WaitForSingleObject. I tried to use also the BringWindowToTop with no luck. What ever I tried I had no success.

        sdancer75

        L 1 Reply Last reply
        0
        • S sdancer75

          Thank you for your answer. As you can see in the code I am using WaitForSingleObject. I tried to use also the BringWindowToTop with no luck. What ever I tried I had no success.

          sdancer75

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          sdancer75 wrote:

          As you can see ... What ever I tried I had no success.

          We cannot see anything, you need to show your code and explain where it goes wrong.

          S 1 Reply Last reply
          0
          • S sdancer75

            I want to call an external application (created by me) using ShellExecute or CreateProcess. It is just an update application for the main app. The problem is, what ever I tried I failed to get window focus back to my main app when the process (update app) is terminated. I created a simple MFC/SDI app that calls window's notepad under "C:\windows\notepad.exe" which suffers from the same problem, just to show you what I mean. I need the parent window -which is the main app- to be disabled (like a modal dialog box behaviour) until the new app -update application- will finish its job. PS:If I do not disable the main window with EnableWindow(FALSE) I have paint corruption with windows XP and back when I move the update application. Here an example: http://www.filedropper.com/shellexecutecreateprocesstestapp[^]

            sdancer75

            J Offline
            J Offline
            Jochen Arndt
            wrote on last edited by
            #5

            When the external update process should also update the executable of your main application, that must be terminated before the new exe file can be copyied. So there is no need to get the focus back. A typical sequence for such a process:

            • Ask the user if the update should be installed
            • Perform closing tasks that are time consuming or require user interaction like closing open documents
            • Start the update process
            • Terminate your application
            • The update process should check if there is a running instance of your application (after a short wait time) and terminate with an error if so
            • The update process might restart your application

            In another post you mentioned that you are using WaitForSingleObject to wait for the update process to be terminated. If you call that from within your main thread, your application's message loop is blocked so that paint events are not processed. If you don't want to update the executable itself and must wait for the external process to be finished start the process from within a worker thread where you can call WaitForSingleObject without blocking the message loop. Use a global state variable indicating that the update is executing to disallow specific tasks of your application or just show a modal dialog that is closed automatically when the update has finished.

            S 1 Reply Last reply
            0
            • S sdancer75

              I want to call an external application (created by me) using ShellExecute or CreateProcess. It is just an update application for the main app. The problem is, what ever I tried I failed to get window focus back to my main app when the process (update app) is terminated. I created a simple MFC/SDI app that calls window's notepad under "C:\windows\notepad.exe" which suffers from the same problem, just to show you what I mean. I need the parent window -which is the main app- to be disabled (like a modal dialog box behaviour) until the new app -update application- will finish its job. PS:If I do not disable the main window with EnableWindow(FALSE) I have paint corruption with windows XP and back when I move the update application. Here an example: http://www.filedropper.com/shellexecutecreateprocesstestapp[^]

              sdancer75

              V Offline
              V Offline
              Victor Nijegorodov
              wrote on last edited by
              #6

              > I need the parent window -which is the main app- to be disabled (like a modal dialog box behaviour) until the new app -update application- will finish its job. Did you try to hide or minimize the "parent window" instead?

              S 1 Reply Last reply
              0
              • V Victor Nijegorodov

                > I need the parent window -which is the main app- to be disabled (like a modal dialog box behaviour) until the new app -update application- will finish its job. Did you try to hide or minimize the "parent window" instead?

                S Offline
                S Offline
                sdancer75
                wrote on last edited by
                #7

                Yes this way it works but I dont want to minimize the parent window. I need a modal like behaviour.

                sdancer75

                1 Reply Last reply
                0
                • J Jochen Arndt

                  When the external update process should also update the executable of your main application, that must be terminated before the new exe file can be copyied. So there is no need to get the focus back. A typical sequence for such a process:

                  • Ask the user if the update should be installed
                  • Perform closing tasks that are time consuming or require user interaction like closing open documents
                  • Start the update process
                  • Terminate your application
                  • The update process should check if there is a running instance of your application (after a short wait time) and terminate with an error if so
                  • The update process might restart your application

                  In another post you mentioned that you are using WaitForSingleObject to wait for the update process to be terminated. If you call that from within your main thread, your application's message loop is blocked so that paint events are not processed. If you don't want to update the executable itself and must wait for the external process to be finished start the process from within a worker thread where you can call WaitForSingleObject without blocking the message loop. Use a global state variable indicating that the update is executing to disallow specific tasks of your application or just show a modal dialog that is closed automatically when the update has finished.

                  S Offline
                  S Offline
                  sdancer75
                  wrote on last edited by
                  #8

                  Quote:

                  When the external update process should also update the executable of your main application, that must be terminated before the new exe file can be copyied. So there is no need to get the focus back.

                  I have managed this kind of problems with success so, dont bother with that.

                  Quote:

                  In another post you mentioned that you are using WaitForSingleObject to wait for the update process to be terminated. If you call that from within your main thread, your application's message loop is blocked so that paint events are not processed.

                  Thats correct. Windows Vista/Win7/Win8 does not have problems with paint events but XP they have. For that reason I want to disable the parent to avoid such kind of problems.

                  Quote:

                  If you don't want to update the executable itself and must wait for the external process to be finished start the process from within a worker thread where you can call WaitForSingleObject without blocking the message loop. Use a global state variable indicating that the update is executing to disallow specific tasks of your application or just show a modal dialog that is closed automatically when the update has finished.

                  I update the executables too, but I dont have problems with that. If you download the sample code, you will understand the focus problem i currently have.

                  sdancer75

                  J 1 Reply Last reply
                  0
                  • L Lost User

                    sdancer75 wrote:

                    As you can see ... What ever I tried I had no success.

                    We cannot see anything, you need to show your code and explain where it goes wrong.

                    S Offline
                    S Offline
                    sdancer75
                    wrote on last edited by
                    #9

                    I posted a link in my 1st post with a sample MFC/SDI application that have all the code you need. http://www.filedropper.com/shellexecutecreateprocesstestapp[^]

                    sdancer75

                    V 1 Reply Last reply
                    0
                    • S sdancer75

                      I posted a link in my 1st post with a sample MFC/SDI application that have all the code you need. http://www.filedropper.com/shellexecutecreateprocesstestapp[^]

                      sdancer75

                      V Offline
                      V Offline
                      Victor Nijegorodov
                      wrote on last edited by
                      #10

                      But what is a problem for you to attach a piece of code to your post?

                      S 1 Reply Last reply
                      0
                      • V Victor Nijegorodov

                        But what is a problem for you to attach a piece of code to your post?

                        S Offline
                        S Offline
                        sdancer75
                        wrote on last edited by
                        #11

                        Hi, No problem at all, I just gave all the code in the link. Anyway, I attach you the most important code from the sample app.

                        void CMainFrame::OnRunExternalApp() {

                        SHELLEXECUTEINFO	lpExecInfo;
                        PROCESS\_INFORMATION processInfo;
                        DWORD				dwExitCode;
                        HANDLE				hProcess = 0;
                        BOOL				bResult;
                        LPTSTR				strCmd;
                        
                        
                        
                        
                        
                        strCmd = \_T("");
                        
                        //bResult = StartupApplicationWithShell (\_T("LiveUpdate.exe"), (LPTSTR)strCmd,  GetSafeHwnd(), &hProcess);
                        bResult = StartupApplicationWithProcess (\_T("C:\\\\Windows\\\\notepad.exe"), (LPTSTR)strCmd,  &processInfo);
                        
                        EnableWindow(FALSE);
                        
                        
                        
                        if(bResult) { //(UINT)result > HINSTANCE\_ERROR)
                        
                        	//ShowWindow( SW\_HIDE );
                        	//ShowWindow( SW\_SHOWNOACTIVATE );
                        	
                        
                            //WaitForSingleObject( hProcess, INFINITE );
                        	WaitForSingleObject(processInfo.hProcess, INFINITE);
                        	//WaitForMultipleObjects(1, &processInfo.hThread, TRUE, INFINITE );
                        
                        
                        
                        	   
                        	//if (!GetExitCodeProcess(hProcess, &dwExitCode)) {
                        	//	   	AMLOGINFO(\_T("LiveUpdate is not terminated normally.")); 
                        	//}
                        	if (!GetExitCodeProcess(processInfo.hProcess, &dwExitCode)) {
                        		   	//failed
                        	}
                        	CloseHandle( processInfo.hProcess );
                            CloseHandle( processInfo.hThread );
                        	//CloseHandle(hProcess);
                        
                        
                        } else {
                        	
                        	// failed
                        }
                        
                        BringWindowToTop();
                        EnableWindow(TRUE);
                        
                        //UpdateWindow();
                        
                        //::SetWindowPos( GetSafeHwnd(), HWND\_TOP, 0, 0, 0, 0, SWP\_NOMOVE | SWP\_NOSIZE | SWP\_SHOWWINDOW );
                        

                        }

                        sdancer75

                        V 1 Reply Last reply
                        0
                        • S sdancer75

                          Hi, No problem at all, I just gave all the code in the link. Anyway, I attach you the most important code from the sample app.

                          void CMainFrame::OnRunExternalApp() {

                          SHELLEXECUTEINFO	lpExecInfo;
                          PROCESS\_INFORMATION processInfo;
                          DWORD				dwExitCode;
                          HANDLE				hProcess = 0;
                          BOOL				bResult;
                          LPTSTR				strCmd;
                          
                          
                          
                          
                          
                          strCmd = \_T("");
                          
                          //bResult = StartupApplicationWithShell (\_T("LiveUpdate.exe"), (LPTSTR)strCmd,  GetSafeHwnd(), &hProcess);
                          bResult = StartupApplicationWithProcess (\_T("C:\\\\Windows\\\\notepad.exe"), (LPTSTR)strCmd,  &processInfo);
                          
                          EnableWindow(FALSE);
                          
                          
                          
                          if(bResult) { //(UINT)result > HINSTANCE\_ERROR)
                          
                          	//ShowWindow( SW\_HIDE );
                          	//ShowWindow( SW\_SHOWNOACTIVATE );
                          	
                          
                              //WaitForSingleObject( hProcess, INFINITE );
                          	WaitForSingleObject(processInfo.hProcess, INFINITE);
                          	//WaitForMultipleObjects(1, &processInfo.hThread, TRUE, INFINITE );
                          
                          
                          
                          	   
                          	//if (!GetExitCodeProcess(hProcess, &dwExitCode)) {
                          	//	   	AMLOGINFO(\_T("LiveUpdate is not terminated normally.")); 
                          	//}
                          	if (!GetExitCodeProcess(processInfo.hProcess, &dwExitCode)) {
                          		   	//failed
                          	}
                          	CloseHandle( processInfo.hProcess );
                              CloseHandle( processInfo.hThread );
                          	//CloseHandle(hProcess);
                          
                          
                          } else {
                          	
                          	// failed
                          }
                          
                          BringWindowToTop();
                          EnableWindow(TRUE);
                          
                          //UpdateWindow();
                          
                          //::SetWindowPos( GetSafeHwnd(), HWND\_TOP, 0, 0, 0, 0, SWP\_NOMOVE | SWP\_NOSIZE | SWP\_SHOWWINDOW );
                          

                          }

                          sdancer75

                          V Offline
                          V Offline
                          Victor Nijegorodov
                          wrote on last edited by
                          #12

                          Maybe this will help you: windows forceforeground (bringWindowToTop) brings it to top but without being active (a forceForeGround that works with windows xp and windows 7) | Roger's woze[^]

                          S 1 Reply Last reply
                          0
                          • V Victor Nijegorodov

                            Maybe this will help you: windows forceforeground (bringWindowToTop) brings it to top but without being active (a forceForeGround that works with windows xp and windows 7) | Roger's woze[^]

                            S Offline
                            S Offline
                            sdancer75
                            wrote on last edited by
                            #13

                            I will give it a try but as you may already see, I am using the bringWindowToTop without success. Thanx

                            sdancer75

                            V 1 Reply Last reply
                            0
                            • S sdancer75

                              Quote:

                              When the external update process should also update the executable of your main application, that must be terminated before the new exe file can be copyied. So there is no need to get the focus back.

                              I have managed this kind of problems with success so, dont bother with that.

                              Quote:

                              In another post you mentioned that you are using WaitForSingleObject to wait for the update process to be terminated. If you call that from within your main thread, your application's message loop is blocked so that paint events are not processed.

                              Thats correct. Windows Vista/Win7/Win8 does not have problems with paint events but XP they have. For that reason I want to disable the parent to avoid such kind of problems.

                              Quote:

                              If you don't want to update the executable itself and must wait for the external process to be finished start the process from within a worker thread where you can call WaitForSingleObject without blocking the message loop. Use a global state variable indicating that the update is executing to disallow specific tasks of your application or just show a modal dialog that is closed automatically when the update has finished.

                              I update the executables too, but I dont have problems with that. If you download the sample code, you will understand the focus problem i currently have.

                              sdancer75

                              J Offline
                              J Offline
                              Jochen Arndt
                              wrote on last edited by
                              #14

                              My intention was to show you a solution that differs from your current implementation and pointing to the fact that you block the message loop. You must not call WaitForSingleObject from within your main thread to ensure that the window is repainted (e.g. when moving another window over the application window). That will solve the problem of paint corruption and might also solve your other problems. Overall I think I must shout: Don't use WaitForSingleObject from within your main GUI thread; especially with long wait times! I (like most others here) will not download a complete project and build it. Especially in this case where it must be tested with XP too.

                              S 1 Reply Last reply
                              0
                              • S sdancer75

                                I will give it a try but as you may already see, I am using the bringWindowToTop without success. Thanx

                                sdancer75

                                V Offline
                                V Offline
                                Victor Nijegorodov
                                wrote on last edited by
                                #15

                                Yes, I see. But try it in the following order: EnableWindow SetForegroundWindow SetActiveWindow BringWindowToTop

                                S 2 Replies Last reply
                                0
                                • J Jochen Arndt

                                  My intention was to show you a solution that differs from your current implementation and pointing to the fact that you block the message loop. You must not call WaitForSingleObject from within your main thread to ensure that the window is repainted (e.g. when moving another window over the application window). That will solve the problem of paint corruption and might also solve your other problems. Overall I think I must shout: Don't use WaitForSingleObject from within your main GUI thread; especially with long wait times! I (like most others here) will not download a complete project and build it. Especially in this case where it must be tested with XP too.

                                  S Offline
                                  S Offline
                                  sdancer75
                                  wrote on last edited by
                                  #16

                                  Thanks for your time. Do you suggest to use WaitForMultipleObjects instead ?

                                  sdancer75

                                  J 1 Reply Last reply
                                  0
                                  • V Victor Nijegorodov

                                    Yes, I see. But try it in the following order: EnableWindow SetForegroundWindow SetActiveWindow BringWindowToTop

                                    S Offline
                                    S Offline
                                    sdancer75
                                    wrote on last edited by
                                    #17

                                    Seems to work with one exception. I get a flicker since it instantly lose its focus and then regain it back....

                                    sdancer75

                                    1 Reply Last reply
                                    0
                                    • S sdancer75

                                      Thanks for your time. Do you suggest to use WaitForMultipleObjects instead ?

                                      sdancer75

                                      J Offline
                                      J Offline
                                      Jochen Arndt
                                      wrote on last edited by
                                      #18

                                      No. That is similar (it can just wait for more events). Don't use any blocking wait (or more general: any function that may block for long intervals) from within the main GUI thread. As already suggested you might use a worker thread.

                                      S 1 Reply Last reply
                                      0
                                      • J Jochen Arndt

                                        No. That is similar (it can just wait for more events). Don't use any blocking wait (or more general: any function that may block for long intervals) from within the main GUI thread. As already suggested you might use a worker thread.

                                        S Offline
                                        S Offline
                                        sdancer75
                                        wrote on last edited by
                                        #19

                                        The worker thread does not lock the main app as long as its active. I dont want this. I just want a modal like behaviour and not floating windows all around the desktop.

                                        sdancer75

                                        J 1 Reply Last reply
                                        0
                                        • V Victor Nijegorodov

                                          Yes, I see. But try it in the following order: EnableWindow SetForegroundWindow SetActiveWindow BringWindowToTop

                                          S Offline
                                          S Offline
                                          sdancer75
                                          wrote on last edited by
                                          #20

                                          One last thing. The EnableWindow(xxxx) do the mess in my situation. If I dont use this function I have to process the paint messages from the child window. In this case I think that

                                          WaitForMultipleObjects

                                          will do the job in the XP case. Do you agree with this guess ? .... or better i will give it a try right now.

                                          sdancer75

                                          V 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