ShellExecuteEX展开iqy文件引致excel hang的原因分析

图片 1

try
{
fs = new StreamReader(new FileStream(path, FileMode.Open,
FileAccess.Read),
Encoding.GetEncoding(“gb2312”));//符合规律读取文件,要是被excel程序独自占领的话,那个时候会抛出非常
}
catch(Exception e)
{
//抛出分外后,那么就能够拷贝此文件到不经常文件夹下生成的几个随便文件中,然后读取此有的时候文件就能够
string tempFile = Path.GetTempPath() + Path.GetRandomFileName();
File.Copy(path, tempFile);
fs = new StreamReader(new FileStream(tempFile, FileMode.Open,
FileAccess.Read), Encoding.GetEncoding(“gb2312”));
}

 

 

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

由此能够疑心是由于console进度在和excel用DDE音讯通讯时,console未有响应excel发送的DDE新闻,招致excel
hang住

3.3 总结

4> ShellExecuteEx推行实现,但并不destroy “WorkerW”窗口

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;
}

介意到下三个API GetWindowThreadProcessId ( 0x00310172 , 0x0012fb70
),适逢其时是获得那几个窗口的pid和tid,查看下参数窗口:

5. 为啥win7上不会有这么的难题

shell_execute.exe的主要code:

查看一下buff的地址:

图片 2

图片 3

3> Post WM_DDE_EXECUTE给excel,告知张开test.iqy的一声令下

表达excel给持有顶层窗口发送一个WM_DDE_INITIATE新闻,可是有窗口未有response

图片 4

call stack展现实乃ShellExecuteEx所调用

无只有偶就是展开test.iqy的吩咐,表达ShellExecuteEx正是先创制了excel的经过,然后发送test.iqy的公文命令给excel打开。

1. 问题

能够见到Excel
hang在NtUserMessageCall()中,经过查询知,SendMessage()内部正是调用NtUserMessageCall()来发送音讯的。

图片 5

其意气风发窗口所属的经过PID =
0xc54,恰巧是excel的历程,表达ShellExecuteEx确实发送了DDE音信给excel,并且可执发送的消息的thread就是主线程

5>
excel收到WM_DDE_EXECUTE音信后会广播WM_DDE_INITIATE音信,”WorkerW”窗口所在的console进度由于未有概念新闻管理函数,ShellExecuteEx定义的”WorkerW”窗口音讯管理函数得不到CPU实践机遇,引致不会response该新闻,进而以致excel
hang住

3.1 excel hang在哪里?

 

图片 6

2> 运行http_server.py(需先安装python卡塔尔国

https://msdn.microsoft.com/en-us/library/windows/desktop/ff468829(v=vs.85).aspx

 

图片 7

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

依照DDE的音信参数,可以看到wParam正是发送音信的窗口,其句柄为2425190 =
0x250166,反向查询知那是ShellExecuteEx创设的”WorkerW”窗口

3. 缘故深入分析

5.1 在API Monitor中看下PostMessageW

图片 8

 

因为双击展开实际是用explorer.exe打开,而explorer.exe是有窗口的,能够不奇怪的收四处理WM_DDE_INITIATE消息

当在console中调用API
ShellExecuteEx张开”test.iqy”文件时,开采excel会hang住,console退出后excel才会响应,但直接双击”test.iqy”是还没难题的,有趣的是其黄金年代情景只有在xp产生,在win7上一贯不那些难点。

小心到win7下PostMessageW是用的线程2调用的,搜一下线程制造API
CreateThread

图片 9

3.2 为了验证3.1.1的估算,用API Monitor一下ShellExecuteEx

4. 为何双击张开excel不会hang住

能够是ShellExecuteEx内部创制的线程,所以win7上ShellExecuteEx创设了叁个线程特地用来拍卖和excel的DDE新闻通讯,那样就能够健康的收随地理excel发过来的WM_DDE_INITIATE消息了

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

 

图片 10

翻开参数知excel调用NtUserMessageCall()形似如下:

 

1> ShellExecuteEx展开test.iqy的时先创制excel进度

2> 然后创设多少个”WorkerW”的窗口用于DDE通讯

2. 复出步骤

NtUserMessageCall(HWND_BROADCAST, WM_DDE_INITIATE)

3.2.2 为了验证3.2.1的下结论,在PostMessageW上下断点追踪一下

复出景况:XP sp3 / Office 二零零六(别的office版本应该也能够,未有测量试验卡塔 尔(阿拉伯语:قطر‎

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

恍如,大家能够创造叁个带窗口的主次,运行后将其挂起,这个时候,纵然直接双击展开test.iqy也会hang住。

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

https://files.cnblogs.com/files/organic/iqy_test.zip

1> 解压iqy_test.zip

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图