http://bugs.winehq.org/show_bug.cgi?id=19095
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #2 from Anastasius Focht focht@gmx.net 2009-06-28 05:30:43 --- Hello,
well it seems you trigger a shutdown race with your AHK script code.
0009: AHK main thread 001b: target process "PE explorer" main GUI thread
The first attempt to shut down the target GUI process (translated pseudo code):
PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
--- snip ---- ... 0009: get_window_text() = 0 { text=L"PE Explorer - 30 day evaluation version" } 0009:trace:msg:PostMessageW hwnd 0x10044 msg 112 (WM_SYSCOMMAND) wp f060 lp 0 0009: get_window_info( handle=00010044 ) 0009: get_window_info() = 0 { full_handle=00010044, last_active=00010044, pid=001a, tid=001b, atom=c052, is_unicode=0 } 0009: send_message( id=001b, type=6, flags=0, win=00010044, msg=00000112, wparam=0000f060, lparam=00000000, timeout=infinite, data={} ) 001b: *wakeup* signaled=0 0009: send_message() = 0 0009: get_window_children( desktop=0000, parent=00010020, atom=0000, tid=0000, class=L"" ) 0009: get_window_children() = 0 { count=21, children={00010036,000100cc,000100ca,000100c0,000100bc,00010060,00010058,00010044,0001010a,0001003c,0001006c,0001006a,0001003a,00010038,00010034,00010030,0001002e,0001002c,0001002a,00010028,00010026} } 001b: get_message( flags=00000001, get_win=00000000, get_first=00000000, get_last=ffffffff, hw_id=00000000, wake_mask=00000000, changed_mask=00000000 ) 001b: get_message() = 0 { win=00010044, msg=00000112, wparam=0000f060, lparam=00000000, type=6, time=000045e8, active_hooks=80000000, total=0, data={} } 001b:trace:msg:peek_message got type 6 msg 112 (WM_SYSCOMMAND) hwnd 0x10044 wp f060 lp 0 001b:trace:msg:WINPROC_CallProcWtoA (hwnd=0x10044,msg=WM_CLOSE,wp=00000000,lp=00000000) ... --- snip ----
The target process main window message handler received WM_CLOSE and starts app cleanup/destruction sequence.
A short time later, another shutdown attempt is done from AHK process:
PostMessage(hwnd, WM_CLOSE, 0, 0);
--- snip --- ... 0009: get_window_text( handle=00010044 ) 0009: get_window_text() = 0 { text=L"PE Explorer - 30 day evaluation version" } ... 0009: get_window_info( handle=00010044 ) 0009: get_window_info() = 0 { full_handle=00010044, last_active=00010044, pid=001a, tid=001b, atom=c052, is_unicode=0 } 0009:trace:msg:send_inter_thread_message hwnd 0x10044 msg 10 (WM_CLOSE) wp 0 lp 0 001b: get_window_property( window=00010108, atom=0000, name=L"__wine_x11_gl_drawable" ) 001b: get_window_property() = 0 { data=00000000 } 0009: send_message( id=001b, type=5, flags=1, win=00010044, msg=00000010, wparam=00000000, lparam=00000000, timeout=+0.5000000, data={} ) 0009: send_message() = 0 ... 001b:trace:msg:peek_message got type 5 msg 10 (WM_CLOSE) hwnd 0x10044 wp 0 lp 0 001b:trace:msg:WINPROC_CallProcWtoA (hwnd=0x10044,msg=WM_CLOSE,wp=00000000,lp=00000000) 001b:trace:seh:raise_exception code=c0000005 flags=0 addr=(nil) ip=00000000 tid=001b 001b:trace:seh:raise_exception info[0]=00000000 001b:trace:seh:raise_exception info[1]=00000000 001b:trace:seh:raise_exception eax=01137954 ebx=00000000 ecx=01137950 edx=00000001 esi=010a872c edi=00000001 001b:trace:seh:raise_exception ebp=0033f0d4 esp=0033f0ac cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00210202 --- snip ---
This seems to catch the target app in midst of shutdown sequence. Some (child) windows have already been destroyed at this point.
Looking at your AHK script code:
--- snip pex.ahk --- FORCE_CLOSE("PE Explorer - 30 day evaluation version") --- snip pex.ahk ---
--- snip helper_functions --- ... ; Force a window to close. AutoHotKey comes with the 'WinClose' function, which sends WM_CLOSE and asks ; the program to close nicely. 'WinKill' is an extended version, which is supposed to send WM_CLOSE, and if it fails, ; terminates the program's process. I found it to be inconsistent, on both Windows and Wine. As a backup, the AHK FAQ ; offers a workaround, which I greatly prefer. For reference, 0x112 = WM_SYSCOMMAND, 0xF060 = SC_CLOSE. This is equivalent ; to clicking on the system menu and choosing 'Close', or roughly equivalent to 'ALT+F4'. It is much more consistent.
FORCE_CLOSE(windowname) { PostMessage, 0x112, 0xF060,,, %windowname% IfWinExist, %windowname% { WinKill, %windowname% } } --- snip helper_functions ---
Wine can't replicate exact Windows thread timing by design. I don't know if Windows magically protects the app Window shutdown sequence/handler from interleaving WM_CLOSE messages. Even if the code works for Windows it introduces nasty races which also depend on system utilization.
I suggest that you change the script code a bit. Instead of calling IfWinExist a single time directly after PostMessage, use a short loop. Call IfWinExist within that loop and if it still exists, do a bit sleep() before next iteration to give target process time to do a clean shutdown. Break when main window doesn't exist anymore. After predefined number of times also break the loop (target hangs whatever). Out of loop use WinKill() if the window still exists.
In my opinion this is WONTFIX.
Regards