Update of /cvsroot/boost/boost/tools/jam/src
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv20060

Modified Files:
        execnt.c 
Log Message:
Improve auto-closing of dialog boxes.

  - Don't close boxes owned by 'explorer.exe'.
  - Close dialog parented by csrss.exe ("Unable to locate component/dll")
  - Various cleanups

Patch from Bronek Kozicki.


Index: execnt.c
===================================================================
RCS file: /cvsroot/boost/boost/tools/jam/src/execnt.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- execnt.c    7 Jun 2006 02:16:58 -0000       1.26
+++ execnt.c    15 Jul 2006 05:54:35 -0000      1.27
@@ -1002,6 +1002,8 @@
 {
     HANDLE process_snapshot_h = INVALID_HANDLE_VALUE;
 
+    if (!child)
+        return 0;
     if (parent == child)
         return 1;
 
@@ -1016,8 +1018,37 @@
             ok == TRUE; 
             ok = Process32Next(process_snapshot_h, &pinfo) )
         {
-            if (pinfo.th32ProcessID == child && pinfo.th32ParentProcessID)
+            if (pinfo.th32ProcessID == child)
+            {
+                CloseHandle(process_snapshot_h);
+                if (!stricmp(pinfo.szExeFile, "explorer.exe"))
+                {
+                    /* explorer.exe is orphaned and process_id of its parent 
may
+                    accidentally match process_id of process we are after. We 
must not
+                    close dialog boxes displayed by children of explorer.exe 
even 
+                    though (thanks to its parent process id) it might appear 
to be 
+                    our child. This is not very reliable - there might be more 
+                    orphaned processes or shell might be something else than 
+                    explorer.exe, but this is most common and important 
scenario */
+                    return 0; 
+                }
+                if (!stricmp(pinfo.szExeFile, "csrss.exe"))
+                {
+                    /* csrss.exe may display message box like following:
+                        xyz.exe - Unable To Locate Component
+                        This application has failed to start because 
boost_foo-bar.dll 
+                        was not found. Re-installing the application may fix 
the problem
+                    This actually happens when starting test process that 
depends on 
+                    dynamic library which failed to build. We want to 
automatically 
+                    close these message boxes even though csrss.exe is not our 
+                    child process. We may depend on the fact that (in all 
current 
+                    versions of Windows) csrss.exe is indirectly child of 
System which 
+                    always has process id == 4 */
+                    if (is_parent_child(4, pinfo.th32ParentProcessID))
+                        return 1;
+                }
                 return is_parent_child(parent, pinfo.th32ParentProcessID);
+            }
         }
 
         CloseHandle(process_snapshot_h);
@@ -1026,28 +1057,44 @@
     return 0;
 }
 
-int related(HANDLE h, DWORD p)
+int related(DWORD d, DWORD p)
 {
-    return is_parent_child(get_process_id(h), p);
+    return is_parent_child(d, p);
 }
 
+typedef struct PROCESS_HANDLE_ID {HANDLE h; DWORD pid;} PROCESS_HANDLE_ID;
+
 BOOL CALLBACK window_enum(HWND hwnd, LPARAM lParam)
 {
-    char buf[10] = {0};
-    HANDLE h = *((HANDLE*) (lParam));
+    char buf[7] = {0};
+    PROCESS_HANDLE_ID p = *((PROCESS_HANDLE_ID*) (lParam));
     DWORD pid = 0;
+    DWORD tid = 0;
 
-    if (!GetClassNameA(hwnd, buf, 10))
-        return TRUE; // failed to read class name
+    if (!IsWindowVisible(hwnd))
+        return TRUE;
+
+    if (!GetClassNameA(hwnd, buf, 7))
+        return TRUE; /* failed to read class name; presume it's not a dialog */
 
     if (strcmp(buf, "#32770"))
-        return TRUE; // not a dialog
+        return TRUE; /* not a dialog */
 
-    GetWindowThreadProcessId(hwnd, &pid);
-    if (related(h, pid))
+    tid = GetWindowThreadProcessId(hwnd, &pid);
+    if (tid && related(p.pid, pid))
     {
-        PostMessage(hwnd, WM_QUIT, 0, 0);
-        // just one window at a time
+        /* ask really nice */
+        PostMessageA(hwnd, WM_CLOSE, 0, 0);
+        /* now wait and see if it worked. If not, insist */
+        if (WaitForSingleObject(p.h, 200) == WAIT_TIMEOUT)
+        {
+            PostThreadMessageA(tid, WM_QUIT, 0, 0);
+            if (WaitForSingleObject(p.h, 500) == WAIT_TIMEOUT)
+            {
+                PostThreadMessageA(tid, WM_QUIT, 0, 0);
+                WaitForSingleObject(p.h, 500);
+            }
+        }
         return FALSE;
     }
 
@@ -1056,7 +1103,13 @@
 
 void close_alert(HANDLE process)
 {
-    EnumWindows(&window_enum, (LPARAM) &process);
+    DWORD pid = get_process_id(process);
+    /* If process already exited or we just cannot get its process id, do not 
go any further */
+    if (pid)
+    {
+        PROCESS_HANDLE_ID p = {process, pid};
+        EnumWindows(&window_enum, (LPARAM) &p);
+    }
 }
 
 static int
@@ -1094,9 +1147,10 @@
     
     if ( globs.timeout > 0 )
     {
+        unsigned int alert_wait = 1;
         /* with a timeout we wait for a finish or a timeout, we check every 
second
          to see if something timed out */
-        for (waitcode = WAIT_TIMEOUT; waitcode == WAIT_TIMEOUT;)
+        for (waitcode = WAIT_TIMEOUT; waitcode == WAIT_TIMEOUT; ++alert_wait)
         {
             waitcode = WaitForMultipleObjects( num_active, active_handles, 
FALSE, 1*1000 /* 1 second */ );
             if ( waitcode == WAIT_TIMEOUT )
@@ -1105,10 +1159,15 @@
                 for ( i = 0; i < num_active; ++i )
                 {
                     double t = running_time(active_handles[i]);
+
+                    /* periodically (each 5 secs) review and close alert 
dialogs hanging around */
+                    if ((alert_wait % ((unsigned int) 5)) == 0)
+                        close_alert(active_handles[i]);
+
                     if ( t > (double)globs.timeout )
                     {
                         /* the job may have left an alert dialog around,
-                         try and get rid of it before killing */
+                        try and get rid of it before killing */
                         close_alert(active_handles[i]);
                         /* we have a "runaway" job, kill it */
                         kill_all(0,active_handles[i]);



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs

Reply via email to