Is there a way to restart explorer without taskkill
?
I write a program, in it I make some changes in registry, and to apply these changes it needs to restart explorer.exe, but I don't want to use taskkill
, is there any other way to restart explorer.exe
?
You can use the Restart Manager API :
The Restart Manager stops applications in the following order, and after the applications have been updated, restarts applications that have been registered for restart in the reverse order.
- GUI applications
- Console applications
- Windows services Windows
- explorer
Sheng Jiang's blog (from Microsoft) has a nice article explaining how to restart Explorer gracefully using the Restart Manager API:
//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);
It could be not necessary to restart explorer at all.
There may be some Windows message that does the trick of updating necessary stuff. For example notification area icons are recreated on RegiserWindowsMessage("TaskbarCreated")
and some of settings apply on WM_SETTINGCHANGE
.
Or maybe the setting in question is accessible via API that does refresh in addition to registry write.
Consider "softer" approaches before resorting to restart.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.