Skip to content Skip to sidebar Skip to footer

Determining When A Process Has Finalized Initialization

I'm building an IronPython module that initializes an instance of AutoCAD and I need to return 1 to the module calling it after AutoCAD has finished initializing, entered its messa

Solution 1:

A process can start processing messages almost immediately after start up. There is no requirement that the main window is displayed before this is done. This can be done to avoid being displayed as hanging, in case loading is slow.

You can either try interacting with the process after WaitForInputIdle returns — it may eventually respond even while "loading". If it doesn't work, wait for the main window to appear (using FindWindow). If the application is COM server, you try establishing COM connection.

P.S. Killing processes is not the best idea and may result in corrupted data or configuration. Try closing application properly be sending close event to its main window.

Solution 2:

In the title of your question you ask for "a process". In the text of your question you ask specifically for Autocad.

I can tell you how to do it for a process in general, not specifically for Autocad.

I had the same problem and came to the solution to use the API

GetModuleFileNameEx(HANDLE h_Process, ....)

MSDN says:

If the module list in the target process is corrupted or is not yet initialized, or if the module list changes during the function call as a result of DLLs being loaded or unloaded, GetModuleFileNameEx may fail or return incorrect information.

And in deed when you try to get the executable path of the process with this function while the process is still loading it's DLL's the function fails and GetLastError() returns ERROR_INVALID_HANDLE. This does not mean that the process handle that you pass to the function is invalid. But this is the error code you get when the process is still starting up.

I tested it with several applications. It works perfectly.

intWaitForProcess(HANDLE h_Process, int Timeout){
    for (int T=0; T<=Timeout; T+=50)
    {
       if (GetModuleFileNameEx(h_Process, NULL, ...) > 0)
           return0;

       int Err = GetLastError();
       if (Err != ERROR_INVALID_HANDLE) // = 6return Err;

       Sleep(50);
    }
    return ERROR_TIMEOUT;
}

Why does it work? What GetModuleFileNameEx() does internally is to read the memory of the process (for that you must open the process with access permission PROCESS_VM_READ). But this is not allowed while the process is in the loader lock. The loader lock is active while a process is loading DLL's.

This code is general and works for any application. It waits until the application is ready with it's basic initialization. If this is not enough for you I recommend to wait for the main window of the application to appear.

Post a Comment for "Determining When A Process Has Finalized Initialization"