是否有没有taskkill
来重启资源管理器的方法?
我编写了一个程序,在其中我对注册表进行了一些更改,并且要应用这些更改,需要重新启动explorer.exe,但我不想使用taskkill
,还有其他方法可以重新启动[C0 ]?
您可以使用explorer.exe
:
重新启动管理器按以下顺序停止应用程序,并且应用程序更新后,重新启动已注册为以相反的顺序重新启动。
- GUI应用程序
- 控制台应用程序
- Windows服务Windows
- 资源管理器
[Restart Manager API(来自Microsoft)有一篇不错的文章,解释了如何使用Restart Manager API正常重启Explorer:
Sheng Jiang's blog
根本不需要重新启动资源管理器。
可能有一些Windows消息可以完成更新必要内容的技巧。例如,在//returns the process id and create time for the oldest explorer.exe
RM_UNIQUE_PROCESS GetExplorerApplication()
{
RM_UNIQUE_PROCESS result={0};
DWORD bytesReturned=0;
DWORD processIdSize=4096;
std::vector<DWORD> processIds;
processIds.resize(1024);
EnumProcesses(processIds.data(),processIdSize,&bytesReturned);
while(bytesReturned==processIdSize)
{
processIdSize+=processIdSize;
processIds.resize(processIdSize/4);
EnumProcesses(processIds.data(),processIdSize,&bytesReturned);
} std::for_each(processIds.begin(), processIds.end(), [&result] (DWORD processId) {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
FALSE, processId);
if (hProcess) {
std::wstring imageName;
imageName.resize(4096);
if(GetProcessImageFileName (hProcess,(LPWSTR)imageName.data(),4096)>0)
{
if(wcscmp(L"explorer.exe",PathFindFileName(imageName.data()))==0)
{
//this is assmuing the user is not running elevated and won't see explorer processes in other sessions
FILETIME ftCreate, ftExit, ftKernel, ftUser;
if (GetProcessTimes(hProcess, &ftCreate, &ftExit,&ftKernel, &ftUser))
{
if(result.dwProcessId==0)
{
result.dwProcessId=processId;
result.ProcessStartTime=ftCreate;
}
else if(CompareFileTime(&result.ProcessStartTime,&ftCreate)>0)
{
result.dwProcessId=processId;
result.ProcessStartTime=ftCreate;
}
}
}
}
CloseHandle(hProcess);
}
});
return result;
}
//taskbar position calculating code omitted
DWORD dwSession=0;
WCHAR szSessionKey[CCH_RM_SESSION_KEY+1] = { 0 };
DWORD dwError = RmStartSession(&dwSession, 0, szSessionKey);
if (dwError == ERROR_SUCCESS) {
RM_UNIQUE_PROCESS rgApplications[1]={GetExplorerApplication()};
dwError=RmRegisterResources(
dwSession,0,NULL,1,rgApplications,0,NULL);
DWORD dwReason;
UINT nProcInfoNeeded;
UINT nProcInfo = 10;
RM_PROCESS_INFO rgpi[10];
dwError = RmGetList(dwSession, &nProcInfoNeeded,
&nProcInfo, rgpi, &dwReason);
if(dwReason==RmRebootReasonNone)//now free to restart explorer
{
RmShutdown(dwSession,RmForceShutdown,NULL);//important, if we change the registry before shutting down explorer will override our change
//using undocumented setting structure, could break any time
//edge setting is stored at HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2!Settings
HKEY hKey={0};
DWORD result=0;
result=::RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects2"),
0, KEY_READ|KEY_WRITE, &hKey) ;
if (result== ERROR_SUCCESS)
{
std::vector<BYTE> data;
data.resize(256);
TCHAR settingValue[]= _T("Settings");
DWORD dwKeyDataType=0;
DWORD dwDataBufSize=data.size();
result=::RegQueryValueEx(hKey,settingValue, NULL, &dwKeyDataType,
(LPBYTE) data.data(), &dwDataBufSize);
while(ERROR_MORE_DATA==result)
{
data.resize(256+data.size());
dwDataBufSize=data.size();
result=::RegQueryValueEx(hKey,settingValue, NULL, &dwKeyDataType,
(LPBYTE) data.data(), &dwDataBufSize);
}
data.resize(dwDataBufSize);
if(result==ERROR_SUCCESS)
{
switch ( dwKeyDataType )
{
case REG_BINARY:
if(data.size()==40)
{
BYTE taskbarPosition=data[12];
taskbarPosition=edge;
data[12]=taskbarPosition;
RECT* taskbarRect=(RECT*)&data[24];
CopyRect (taskbarRect,&abd.rc);
result=::RegSetValueEx(hKey,settingValue,0,REG_BINARY,(LPBYTE) data.data(), dwDataBufSize);
}
break;
}
}
::RegCloseKey( hKey );
}
RmRestart (dwSession,0,NULL);
}
}
RmEndSession(dwSession);
上重新创建了通知区域图标,在RegiserWindowsMessage("TaskbarCreated")
上应用了某些设置。
或者也许可以通过除注册表写之外刷新的API访问有问题的设置。
请在重新启动之前考虑“较软”的方法。