修改explorer无法启动的问题
This commit is contained in:
parent
dcec7afdca
commit
d9706e16bd
@ -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
BIN
lib/UserEnv.Lib
Normal file
Binary file not shown.
BIN
lib/WtsApi32.Lib
Normal file
BIN
lib/WtsApi32.Lib
Normal file
Binary file not shown.
BIN
lib/userenv.dll
Normal file
BIN
lib/userenv.dll
Normal file
Binary file not shown.
BIN
lib/wtsapi32.dll
Normal file
BIN
lib/wtsapi32.dll
Normal file
Binary file not shown.
3
logs/MemoryCheck.log
Normal file
3
logs/MemoryCheck.log
Normal 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)...
|
||||||
@ -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++
|
||||||
|
|||||||
@ -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; //白名单
|
||||||
};
|
};
|
||||||
@ -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);
|
||||||
@ -328,7 +332,6 @@ void MemoryCheck::CheckAndAlert() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (needClose) {
|
if (needClose) {
|
||||||
LOG(INFO) << u8"尝试关闭" << log.m_ProcessName.c_str();
|
LOG(INFO) << u8"尝试关闭" << log.m_ProcessName.c_str();
|
||||||
string pskillPath = StringHelper::GetAppPath() + "pskill.exe";
|
string pskillPath = StringHelper::GetAppPath() + "pskill.exe";
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user