最近开发的项目碰到一个问题,来问问大家有什么看法。
项目中一个模块的功能是,在新创建的桌面(Desktop) 顶部创建一个AppBar窗口,大概过程如下。
(一)主线程先在原桌面顶部中间创建一个AppBar对话框,然后启动另外一个线程 m_secThread:
if (!m_pDftBar->Create())
{
LOG("error: create default-appbar fail");
return FALSE;
}
Create中创建AppBar的步骤如下(省去代码细节):
(1)创建窗口:m_hAppBar = CreateWindowEx()
(2) 注册AppBar:(BOOL)SHAppBarMessage(ABM_NEW, &abd);
//启动安全桌面线程并切换桌面
m_secThread = CreateThread(NULL, 0, SecThread, hInst, 0, &m_secTid);
(二) 在SecThread 中,依次做如下几件事:
(1)创建桌面:m_hdskSec = CreateDesktop();
(2)设置新线程桌面为新创建的桌面:SetThreadDesktop(m_hdskSec)
(3)切换到新的桌面:SwitchDesktop(m_hdskSec)
(4)创建Explorer进程:CreateProcess()
(5)等待Explorer完成初始化:WaitForInputIdle(m_explorer.hProcess, INFINITE);
(6)在新的桌面的顶部中间创建一个一模一样的AppBar(过程和(一)中描述的一样)
现在问题出现在第6步。
在创建AppBar的过程中,注册AppBar 返回失败: (BOOL)SHAppBarMessage(ABM_NEW, &abd)失败;
MSDN的说明是:return FALSE if an error occurs or if the appbar is already registered.
要么就是该appbar已经注册,或是有错误发生(MSDN没说如何获得错误码以及对应的含义)
假设原因就是appbar已经被注册。
但是,本人尝试在(5)和(6)之间Sleep(500) 半秒
发现没有任何问题,这时候AppBar注册成功,即SHAppBarMessage(ABM_NEW, &abd)成功
也能按预期的显示,如果这时间改短,比如10,那将返回失败。
所以猜想,SHAppBarMessage 系列函数的执行是否依赖SHELL环境(即Explorer进程)
其实步骤(5)也是出于这个考虑添加上去的,就是等待Explorer完成初始化。可是目前看来和这个没有直接关系。
向大家请教下有什么思路,现在我就局限在和Explorer这个进程的关系上,没有什么想法。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)