Как перезапустить проводник без тасккила - PullRequest
0 голосов
/ 26 апреля 2020

Есть ли способ перезапустить проводник без taskkill?

Я пишу программу, в ней я делаю некоторые изменения в реестре, и чтобы применить эти изменения, он должен перезапустить explorer.exe, но я не хотите использовать taskkill, есть ли другой способ перезапустить explorer.exe?

Ответы [ 3 ]

3 голосов
/ 26 апреля 2020

Вы можете использовать API менеджера перезапуска :

Менеджер перезапуска останавливает приложения в следующем порядке, а после обновления приложений перезапускает зарегистрированные приложения. для перезапуска в обратном порядке.

  • GUI приложения
  • Консольные приложения
  • Windows службы Windows
  • проводник
1 голос
/ 26 апреля 2020

В блоге Шен Цзяна (от Microsoft) есть хорошая статья, объясняющая, как изящно перезапустить Explorer, используя API Restart Manager:

//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);
0 голосов
/ 27 апреля 2020

Может быть, вообще не нужно перезапускать проводник.

Может быть какое-то сообщение Windows, которое делает трюк с обновлением необходимых вещей. Например, значки области уведомлений воссоздаются на RegiserWindowsMessage("TaskbarCreated"), а некоторые настройки применяются на WM_SETTINGCHANGE.

. Или, возможно, данный параметр доступен через API, который ссылается на sh в дополнение к записи в реестре.

Подумайте о «более мягких» подходах, прежде чем прибегать к перезапуску.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...