1
0
mirror of https://github.com/valinet/ExplorerPatcher.git synced 2024-11-23 23:21:08 +01:00

File Explorer is restarted using Windows Restart Manager

This commit is contained in:
Valentin Radu 2021-10-25 05:42:03 +03:00
parent 91cb5c5c07
commit 0210935459
3 changed files with 173 additions and 35 deletions

View File

@ -510,30 +510,14 @@ static BOOL GUI_Build(HDC hDC, HWND hwnd, POINT pt)
if (p) *p = 0;
if (!strncmp(line + 1, "restart", 7))
{
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS,
0
);
if (Process32First(hSnapshot, &pe32) == TRUE)
if (FindWindowW(L"Shell_TrayWnd", NULL))
{
do
{
if (!wcscmp(pe32.szExeFile, TEXT("sihost.exe")))
{
HANDLE hSihost = OpenProcess(
PROCESS_TERMINATE,
FALSE,
pe32.th32ProcessID
);
TerminateProcess(hSihost, 0);
CloseHandle(hSihost);
return TRUE;
}
} while (Process32Next(hSnapshot, &pe32) == TRUE);
ZZRestartExplorer();
}
else
{
StartExplorer();
}
CloseHandle(hSnapshot);
}
else if (!strncmp(line + 1, "reset", 5))
{

View File

@ -99,18 +99,6 @@ const IActivationFactoryAA XamlExtensionsFactory = {
};
#pragma endregion
int FileExistsW(wchar_t* file)
{
WIN32_FIND_DATAW FindFileData;
HANDLE handle = FindFirstFileW(file, &FindFileData);
int found = handle != INVALID_HANDLE_VALUE;
if (found)
{
FindClose(handle);
}
return found;
}
void printf_guid(GUID guid)
{
printf("Guid = {%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}\n",
@ -276,6 +264,12 @@ __declspec(dllexport) CALLBACK ZZLaunchExplorerDelayed(HWND hWnd, HINSTANCE hIns
ZZLaunchExplorer(hWnd, hInstance, lpszCmdLine, nCmdShow);
}
__declspec(dllexport) CALLBACK ZZRestartExplorer(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow)
{
BeginExplorerRestart();
FinishExplorerRestart();
}
POINT GetDefaultWinXPosition(BOOL bUseRcWork, BOOL* lpBottom, BOOL* lpRight, BOOL bAdjust)
{
if (lpBottom) *lpBottom = FALSE;

View File

@ -10,6 +10,8 @@
#include <aclapi.h>
#include <sddl.h>
#include <Shlobj_core.h>
#include <restartmanager.h>
#pragma comment(lib, "Rstrtmgr.lib")
#define _LIBVALINET_INCLUDE_UNIVERSAL
#include <valinet/universal/toast/toast.h>
@ -75,7 +77,17 @@ typedef struct _IActivationFactoryAA
extern const IActivationFactoryAA XamlExtensionsFactory;
#pragma endregion
int FileExistsW(wchar_t* file);
inline int FileExistsW(wchar_t* file)
{
WIN32_FIND_DATAW FindFileData;
HANDLE handle = FindFirstFileW(file, &FindFileData);
int found = handle != INVALID_HANDLE_VALUE;
if (found)
{
FindClose(handle);
}
return found;
}
// https://stackoverflow.com/questions/1672677/print-a-guid-variable
void printf_guid(GUID guid);
@ -258,4 +270,152 @@ Cleanup:
return fIsRunAsAdmin;
}
inline BOOL IsDesktopWindowAlreadyPresent()
{
return (FindWindowExW(NULL, NULL, L"Progman", NULL) || FindWindowExW(NULL, NULL, L"Proxy Desktop", NULL));
}
// https://jiangsheng.net/2013/01/22/how-to-restart-windows-explorer-programmatically-using-restart-manager/
inline RM_UNIQUE_PROCESS GetExplorerApplication()
{
HWND hwnd = FindWindow(L"Shell_TrayWnd", NULL);
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
RM_UNIQUE_PROCESS out = { 0, { -1, -1 } };
DWORD bytesReturned;
WCHAR imageName[MAX_PATH]; // process image name buffer
DWORD processIds[2048]; // max 2048 processes (more than enough)
// enumerate all running processes (usually around 60-70)
EnumProcesses(processIds, sizeof(processIds), &bytesReturned);
int count = bytesReturned / sizeof(DWORD); // number of processIds returned
for (int i = 0; i < count; ++i)
{
DWORD processId = processIds[i];
HANDLE hProc;
if (processId == pid && (hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId)))
{
GetProcessImageFileNameW(hProc, imageName, MAX_PATH);
FILETIME ftStart, ftExit, ftKernel, ftUser;
GetProcessTimes(hProc, &ftStart, &ftExit, &ftKernel, &ftUser);
if (ftStart.dwLowDateTime < out.ProcessStartTime.dwLowDateTime)
{
out.dwProcessId = processId;
out.ProcessStartTime = ftStart;
}
CloseHandle(hProc);
}
}
return out; // return count in pResults
}
static DWORD RmSession = -1;
static wchar_t RmSessionKey[CCH_RM_SESSION_KEY + 1];
// shuts down the explorer and is ready for explorer restart
inline void BeginExplorerRestart()
{
if (RmStartSession(&RmSession, 0, RmSessionKey) == ERROR_SUCCESS)
{
RM_UNIQUE_PROCESS rgApplications[] = { GetExplorerApplication() };
RmRegisterResources(RmSession, 0, 0, 1, rgApplications, 0, 0);
DWORD rebootReason;
UINT nProcInfoNeeded, nProcInfo = 16;
RM_PROCESS_INFO affectedApps[16];
RmGetList(RmSession, &nProcInfoNeeded, &nProcInfo, affectedApps, &rebootReason);
if (rebootReason == RmRebootReasonNone) // no need for reboot?
{
// shutdown explorer
RmShutdown(RmSession, RmForceShutdown, 0);
}
}
}
// restarts the explorer
inline void FinishExplorerRestart()
{
DWORD dwError;
if (dwError = RmRestart(RmSession, 0, NULL))
printf("\n RmRestart error: %d\n\n", dwError);
RmEndSession(RmSession);
RmSession = -1;
RmSessionKey[0] = 0;
}
// https://stackoverflow.com/questions/5689904/gracefully-exit-explorer-programmatically
inline BOOL ExitExplorer()
{
HWND hWndTray = FindWindowW(L"Shell_TrayWnd", NULL);
return PostMessageW(hWndTray, 0x5B4, 0, 0);
}
inline void StartExplorer()
{
/*PROCESSENTRY32 pe32 = {0};
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS,
0
);
if (Process32First(hSnapshot, &pe32) == TRUE)
{
do
{
if (!wcscmp(pe32.szExeFile, TEXT("explorer.exe")))
{
HANDLE hSihost = OpenProcess(
PROCESS_TERMINATE,
FALSE,
pe32.th32ProcessID
);
TerminateProcess(hSihost, 1);
CloseHandle(hSihost);
}
} while (Process32Next(hSnapshot, &pe32) == TRUE);
}
CloseHandle(hSnapshot);
*/
wchar_t wszPath[MAX_PATH];
ZeroMemory(
wszPath,
(MAX_PATH) * sizeof(wchar_t)
);
GetWindowsDirectoryW(
wszPath,
MAX_PATH
);
wcscat_s(
wszPath,
MAX_PATH,
L"\\explorer.exe"
);
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
if (CreateProcessW(
NULL,
wszPath,
NULL,
NULL,
TRUE,
CREATE_UNICODE_ENVIRONMENT,
NULL,
NULL,
&si,
&pi
))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
}
#endif