HOWTO: Detect All Program TerminationsLast reviewed: May 27, 1997Article ID: Q125689 |
The information in this article applies to:
SUMMARYThe processes for detecting program terminations fall into two categories:
MORE INFORMATIONWin32 processes can use one of the Wait functions to wait for a spawned process. By using CreateProcess() to launch a Win32 process, 16-bit process, or MS-DOS-based application, you can fill in a PROCESS_INFORMATION structure. The hProcess field of this structure can be used to wait until the spawned process terminates. For example, the following code spawns a process and waits for its termination:
PROCESS_INFORMATION ProcessInfo; STARTUPINFO StartupInfo = {0}; StartupInfo.cb = sizeof(STARTUPINFO); if (CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)) { WaitForSingleObject(ProcessInfo.hProcess, INFINITE); /* Process has terminated */ ... } else { /* Process could not be started */ ... }If necessary, you can put this code into a separate thread to allow the initial thread to continue to execute. NOTE: For a discussion of how the NTVDM WOW architecture may influence waiting on 16-bit applications, please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q105676 TITLE : Starting and Terminating Windows-based ApplicationThis synchronization method is not available to 16-bit processes. Instead, they must use the TOOLHELP NotifyRegister function to register a callback function to be called when a program terminates. This method will detect the termination of 16-bit processes and MS-DOS-based applications, but not Win32 processes. The following code shows how to register a callback function with NotifyRegister():
FARPROC lpfnCallback; lpfnCallback = MakeProcInstance(NotifyRegisterCallback, ghInst); if (!NotifyRegister(NULL, (LPFNNOTIFYCALLBACK)lpfnCallback, NF_NORMAL)) { MessageBox(NULL, "NotifyRegister Failed", "Error", MB_OK); FreeProcInstance(lpfnCallback); }The next section of code demonstrates the implementation of the callback function:
BOOL FAR PASCAL __export NotifyRegisterCallback (WORD wID, DWORD dwData) { HTASK hTask; // task that called the notification callback TASKENTRY te; // Check for task exiting switch (wID) { case NFY_EXITTASK: // Obtain info about the task that is terminating hTask = GetCurrentTask(); te.dwSize = sizeof(TASKENTRY); TaskFindHandle(&te, hTask); // Check if the task that is terminating is our child task. // Also check if the hInstance of the task that is // terminating is the same as the hInstance of the task // that was WinExec'd by us earlier in the program. if (te.hTaskParent == ghtaskParent && te.hInst == ghInstChild) PostMessage(ghwnd, WM_USER+509, (WORD)te.hInst, dwData); break; default: break; } // Pass notification to other callback functions return FALSE; }The NotifyRegisterCallback() API is called by the 16-bit TOOLHELP DLL in the context of the process that is causing the event. Problems arising because of reentrancy and notification chaining makes the callback function subject to certain restrictions. For example, operations that cause TOOLHELP events cannot be done in the callback function. (See the TOOLHELP NotifyRegister function documentation in your Software Development Kit for events that cause TOOLHELP callbacks.) There is no way a 16-bit process can be notified when a Win32 process exits. However, a 16-bit process can use TaskFirst() and TaskNext() to periodically walk the task list to determine if a Win32 process is still executing. This technique also works for 16-bit processes and MS-DOS-based applications. For example, the following code shows how to check for the existence of a process:
BOOL StillExecuting(HINSTANCE hAppInstance) { TASKENTRY te = {0}; te.dwSize = sizeof(te); if (TaskFirst(&te)) do { if (te.hInstance == hAppInstance) return TRUE; // process found } while (TaskNext(&te)); // process not found return FALSE; }Refer to the TermWait sample for complete details on how to use NotifyRegister and implement a callback function. For additional information, please search in the Microsoft Knowledge Base using this word:
TERMWAIT |
Additional query words: end exit notification notify spawn terminate
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |