修改explorer无法启动的问题
This commit is contained in:
parent
dcec7afdca
commit
d9706e16bd
@ -77,6 +77,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>$(Platform)\$(Configuration)obj\</IntDir>
|
||||
<IncludePath>$(ProjectDir)include\easylog;$(ProjectDir)include\INIH;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)lib\;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@ -134,7 +135,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>rpcrt4.lib;WtsApi32.Lib;UserEnv.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<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]
|
||||
UpLimit=80 ; 内存检测上限%
|
||||
CheckInterval = 4 ; 检测时间间隔s
|
||||
UpLimit=90 ; 内存检测上限%
|
||||
CheckInterval = 10 ; 检测时间间隔s
|
||||
RestartExplorer = true ; 重启explorer
|
||||
|
||||
[whitelist] ; 白名单
|
||||
value = HBDSystemE1000Pro
|
||||
value = HBDSystemE1000Pro
|
||||
value = notepad++
|
||||
|
||||
@ -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<string> m_Whitelists; //白名单
|
||||
};
|
||||
@ -13,6 +13,8 @@
|
||||
#include <sstream>
|
||||
#include "../utils/StringHelper.h"
|
||||
#include "easylogging++.h"
|
||||
#include <wtsapi32.h>
|
||||
#include <UserEnv.h>
|
||||
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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<bool> m_Running{ false };
|
||||
//std::thread m_MonitorThread;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user