Thread: Checking for a completed process/thread or simply When does a program end?

  1. #1
    Registered User Nova_Collision's Avatar
    Join Date
    Feb 2003
    Posts
    40

    Checking for a completed process/thread or simply When does a program end?

    I'm using CreateProcess() to run the JRE installer and I need to know when the installer finishes. Both GetExitCodeProcess() and GetExitCodeThread crash the program. Here's my code:

    Process Creation :
    Code:
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(pi));
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    int res = CreateProcess("c:\\j2re-1_4_2_04-windows-i586-p.exe", 0, 0, 0, 0, 0, 0, 0, &si, &pi);
    HANDLE process = pi.hProcess;
    Checking for exit: (Part of my default: option for switch in Main Window Procedure)
    Code:
    LPDWORD exitCode = NULL;
    GetExitCodeProcess(process, exitCode);
    if(exitCode != (unsigned long *)259)
    {
     CloseHandle(process);
     currentStep = 110;
    }
    When in doubt, empty your magazine - Murphy's Laws Of Combat #7

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    When a function takes a pointer to a variable, it means it takes the address of a variable. Not a pointer to nothing. It then fills in this variable.

    This is a hard rule. If a function wants a pointer to a DWORD give it the address of a DWORD. If a function wants a pointer to an OPENFILENAME struct give it the address of an OPENFILENAME struct. If a function wants a pointer to a void * (ie. a void **) give it the address of a void * variable.

    The only exception is some functions will accept the value NULL to indicate that the caller does not want the return value.

    Code:
    LPDWORD exitCode = NULL;
    GetExitCodeProcess(process, exitCode);
    When GetExitCodeProcess() dereferences exitCode what will happen?

    Code:
    // Sample implementation:
    BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpdwExitCode)
    {
         ...
    
         *lpdwExitCode = dwExitCode;
         ...
    }
    I'll leave it to you to provide a sample of the correct usage of GetExitCodeProcess().

    As a side note, this is not the best way to wait for a process to complete. The preferred method is:
    Code:
    if (WAIT_OBJECT_0 == WaitForSingleObject(hProcess, INFINITE))
    {
        // Process complete
    }
    else
    {
        // Process not complete - timeout (won't happen if timeout is INFINITE)
    }
    If you don't want to wait, as you don't in a window procedure, use a timeout of 0.

  3. #3
    Registered User Nova_Collision's Avatar
    Join Date
    Feb 2003
    Posts
    40
    Okay....I'm trying to wrap my head around that. Pointers have always been a bit tricky for me. From what I understood of what you said about GetExitCodeProcess(), I should pass it a DWORD that has been initialized to a non-null value, but that's what I did first and put it to NULL, wondering if that had something to do with it. I'm sure I'm not getting something in your explanation.

    As far as the WaitForSingleObject() method, I implemented it and it works - after a fashion. I don't need anything to happen while the program waits for the other to finish, so I have no else. Anyway, either with INFINITE or 0 set, it takes about 20 seconds for it to realize that the program has completed and then the dialog freezes. I'm not sure if the program locks up, but I can't use any controls.

    Code:
    if((process != NULL) && (currentStep == 105))
    {
     if(WAIT_OBJECT_0 == WaitForSingleObject(process, 0))
     {
      CloseHandle(process);
      currentStep = 110;
     }
    }
    The currentStep variable is what I use to track which dialog screen the user is at. 105 is my "Waiting for installer to finish" dialog, 110 is my "install finished, click next to continue" dialog.
    When in doubt, empty your magazine - Murphy's Laws Of Combat #7

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >>I should pass it a DWORD that has been initialized to a non-null value, but that's what I did first and put it to NULL, wondering if that had something to do with it.<<

    No, you should pass it the address of a DWORD.

    Code:
    DWORD dwExitCode;
    GetExitCodeProcess(hProcess, &dwExitCode);
    Note that you can use the constant STILL_ACTIVE instead of 259. The reason this method is unreliable is that the process may return 259. In that case your program would wait forever for the process to finish.

    >>Anyway, either with INFINITE or 0 set, it takes about 20 seconds for it to realize that the program has completed and then the dialog freezes. I'm not sure if the program locks up, but I can't use any controls.<<

    In a window procedure you should use zero as the timeout so that the window procedure can continue processing messages. Messages such as WM_PAINT and WM_MOUSEMOVE, etc which are sent all the time and must be processed or your program will lock up.

    It should not lock up with a timeout of zero, so I would need more information on this.

  5. #5
    Registered User Nova_Collision's Avatar
    Join Date
    Feb 2003
    Posts
    40
    I'm not sure what else you need. My process creation is still the same and the dialogs work properly. My program is an installer for a Java pogram that I've done. It's made of a series of dialogs that run from the same procedure, since each one uses the same two buttons (Next > and Cancel). What I want it to do is check for the JRE and make sure that version 1.4 or better is installed. I've got that working and then, in the event that JRE 1.4 is not installed, it uses CreateProcess to run the java installer. What I want is for my program to sit at Dialog ID # 105 (Which basically just says "Waiting for the Java install to complete...") and then jump to Dialog ID # 110 as soon as the install is done.

    Code:
    if((process != NULL) && (currentStep == 105))
    {
    	/*
    	DWORD dwExitCode;
    	GetExitCodeProcess(process, &dwExitCode);
    	if(dwExitCode != STILL_ACTIVE)
    	{
    		CloseHandle(process);
    		currentStep = 110;
    	}*/
    
    	if(WAIT_OBJECT_0 == WaitForSingleObject(process, 0))
    	{
    		CloseHandle(process);
    		currentStep = 110;
    	}
    }
    As you can see, I've tried both. The GetExitCodeProcess method doesn't crash instantly anymore, but crashes once the java installer completes (IE, dwExitCode != STILL_ACTIVE).

    The WaitForSingleObject() method seems to work, as I've said, after a fashion. Unfortunately, the window won't change to dialog 110 until I refresh it (minimize then maximize), so that makes me think that the Paint() method (or whatever it is) is being stopped. Then, one it refreshes, I cannot click on Next > or Cancel, but can click on the minimize/maximize/close buttons. So only the controls are locked. If I skip the java install step, the dialog works fine, so it's not entering an infinite loop somewhere that I've done.

    Aside from that, I dunno what else you want and I'm loathe to post the whole program as that's just irritating for you guys. Because of time constraints, I'm at my last attempts for this. My team needs an installer and while this would be great, we'll probably work something else out if I don't ge this working by Monday (Tomorrow). So don't worry about it too much.
    When in doubt, empty your magazine - Murphy's Laws Of Combat #7

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    How about posting the window procedure at least. The code that you've posted is fine. The only problem I could see is if the process variable is going out of scope. If it is declared as a local variable in the window procedure it will go out of scope when the window procedure returns.

    You can post the lot as an attachment. No one will mind, but I can't guarantee anyone will be able to find the problem.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem building Quake source
    By Silvercord in forum Game Programming
    Replies: 16
    Last Post: 07-11-2010, 09:13 AM
  2. Program Plan
    By Programmer_P in forum C++ Programming
    Replies: 0
    Last Post: 05-11-2009, 01:42 AM
  3. Another weird error
    By rwmarsh in forum Game Programming
    Replies: 4
    Last Post: 09-24-2006, 10:00 PM
  4. Problems about gcc installation
    By kevin_cat in forum Linux Programming
    Replies: 4
    Last Post: 08-09-2005, 09:05 AM
  5. Replies: 2
    Last Post: 05-10-2002, 04:16 PM