智业his系统在点击打印后需要很时间(4-15秒)左右才弹出打印机选择框。由于是第三方应用,只能在没有源码的情况下分析。
现象:云桌面登录智业系统选定病人病历或者医嘱等可打印页面,点击打印按钮后需要等待5-15秒左右才能弹出打印机选择框,完成打印后智业系统界面会假死5-15秒左右,经走访医生发现本地也有一样的现象。
问题产生的原因:通过分析发现在点击打印后和完成打印后智业系统会两次同步模式发送广播消息,伪代码(Sendmessagetimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0, L”打印机名”, 0, 1000, 0)).
即向所有顶层窗口发送设备模式变更的消息,超时时间为1s,由于广播消息的机制是所有顶层窗口处理完成消息或者都超时之后才会返回给发送方,因此在顶层窗口较多的情况下会导致超时时间成倍增加,如果有10个窗口,最坏的情况就是等待10秒。广播消息的机制可参考:https://learn.microsoft.com/zh-tw/previous-versions/aa925929(v=msdn.10)
具体代码在:zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xc6b4
建议修改方案:
一 将超时时间改小(windbg调试时将时间设置为8ms)点击打印反应迅速
二 将同步发送消息改为异步。
详细的调试过程如下:
Breakpoint 3 hit
zclientu!CLayer::GetOperManageCount+0x162ed1:
017b99ca 6a00 push 0
0:000:x86> g
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
(2078.2080): C++ EH exception - code e06d7363 (first chance)
Breakpoint 5 hit
zclientu!CLayer::GetOperManageCount+0x162ef0:
017b99e9 85c0 test eax,eax
0:000:x86> u 017b99ca l10
zclientu!CLayer::GetOperManageCount+0x162ed1:
017b99ca 6a00 push 0
017b99cc 8d8c2440010000 lea ecx,[esp+140h]
017b99d3 ff15eccb2802 call dword ptr [zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xc11c (0228cbec)]
017b99d9 50 push eax
017b99da 6a00 push 0
017b99dc 6a1b push 1Bh
017b99de 68ffff0000 push 0FFFFh
017b99e3 ff1584d12802 call dword ptr [zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xc6b4 (0228d184)]
017b99e9 85c0 test eax,eax
017b99eb 8b1d20c02802 mov ebx,dword ptr [zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xb550 (0228c020)]
017b99f1 751a jne zclientu!CLayer::GetOperManageCount+0x162f14 (017b9a0d)
017b99f3 ff15f8bf2802 call dword ptr [zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xb528 (0228bff8)]
017b99f9 56 push esi
017b99fa ffd3 call ebx
017b99fc 8b442414 mov eax,dword ptr [esp+14h]
017b9a00 50 push eax
0:000:x86> dd 0228d184
0228d184 75e497e1 75e5b7bf 75e46c4c 75e50efe
0228d194 75e52353 75e513c9 75e50e63 75e4d1ef
0228d1a4 75e51389 75e513a9 75e49f94 75e49a67
0228d1b4 77c226dd 75e50e43 75e48a39 75e47d3f
0228d1c4 75e4b195 75e4fc20 75e478f2 75e49ecd
0228d1d4 75ea00ef 75e536d1 75e54262 75e5266d
0228d1e4 75e5597d 75e5580c 75e50c05 75e528cc
0228d1f4 75e54299 75e92763 75e4b250 75e5396c
0:000:x86> u 75e497e1
USER32!SendMessageTimeoutW:
75e497e1 8bff mov edi,edi
75e497e3 55 push ebp
75e497e4 8bec mov ebp,esp
75e497e6 6a00 push 0
75e497e8 ff7520 push dword ptr [ebp+20h]
75e497eb ff751c push dword ptr [ebp+1Ch]
75e497ee ff7518 push dword ptr [ebp+18h]
75e497f1 ff7514 push dword ptr [ebp+14h]
Breakpoint 3 hit
zclientu!CLayer::GetOperManageCount+0x162ed1:
017b99ca 6a00 push 0
0:000:x86> p
zclientu!CLayer::GetOperManageCount+0x162ed3:
017b99cc 8d8c2440010000 lea ecx,[esp+140h]
0:000:x86> p
zclientu!CLayer::GetOperManageCount+0x162eda:
017b99d3 ff15eccb2802 call dword ptr [zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xc11c (0228cbec)] ds:002b:0228cbec={MSVCP80!std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >::data (67407e10)}
0:000:x86> p
zclientu!CLayer::GetOperManageCount+0x162ee0:
017b99d9 50 push eax
0:000:x86> p
zclientu!CLayer::GetOperManageCount+0x162ee1:
017b99da 6a00 push 0
0:000:x86> p
zclientu!CLayer::GetOperManageCount+0x162ee3:
017b99dc 6a1b push 1Bh
0:000:x86> p
zclientu!CLayer::GetOperManageCount+0x162ee5:
017b99de 68ffff0000 push 0FFFFh
0:000:x86> p
zclientu!CLayer::GetOperManageCount+0x162eea:
017b99e3 ff1584d12802 call dword ptr [zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xc6b4 (0228d184)] ds:002b:0228d184={USER32!SendMessageTimeoutW (75e497e1)}
zclientu!CLayer::GetOperManageCount+0x162eea:
017b99e3 ff1584d12802 call dword ptr [zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xc6b4 (0228d184)] ds:002b:0228d184={USER32!SendMessageTimeoutW (75e497e1)}
0:000:x86> r
eax=09b4afa0 ebx=764f51d6 ecx=0018e940 edx=00000000 esi=1d023408 edi=00000000
eip=017b99e3 esp=0018e7f0 ebp=0018e9a8 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216
zclientu!CLayer::GetOperManageCount+0x162eea:
017b99e3 ff1584d12802 call dword ptr [zclientu!CEmrBaseTpCreator::m_mapTimePoint+0xc6b4 (0228d184)] ds:002b:0228d184={USER32!SendMessageTimeoutW (75e497e1)}
0:000:x86> dd 09b4afa0
09b4afa0 00500045 004f0053 0020004e 0031004d
09b4afb0 00300030 00530020 00720065 00650069
09b4afc0 00000073 00740068 00000000 00000000
09b4afd0 61aae064 80000031 011d001e 0046011c
09b4afe0 000d000b 010b0119 0132010c 00140107
09b4aff0 001f001b 00050001 01020008 000c0042
09b4b000 01000103 00000034 61aae39f 80000034
09b4b010 057e0025 00650073 120bb1a8 057ecd70
0:000:x86> dw 09b4afa0
09b4afa0 0045 0050 0053 004f 004e 0020 004d 0031
09b4afb0 0030 0030 0020 0053 0065 0072 0069 0065
09b4afc0 0073 0000 0068 0074 0000 0000 0000 0000
09b4afd0 e064 61aa 0031 8000 001e 011d 011c 0046
09b4afe0 000b 000d 0119 010b 010c 0132 0107 0014
09b4aff0 001b 001f 0001 0005 0008 0102 0042 000c
09b4b000 0103 0100 0034 0000 e39f 61aa 0034 8000
09b4b010 0025 057e 0073 0065 b1a8 120b cd70 057e
0:000:x86> du 09b4afa0
09b4afa0 "EPSON M100 Series"
0:099> lmvm zclientu
Browse full module list
start end module name
00000000`01640000 00000000`023a5000 zclientu (export symbols) zclientu.dll
Loaded symbol image file: zclientu.dll
Image path: zclientu.dll
Image name: zclientu.dll
Browse all global symbols functions data
Timestamp: Fri May 6 12:36:53 2022 (6274A5E5)
CheckSum: 00D58786
ImageSize: 00D65000
File version: 3.6.27.0
Product version: 3.6.27.0
File flags: 0 (Mask 17)
File OS: 4 Unknown Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0804.04b0
CompanyName: 厦门智业软件工程有限公司
InternalName: zclient.dll
OriginalFilename: zclient.dll
ProductVersion: 3,6,27,0
FileVersion: 3,6,27,0
FileDescription: 客户端公用模块
LegalTrademarks: zemr
Comments: http://www.zysoft.com.cn