diff --git a/MemoryCheck.vcxproj b/MemoryCheck.vcxproj
index 8b461b7..ab5cc45 100644
--- a/MemoryCheck.vcxproj
+++ b/MemoryCheck.vcxproj
@@ -77,6 +77,7 @@
$(Platform)\$(Configuration)obj\
$(ProjectDir)include\easylog;$(ProjectDir)include\INIH;$(IncludePath)
+ $(ProjectDir)lib\;$(LibraryPath)
@@ -134,7 +135,7 @@
true
true
true
- rpcrt4.lib;%(AdditionalDependencies)
+ rpcrt4.lib;WtsApi32.Lib;UserEnv.Lib;%(AdditionalDependencies)
diff --git a/lib/UserEnv.Lib b/lib/UserEnv.Lib
new file mode 100644
index 0000000..b4f8d8f
Binary files /dev/null and b/lib/UserEnv.Lib differ
diff --git a/lib/WtsApi32.Lib b/lib/WtsApi32.Lib
new file mode 100644
index 0000000..51a20a7
Binary files /dev/null and b/lib/WtsApi32.Lib differ
diff --git a/lib/userenv.dll b/lib/userenv.dll
new file mode 100644
index 0000000..deb5c6d
Binary files /dev/null and b/lib/userenv.dll differ
diff --git a/lib/wtsapi32.dll b/lib/wtsapi32.dll
new file mode 100644
index 0000000..47cace6
Binary files /dev/null and b/lib/wtsapi32.dll differ
diff --git a/logs/MemoryCheck.log b/logs/MemoryCheck.log
new file mode 100644
index 0000000..d2995d0
--- /dev/null
+++ b/logs/MemoryCheck.log
@@ -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)...
diff --git a/resource/config.ini b/resource/config.ini
index ea3b1e3..c3f17d5 100644
--- a/resource/config.ini
+++ b/resource/config.ini
@@ -1,9 +1,9 @@
-; Test config file for ini_example.c and INIReaderTest.cpp
[MemCheck]
-UpLimit=80 ; 内存检测上限%
-CheckInterval = 4 ; 检测时间间隔s
+UpLimit=90 ; 内存检测上限%
+CheckInterval = 10 ; 检测时间间隔s
+RestartExplorer = true ; 重启explorer
[whitelist] ; 白名单
value = HBDSystemE1000Pro
-value = HBDSystemE1000Pro
+value = notepad++
diff --git a/src/Config.h b/src/Config.h
index 21dcfae..c467db8 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -10,7 +10,7 @@ using namespace std;
class Config {
public :
- Config():m_MemCheckUpLimit(90), m_CheckInterval(60){}
+ Config():m_MemCheckUpLimit(90), m_CheckInterval(60), m_RestartExplorer(false){}
~Config() {}
void Init() {
@@ -26,6 +26,7 @@ public :
m_MemCheckUpLimit = reader.GetReal("MemCheck", "UpLimit", 90);
m_CheckInterval = reader.GetReal("MemCheck", "CheckInterval", 120);
+ m_RestartExplorer = reader.GetBoolean("MemCheck", "RestartExplorer", false);
LOG(TRACE) << m_MemCheckUpLimit;
string whiteList = reader.Get("whitelist", "value", "UNKNOW");
istringstream iss(whiteList);
@@ -34,6 +35,7 @@ public :
m_Whitelists.emplace_back(line);
LOG(TRACE) << "line:" << line;
}
+
}
bool InWhitelists(string& processName) {
@@ -53,5 +55,6 @@ public :
float m_MemCheckUpLimit; //内存检测上限
float m_CheckInterval; //检测时间间隔s
+ bool m_RestartExplorer; //重启explorer
vector m_Whitelists; //白名单
};
\ No newline at end of file
diff --git a/src/MemoryCheck.cpp b/src/MemoryCheck.cpp
index 3ade2dd..ef8c22f 100644
--- a/src/MemoryCheck.cpp
+++ b/src/MemoryCheck.cpp
@@ -13,6 +13,8 @@
#include
#include "../utils/StringHelper.h"
#include "easylogging++.h"
+#include
+#include
/*
NTSYSCALLAPI NTSTATUS NTAPI
@@ -68,6 +70,8 @@ void MemoryCheck::Start()
{
if (m_Running) return;
m_Running = true;
+
+ if(m_Config->m_RestartExplorer) TestRestartProcess();
MonitorProc();
//m_MonitorThread = std::thread(&MemoryCheck::MonitorProc, this);
//SetThreadPriority(m_MonitorThread.native_handle(), THREAD_PRIORITY_BELOW_NORMAL);
@@ -327,7 +331,6 @@ void MemoryCheck::CheckAndAlert() {
log.m_ProcessName = "notepad++";
}
#endif
-
if (needClose) {
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());
LOG(DEBUG) << buffer;
- if (log.m_ProcessName == "explorer" || log.m_ProcessName == "Explorer" || log.m_ProcessName == "EXPLORER") {
- Sleep(2000);
- SHELLEXECUTEINFO sei = { sizeof(sei) };
- sei.lpFile = "explorer.exe";
- sei.lpDirectory = "C:\\Windows";
- sei.nShow = SW_SHOWNORMAL;
- ShellExecuteEx(&sei);
+ if (log.m_ProcessName == "explorer" || log.m_ProcessName == "Explorer" || log.m_ProcessName == "EXPLORER" ||
+ log.m_ProcessName == "explorer.exe" || log.m_ProcessName == "Explorer.exe" || log.m_ProcessName == "EXPLORER.exe") {
+ Sleep(1000);
+ //SHELLEXECUTEINFO sei = { sizeof(sei) };
+ //sei.lpFile = "explorer.exe";
+ //sei.lpDirectory = "C:\\Windows";
+ //sei.nShow = SW_SHOWNORMAL;
+ //ShellExecuteEx(&sei);
+
+ if (StartInteractiveProcess()) {
+ sprintf_s(buffer, sizeof(buffer), u8"启动%s成功", log.m_ProcessName.c_str());
+ LOG(DEBUG) << buffer;
+ }
}
break;
}
@@ -599,3 +608,125 @@ BOOLEAN MemoryCheck::PhIsExecutingInWow64(VOID)
return FALSE;
#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;
+}
+
diff --git a/src/MemoryCheck.h b/src/MemoryCheck.h
index 9b01ed9..8f4cc2b 100644
--- a/src/MemoryCheck.h
+++ b/src/MemoryCheck.h
@@ -720,6 +720,9 @@ private:
void InitializeWindowsInformation();
BOOLEAN PhIsExecutingInWow64(VOID);
FORCEINLINE NTSTATUS PhGetProcessIsWow64(_In_ HANDLE ProcessHandle, _Out_ PBOOLEAN IsWow64Process);
+
+ void TestRestartProcess();
+ BOOL StartInteractiveProcess();
private:
std::atomic m_Running{ false };
//std::thread m_MonitorThread;