简体   繁体   中英

How to restart explorer without taskkill

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM