粒子连接器修改
This commit is contained in:
1 parent
bd0771747d
commit
8ab3672c4e
5 files changed
+170
-6
No files matched your search
@@ -1,17 +1,24 @@
|
||||
#ifdef _WIN32
|
||||
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#include "platform.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace connector {
|
||||
namespace {
|
||||
|
||||
constexpr unsigned short kConnectorPort = 27843;
|
||||
|
||||
std::wstring wide(const std::string& value) {
|
||||
if (value.empty()) return {};
|
||||
const int size = MultiByteToWideChar(CP_UTF8, 0, value.data(), static_cast<int>(value.size()), nullptr, 0);
|
||||
@@ -35,6 +42,26 @@ std::wstring quote(const std::string& value) {
|
||||
return result + L'\"';
|
||||
}
|
||||
|
||||
std::set<DWORD> connector_port_pids() {
|
||||
DWORD size = 0;
|
||||
DWORD result = GetExtendedTcpTable(nullptr, &size, FALSE, AF_INET,
|
||||
TCP_TABLE_OWNER_PID_LISTENER, 0);
|
||||
if (result != ERROR_INSUFFICIENT_BUFFER || size == 0) return {};
|
||||
std::vector<unsigned char> storage(size);
|
||||
result = GetExtendedTcpTable(storage.data(), &size, FALSE, AF_INET,
|
||||
TCP_TABLE_OWNER_PID_LISTENER, 0);
|
||||
if (result != NO_ERROR) return {};
|
||||
const auto* table = reinterpret_cast<const MIB_TCPTABLE_OWNER_PID*>(storage.data());
|
||||
std::set<DWORD> pids;
|
||||
for (DWORD index = 0; index < table->dwNumEntries; ++index) {
|
||||
const auto& row = table->table[index];
|
||||
if (ntohs(static_cast<u_short>(row.dwLocalPort)) == kConnectorPort && row.dwOwningPid != 0) {
|
||||
pids.insert(row.dwOwningPid);
|
||||
}
|
||||
}
|
||||
return pids;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ProcessResult run_process(const std::string& executable,
|
||||
@@ -93,6 +120,46 @@ ProcessResult run_process(const std::string& executable,
|
||||
return result;
|
||||
}
|
||||
|
||||
bool connector_port_in_use() {
|
||||
return !connector_port_pids().empty();
|
||||
}
|
||||
|
||||
bool stop_connector_port(std::string& error) {
|
||||
const std::set<DWORD> pids = connector_port_pids();
|
||||
if (pids.empty()) {
|
||||
error.clear();
|
||||
return true;
|
||||
}
|
||||
for (const DWORD pid : pids) {
|
||||
if (pid == GetCurrentProcessId()) {
|
||||
error = "无法从外部停止当前连接器进程";
|
||||
return false;
|
||||
}
|
||||
HANDLE process = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid);
|
||||
if (!process) {
|
||||
error = "无法停止占用端口 27843 的进程,请以管理员身份运行后重试";
|
||||
return false;
|
||||
}
|
||||
const BOOL stopped = TerminateProcess(process, 0);
|
||||
if (stopped) WaitForSingleObject(process, 3000);
|
||||
CloseHandle(process);
|
||||
if (!stopped) {
|
||||
error = "停止占用端口 27843 的进程失败";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(3);
|
||||
while (std::chrono::steady_clock::now() < deadline) {
|
||||
if (!connector_port_in_use()) {
|
||||
error.clear();
|
||||
return true;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
}
|
||||
error = "进程已停止,但端口 27843 仍未释放";
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace connector
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user