none
CreateProcess starting 16-bit Windows program problem RRS feed

  • Question

  • I am calling CreateProcess on a 16-bit Windows program, followed by WaitForSingleObject on the process ID with a timeout value. The 16-bit Windows program shows up in the Task Manager but never shows its initial screen until after the timeout occurs and I put up a MessageBox in my parent process asking the user if I should continue waiting for the child process to finish executing.

    If I double-click the 16-bit Windows program from Explorer the program puts out its initial screen immediately.

    Does anybody have any idea what I have to do, without putting up a MessagBox in the parent process, to get the 16-bit Windows program to execute and put out its initial screen immediately.

    Tuesday, July 4, 2006 12:31 PM

Answers

  • This appears to be a common problem with InstallShield.  Refer to these links for details.  Judging from your experience, I'd say that setup.exe is trying to SendMessage() to the parent process (your program) but hangs because you are not pumping messages, you're stalled in WaitForSingleObject().

    Tuesday, July 4, 2006 3:35 PM
    Moderator

All replies

  • Your problem is difficult to reproduce. Maybe you should show us the CreateProcess fragment? In which Operating System the problem occurs?

    Tuesday, July 4, 2006 1:19 PM
  • The problem is occurring in Win2k SP4. The following function is calling the CreateProcess. The name is the process name, cmdline is the process command line, error is where a last error string will be returned. The function returns the process exit code.

    In the actual problem case I am passing the path to setup.exe as the process name and an empty string as the command line.

    The problem only occurs calling a certain Win16 process, which is an old Installshield setup.exe program. All other processes being called by the below code work properly.

    At "Point 1" I can see the setup.exe in the Task Manager task list but there is no initial screen for the setup.exe program. At "Point 2" I am waiting for setup.exe to finish. It has not even put out its initial screen yet and I return with a WAIT_TIMEOUT. At "Point 3", as soon as I put out a MessageBox for the end user, the setup.exe comes to life and triggers its first screen.

    Needless to say I want the setup.exe to trigger its first screen immediately, as it does when I start setup.exe immediately from Explorer.

    ----------------------------------------------------------------------------------------------

    DWORD ExecuteProcess(const std::string & name,const std::string & cmdline,std::string & error)

      {
     
      error = "";
      PROCESS_INFORMATION pi;
      STARTUPINFO sui;
      char * sd(0);
     
      if (cmdline.length())
        {
        sd = std::strdup(cmdline.c_str());
        }
       
      std::size_t sz(sizeof(sui));
     
      std::fill_n(reinterpret_cast<char *>(&sui),sz,0);
      sui.cb = static_cast<DWORD>(sz);
      DWORD ret(0);
      BOOL cret;
     
      if (sd)
        {
        cret = ::CreateProcess(name.c_str(),sd,0,0,FALSE,0,0,0,&sui,&pi);
        }
      else
        {
        cret = ::CreateProcess(name.c_str(),0,0,0,FALSE,0,0,0,&sui,&pi);
        }
     
      if (cret == TRUE) // Point 1
        {
        CloseHandle(pi.hThread);
       
        int mins(0);
        bool completed(false);
         
        while (true)
          {
          if (WaitForSingleObject(pi.hProcess,60000) == WAIT_TIMEOUT) // Point 2
            {
            ++mins;
           
            std::ostringstream oss;
           
            oss << "The process \'" << name
                << "\' has not completed in " << mins << " minutes. "
                   "Do you want the program to wait for the process to complete ?";
                  
            int res(::MessageBox(0,oss.str().c_str(),"Process Running",MB_YESNO)); // Point 3
           
            if (res != IDYES)
              {
              break;
              }
            }
          else 
            {
            completed = true;
            break;
            }
          }
        if (completed)
          {
       
          BOOL excr(GetExitCodeProcess(pi.hProcess,&ret));
       
          if (excr == FALSE)
            {
            error = GetLastErrorString(); // Separate function not listed here for getting the last error string into a string
            }
          }
        else 
          {
          error = "The program did not finish running.";
          }
        }
      else
        {
        error = GetLastErrorString(); // Separate function not listed here for getting the last error string into a string
        }
       
      if (sd)
        {
        free(sd);
        }
      return ret;
     
      }

    Tuesday, July 4, 2006 2:53 PM
  • This appears to be a common problem with InstallShield.  Refer to these links for details.  Judging from your experience, I'd say that setup.exe is trying to SendMessage() to the parent process (your program) but hangs because you are not pumping messages, you're stalled in WaitForSingleObject().

    Tuesday, July 4, 2006 3:35 PM
    Moderator
  • Thanks for the pointer to the Installshield problems. I found this post,  http://groups.google.com/group/comp.lang.pascal.delphi.misc/browse_thread/thread/d2ca0027abd25880/c708c090445206d4?lnk=st&q=%2Bcreateprocess+%2Binstallshield+%2Bsetup.exe&rnum=15&hl=en#c708c090445206d4 ,and the code fragment specified there under "My working code follows below..." solved my problem.
    Tuesday, July 4, 2006 5:54 PM