修改explorer无法启动的问题

This commit is contained in:
wangxx1809 2025-09-26 13:44:47 +08:00
parent dcec7afdca
commit d9706e16bd
10 changed files with 155 additions and 14 deletions

View File

@ -77,6 +77,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IntDir>$(Platform)\$(Configuration)obj\</IntDir> <IntDir>$(Platform)\$(Configuration)obj\</IntDir>
<IncludePath>$(ProjectDir)include\easylog;$(ProjectDir)include\INIH;$(IncludePath)</IncludePath> <IncludePath>$(ProjectDir)include\easylog;$(ProjectDir)include\INIH;$(IncludePath)</IncludePath>
<LibraryPath>$(ProjectDir)lib\;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
@ -134,7 +135,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>rpcrt4.lib;WtsApi32.Lib;UserEnv.Lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

BIN
lib/UserEnv.Lib Normal file

Binary file not shown.

BIN
lib/WtsApi32.Lib Normal file

Binary file not shown.

BIN
lib/userenv.dll Normal file

Binary file not shown.

BIN
lib/wtsapi32.dll Normal file

Binary file not shown.

3
logs/MemoryCheck.log Normal file
View File

@ -0,0 +1,3 @@
2025-09-26 10:45:08,181 DEBUG [main.cpp|274] start error(1063)...
2025-09-26 11:04:45,725 DEBUG [main.cpp|274] start error(1063)...
2025-09-26 12:01:41,746 DEBUG [main.cpp|274] start error(1063)...

View File

@ -1,9 +1,9 @@
; Test config file for ini_example.c and INIReaderTest.cpp
[MemCheck] [MemCheck]
UpLimit=80 ; 内存检测上限% UpLimit=90 ; 内存检测上限%
CheckInterval = 4 ; 检测时间间隔s CheckInterval = 10 ; 检测时间间隔s
RestartExplorer = true ; 重启explorer
[whitelist] ; 白名单 [whitelist] ; 白名单
value = HBDSystemE1000Pro value = HBDSystemE1000Pro
value = HBDSystemE1000Pro value = notepad++

View File

@ -10,7 +10,7 @@ using namespace std;
class Config { class Config {
public : public :
Config():m_MemCheckUpLimit(90), m_CheckInterval(60){} Config():m_MemCheckUpLimit(90), m_CheckInterval(60), m_RestartExplorer(false){}
~Config() {} ~Config() {}
void Init() { void Init() {
@ -26,6 +26,7 @@ public :
m_MemCheckUpLimit = reader.GetReal("MemCheck", "UpLimit", 90); m_MemCheckUpLimit = reader.GetReal("MemCheck", "UpLimit", 90);
m_CheckInterval = reader.GetReal("MemCheck", "CheckInterval", 120); m_CheckInterval = reader.GetReal("MemCheck", "CheckInterval", 120);
m_RestartExplorer = reader.GetBoolean("MemCheck", "RestartExplorer", false);
LOG(TRACE) << m_MemCheckUpLimit; LOG(TRACE) << m_MemCheckUpLimit;
string whiteList = reader.Get("whitelist", "value", "UNKNOW"); string whiteList = reader.Get("whitelist", "value", "UNKNOW");
istringstream iss(whiteList); istringstream iss(whiteList);
@ -34,6 +35,7 @@ public :
m_Whitelists.emplace_back(line); m_Whitelists.emplace_back(line);
LOG(TRACE) << "line:" << line; LOG(TRACE) << "line:" << line;
} }
} }
bool InWhitelists(string& processName) { bool InWhitelists(string& processName) {
@ -53,5 +55,6 @@ public :
float m_MemCheckUpLimit; //内存检测上限 float m_MemCheckUpLimit; //内存检测上限
float m_CheckInterval; //检测时间间隔s float m_CheckInterval; //检测时间间隔s
bool m_RestartExplorer; //重启explorer
vector<string> m_Whitelists; //白名单 vector<string> m_Whitelists; //白名单
}; };

View File

@ -13,6 +13,8 @@
#include <sstream> #include <sstream>
#include "../utils/StringHelper.h" #include "../utils/StringHelper.h"
#include "easylogging++.h" #include "easylogging++.h"
#include <wtsapi32.h>
#include <UserEnv.h>
/* /*
NTSYSCALLAPI NTSTATUS NTAPI NTSYSCALLAPI NTSTATUS NTAPI
@ -68,6 +70,8 @@ void MemoryCheck::Start()
{ {
if (m_Running) return; if (m_Running) return;
m_Running = true; m_Running = true;
if(m_Config->m_RestartExplorer) TestRestartProcess();
MonitorProc(); MonitorProc();
//m_MonitorThread = std::thread(&MemoryCheck::MonitorProc, this); //m_MonitorThread = std::thread(&MemoryCheck::MonitorProc, this);
//SetThreadPriority(m_MonitorThread.native_handle(), THREAD_PRIORITY_BELOW_NORMAL); //SetThreadPriority(m_MonitorThread.native_handle(), THREAD_PRIORITY_BELOW_NORMAL);
@ -327,7 +331,6 @@ void MemoryCheck::CheckAndAlert() {
log.m_ProcessName = "notepad++"; log.m_ProcessName = "notepad++";
} }
#endif #endif
if (needClose) { if (needClose) {
LOG(INFO) << u8"尝试关闭" << log.m_ProcessName.c_str(); LOG(INFO) << u8"尝试关闭" << log.m_ProcessName.c_str();
@ -374,13 +377,19 @@ void MemoryCheck::CheckAndAlert() {
sprintf_s(buffer, sizeof(buffer),u8"关闭%s成功", log.m_ProcessName.c_str()); sprintf_s(buffer, sizeof(buffer),u8"关闭%s成功", log.m_ProcessName.c_str());
LOG(DEBUG) << buffer; LOG(DEBUG) << buffer;
if (log.m_ProcessName == "explorer" || log.m_ProcessName == "Explorer" || log.m_ProcessName == "EXPLORER") { if (log.m_ProcessName == "explorer" || log.m_ProcessName == "Explorer" || log.m_ProcessName == "EXPLORER" ||
Sleep(2000); log.m_ProcessName == "explorer.exe" || log.m_ProcessName == "Explorer.exe" || log.m_ProcessName == "EXPLORER.exe") {
SHELLEXECUTEINFO sei = { sizeof(sei) }; Sleep(1000);
sei.lpFile = "explorer.exe"; //SHELLEXECUTEINFO sei = { sizeof(sei) };
sei.lpDirectory = "C:\\Windows"; //sei.lpFile = "explorer.exe";
sei.nShow = SW_SHOWNORMAL; //sei.lpDirectory = "C:\\Windows";
ShellExecuteEx(&sei); //sei.nShow = SW_SHOWNORMAL;
//ShellExecuteEx(&sei);
if (StartInteractiveProcess()) {
sprintf_s(buffer, sizeof(buffer), u8"启动%s成功", log.m_ProcessName.c_str());
LOG(DEBUG) << buffer;
}
} }
break; break;
} }
@ -599,3 +608,125 @@ BOOLEAN MemoryCheck::PhIsExecutingInWow64(VOID)
return FALSE; return FALSE;
#endif #endif
} }
void MemoryCheck::TestRestartProcess() {
string processName = "explorer";
LOG(INFO) << u8"尝试关闭" << processName.c_str();
string pskillPath = StringHelper::GetAppPath() + "pskill.exe";
char cmd[512];
sprintf_s(cmd, sizeof(cmd), "%s /accepteula %s", pskillPath.c_str(), processName.c_str());
HANDLE hReadPipe, hWritePipe;
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
return;
}
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi = {};
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
si.hStdInput = NULL;
if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
return;
}
CloseHandle(hWritePipe); // 关闭写端,让读操作能结束
char buffer[4096];
DWORD bytesRead;
stringstream output;
while (ReadFile(hReadPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead > 0) {
buffer[bytesRead] = '\0';
output << buffer;
}
CloseHandle(hReadPipe);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
string outstr = output.str();
if (outstr.find("killed") != string::npos)
{
sprintf_s(buffer, sizeof(buffer), u8"关闭%s成功", processName.c_str());
LOG(DEBUG) << buffer;
if (processName == "explorer" || processName == "Explorer" || processName == "EXPLORER" ||
processName == "explorer.exe" || processName == "Explorer.exe" || processName == "EXPLORER.exe") {
Sleep(1000);
if (StartInteractiveProcess()) {
sprintf_s(buffer, sizeof(buffer), u8"启动%s成功", processName.c_str());
LOG(DEBUG) << buffer;
}
}
}
else {
sprintf_s(buffer, sizeof(buffer), u8"关闭%s失败", processName.c_str());
LOG(WARNING) << buffer;
}
}
BOOL MemoryCheck::StartInteractiveProcess() {
DWORD sessionId = WTSGetActiveConsoleSessionId();
if (sessionId == 0xFFFFFFFF) return FALSE;
HANDLE hToken;
if (!WTSQueryUserToken(sessionId, &hToken)) return FALSE;
// 获取用户配置文件目录
char profilePath[MAX_PATH];
DWORD profileSize = MAX_PATH;
if (!GetUserProfileDirectory(hToken, profilePath, &profileSize)) {
CloseHandle(hToken);
return FALSE;
}
// 复制令牌
HANDLE hDuplicatedToken;
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityIdentification, TokenPrimary, &hDuplicatedToken)) {
CloseHandle(hToken);
return FALSE;
}
// 创建环境块
LPVOID envBlock;
if (!CreateEnvironmentBlock(&envBlock, hToken, FALSE)) {
CloseHandle(hDuplicatedToken);
CloseHandle(hToken);
return FALSE;
}
STARTUPINFO si = { sizeof(si) };
si.lpDesktop = (char*)"winsta0\\default";
PROCESS_INFORMATION pi;
char command[] = "explorer.exe";
// 使用用户的主目录作为工作目录
BOOL success = CreateProcessAsUser(hDuplicatedToken,
NULL, command,
NULL, NULL, FALSE,
CREATE_UNICODE_ENVIRONMENT,
envBlock,
profilePath, // 使用用户目录作为工作目录
&si, &pi);
if (success) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
if(envBlock) DestroyEnvironmentBlock(envBlock);
if(hDuplicatedToken) CloseHandle(hDuplicatedToken);
if(hToken) CloseHandle(hToken);
return success;
}

View File

@ -720,6 +720,9 @@ private:
void InitializeWindowsInformation(); void InitializeWindowsInformation();
BOOLEAN PhIsExecutingInWow64(VOID); BOOLEAN PhIsExecutingInWow64(VOID);
FORCEINLINE NTSTATUS PhGetProcessIsWow64(_In_ HANDLE ProcessHandle, _Out_ PBOOLEAN IsWow64Process); FORCEINLINE NTSTATUS PhGetProcessIsWow64(_In_ HANDLE ProcessHandle, _Out_ PBOOLEAN IsWow64Process);
void TestRestartProcess();
BOOL StartInteractiveProcess();
private: private:
std::atomic<bool> m_Running{ false }; std::atomic<bool> m_Running{ false };
//std::thread m_MonitorThread; //std::thread m_MonitorThread;