【永利皇宫手机版下载】Windows音讯机制要点,hang的来头剖析

1. 问题

1. 窗口进程 
每一种窗口会有八个名称叫窗口进程的回调函数(WndProc卡塔尔(英语:State of Qatar),它包括多少个参数,分别为:窗口句柄(Window
Handle),音信ID(Message ID卡塔尔国,和多个新闻参数(wParam,
lParam卡塔尔国,当窗口收到音信时系统就能够调用此窗口进程来管理新闻。(所以叫回调函数)

当在console中调用API
ShellExecuteEx张开”test.iqy”文件时,发掘excel会hang住,console退出后excel才会响应,但平昔双击”test.iqy”是绝非难点的,有趣的是这一个意况独有在xp产生,在win7上未曾那些题目。

2 音信类型 
1卡塔尔(英语:State of Qatar) 系统定义音讯(System-Defined Messages卡塔尔(قطر‎
 
在SDK中先行定义好的音信,非客商定义的,其范围在[0x0000, 0x03ff]里面,
能够分成以下三类:
1>窗口音讯(Windows Message卡塔尔 
与窗口的在那之中运行有关,如成立窗口,绘制窗口,销毁窗口等。能够是雷同的窗口,也得以是Dialog,控件等。
如:WM_CREATE, WM_PAINT, WM_MOUSEMOVE, WM_CTLCOLOR, WM_HSCROLL…
2>命令音讯(Command Message卡塔尔(قطر‎:注意那类新闻通称为WM_COMMAND
与拍卖客商要求有关, 如单击菜单项或工具栏或控件时, 就能够产生命令新闻。
WM_COMMAND, LOWO凯雷德D(wParam卡塔尔表示菜单项,工具栏开关或控件的ID。假诺是控件,
HIWOLX570D(wParam卡塔尔(قطر‎表示控件音信类型
3> 控件公告(Notify Message卡塔尔 
控件布告音讯, 这是最灵敏的音讯格式, 其Message, wParam,
lParam分别为:WM_NOTIFY,
控件ID,指向NMHD奥迪Q3的指针。NMHDPRADO包括控件公告的内容, 能够随性所欲扩充。
2卡塔尔(قطر‎ 程序定义音讯(Application-Defined Messages卡塔尔 
客户自定义的音信, 对于其范围犹如下规定:
WM_USER: 0x0400-0x7FFF    (ex. WM_USER+10)
WM_APP(winver>4.0): 0x8000-0xBFFF (ex.WM_APP+4)
RegisterWindowMessage: 0xC000-0xFFFF

 

3 音信队列(Message Queues卡塔尔(英语:State of Qatar) 
Windows中有三种档期的顺序的音信队列
1卡塔尔(英语:State of Qatar) 系统消息队列(System Message Queue卡塔尔(英语:State of Qatar) 那是贰个系统唯大器晚成的Queue,设备驱动(mouse,
keyboard卡塔尔(قطر‎会把操作输入转造成新闻存在系统队列中,然后系统会把此新闻放到指标窗口所在的线程的音信队列(thread-specific
message queue卡塔尔国中等候管理
2卡塔尔(قطر‎ 线程消息队列(Thread-specific Message Queue卡塔尔国 每三个GUI线程都会维护这么叁个线程音讯队列。(那一个行列唯有在线程调用GDI函数时才会创建,暗许不创建卡塔尔(قطر‎。然后线程新闻队列中的新闻会被送到对应的窗口进程(WndProc卡塔尔管理.
注意:
线程音讯队列中WM_PAINT,WM_永利皇宫手机版下载 ,TIMEXC五19独有在Queue中未有别的消息的时候才会被管理,WM_PAINT音信还可能会被归总以进步效用。别的具备音讯以先进先出(FIFO)的措施被拍卖。

2. 复发步骤

4 队列音信(Queued Messages卡塔尔(英语:State of Qatar)和非队列音信(Non-Queued Messages卡塔尔国
1卡塔尔(قطر‎队列新闻(Queued Messages卡塔尔(قطر‎
 
新闻会先保存在新闻队列中,新闻循环会今后队列中取音信并散发到各窗口管理
如鼠标,键盘新闻。
2卡塔尔 非队列音讯(NonQueued Messages) 新闻会绕过系统音信队列和线程音讯队列直接发送到窗口进程被管理
如: WM_ACTIVATE, WM_SETFOCUS, WM_SETCURSOR, WM_WINDOWPOSCHANGED 
介怀: postMessage发送的音讯是队列新闻,它会把音信Post到音讯队列中;
SendMessage发送的新闻是非队列音讯, 被一贯送到窗口进度管理

复出碰到:XP sp3 / Office 2006(其余office版本应该也得以,未有测量试验)

5 PostMessage(PostThreadMessage), SendMessage 
PostMessage:把音讯放到钦命窗口所在的线程音信队列中后立即回到。
PostThreadMessage:把音信放到钦命线程的新闻队列中后立时回去。
SendMessage:直接把音讯送到窗口进度管理,管理完了才回来。

6 GetMessage, PeekMessage 
PeekMessage会即刻回到能够保存消息
GetMessage在有音讯时重返会去除新闻

1> 解压iqy_test.zip

7 TranslateMessage, TranslateAccelerator 
TranslateMessage: 把叁个virtual-key音信转形成字符音信(character
message卡塔尔,并置于当前线程的音讯队列中,消息循环下三次收取管理。
TranslateAccelerator:将赶快键对应到相应的美食指南命令。它会把WM_KEYDOWN 或
WM_SYSKEYDOWN转形成快速键表中相应的WM_COMMAND或WM_SYSCOMMAND音信,
然后把转变后的 WM_COMMAND或WM_SYSCOMMAND直接发送到窗口过程管理,
管理完后才会回来。

2> 运行http_server.py(需先安装python)

8(消息死锁( Message Deadlocks卡塔尔 
若果有线程A和B, 现在有以下下步骤
1卡塔尔国 线程A SendMessage给线程B, A等待音信在线程B中管理后回去
2卡塔尔(قطر‎ 线程B收到了线程A发来的新闻,并张开始拍片卖, 在管理进度中,B也向线程A
SendMessgae,然后等待从A重返。
因为此时, 线程A正等待从线程B重临, 不可能管理B发来的消息,
进而引致了/线程A,B相互等待, 造成死锁。八个线程也足以形成环形死锁。
能够接纳 SendNotifyMessage或SendMessageTimeout来制止现身死锁。

3> 执行”shell_execute.exe test.iqy”

9 BroadcastSystemMessage 
咱俩日常所接触到的消息都以发送给窗口的,其实,
音信的采用者能够是不可胜言的,它能够是应用程序(applications卡塔尔国,
可设置驱动(installable drivers卡塔尔(英语:State of Qatar),网络设施(network drivers卡塔尔国,
系统级设备驱动(system-level device drivers卡塔尔(英语:State of Qatar)等, 
布罗兹castSystemMessage那个API能够对以上系统组件发送音信。

shell_execute.exe的主要code:

bool shell_execute_file(wstring file_path)
{
    SHELLEXECUTEINFOW shell_exec_info = { 0 };
    shell_exec_info.cbSize = sizeof(SHELLEXECUTEINFOW);
    shell_exec_info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
    shell_exec_info.hwnd = NULL;
    shell_exec_info.lpVerb = NULL;
    shell_exec_info.lpFile = file_path.c_str();
    shell_exec_info.lpParameters = NULL;
    shell_exec_info.lpDirectory = NULL;
    shell_exec_info.nShow = SW_SHOW;
    shell_exec_info.hInstApp = NULL;
    bool ret = ShellExecuteExW(&shell_exec_info);
    printf("process handle is %p\n", shell_exec_info.hProcess);

    return ret;
}

 

3. 缘故分析

3.1 excel hang在哪里?

3.1.1 用windbg附加到excel上,输入如下命令查看主线程hang住的地点

永利皇宫手机版下载 1

能够观察Excel
hang在NtUserMessageCall(卡塔尔(قطر‎中,经过查询知,SendMessage(卡塔尔(قطر‎内部正是调用NtUserMessageCall(卡塔尔(英语:State of Qatar)来发送音讯的。

翻开参数知excel调用NtUserMessageCall(卡塔尔相通如下:

NtUserMessageCall(HWND_BROADCAST, WM_DDE_INITIATE)

表达excel给具有顶层窗口发送二个WM_DDE_INITIATE音讯,但是有窗口未有response

通过能够猜疑是由于console进程在和excel用DDE消息通讯时,console未有响应excel发送的DDE消息,招致excel
hang住

 

3.2 为了验证3.1.1的预计,用API Monitor一下ShellExecuteEx

3.2.1
依据微软的文档可见,发送DDE音信除了WM_DDE_INITIATE和WM_DDE_ACK之外用的都以PostMessage

在API Monitor中追寻一下PostMessage的调用,果然搜到一条

永利皇宫手机版下载 2

call stack显示实乃ShellExecuteEx所调用

永利皇宫手机版下载 3

消息1000为WM_DDE_EXECUTE,Post窗口句柄为0x00310172。

网站地图xml地图