问题
在批处理的某个部分(有点像,见额外信息)中,我需要重新启动资源管理器,所以我使用了一种经过验证的方法:
taskkill /f /im explorer.exe >nul
explorer.exe
然后发生了这个
explorer.exe
被成功终止explorer.exe
启动(见Image 2),但只打开一个资源管理器窗口,该窗口一直保持打开状态(见Image 1)
此时我只能通过从任务管理器启动新任务来正确重启资源管理器,因为我认为 Win + R
是资源管理器的一部分。
额外信息
现在,我说“有点”是因为我正在从一个自解压SFX存档中运行批处理文件,该存档是使用WinRAR创建的。因此,在执行时,存档的内容被提取到 %temp%
,并且会在成功提取后运行用户定义的文件(通常是一个启动程序,在本例中是我的批处理文件)。
到目前为止,我已经得出以下结论:
explorer.exe
肯定被完全终止。- 批处理文件肯定被正确调用和执行,因为它运行并且脚本中的其他所有内容都按设计工作,除了启动
explorer.exe
的那一行。 - 重新启动资源管理器的命令没有“时机不对”之类的问题,因为我已经尝试过延迟。
- 当从存档中手动提取批处理文件时,该批处理文件完美无缺,因此它不是与压缩或提取过程有关的问题。
- 即使使用像
start explorer.exe | cmd.exe
这样的命令,资源管理器也不能正确重启,因此这绝对不是与.bat
文件有关的问题。
我可以确认它在Windows XP和Windows 7 x86上运行正常,但在Windows 7 x64上(我的系统)不正常。
状态
目前,我怀疑WinRAR,因为我已经证明了代码本身是有效的。因此,我使用不同版本的WinRAR创建自解压SFX。到目前为止,我尝试了以下版本:
- 4.11 x86
- 4.11 x64
- 4.20b3 x86
- 4.20b3 x64
每次都得到相同的结果。
我昨天向dev@rarlab.com提交了一个错误报告,今天早上收到了Eugene Roshal本人的回复
你好, SFX 模块使用 ShellExecuteEx 启动设置应用程序。 通常它工作得很好。我不知道资源管理器为什么要切换到窗口模式。 现在我建立了一个小的独立程序
#include <windows.h>
void main()
{
SHELLEXECUTEINFO si;
memset(&si,0,sizeof(si));
si.cbSize=sizeof(si);
si.lpFile="test.bat";
si.nShow=SW_SHOWNORMAL;
ShellExecuteEx(&si);
}
这个程序运行了一个名为test.bat的批处理文件,其内容与您样例中的相同。该程序显示的行为与WinRAR SFX完全一致,因此启动了一个窗口中的资源管理器。
今天早上收到了第二封电子邮件:
抱歉,现在没有建议。我用CreateProcess替换了ShellExecuteEx。
#include <windows.h>
void main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
CreateProcess(NULL,"test.bat",NULL,NULL,TRUE,0,NULL,NULL,&si,&pi);
}
但结果是一样的。我尝试使用其他SW_标志,如SW_SHOWDEFAULT或SW_RESTORE,并将ShellExecuteEx中的lpVerb设置为“open”和“explore”,但这并没有帮助。目前我不理解窗口模式与桌面模式背后的逻辑。我意识到前景不妙,但我希望对某人有所帮助。 证明/证据 如果有人需要,可以链接到演示此内容的SFX归档文件: https://dl.dropbox.com/u/27573003/Social%20Distribution/restart-explorer.exe
![image 1](https://istack.dev59.com/ART4Z.webp)
![image 2](https://istack.dev59.com/HE41j.webp)
VMwareTray.exe
所示),但这并不是由于虚拟机引起的冲突。我已在自己的主机系统上测试了完全相同的文件(该系统与操作系统相同),并获得了相同的结果。
更新
当在完全不同的项目中使用REG ADD
时,我遇到了类似的“在SFX归档文件之外可以正常工作,但在其中不能正常工作”的问题。我只是认为SFX归档文件不会与批处理文件协作。