You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++提取CMD命令输出中变动的端口号与Remoting Auth Token

解决C++提取LeagueClientUx端口与remoting-auth-token的问题

我来帮你搞定这个问题!要提取目标进程的端口和token,得分成两步走:先正确捕获WMIC命令的输出,再用正则精准匹配需要的内容。

第一步:捕获WMIC命令的输出到std::string

直接用system()调用CMD命令没法获取输出,得用Windows的管道机制来捕获标准输出。下面是封装好的函数,能把指定命令的输出转换成std::string:

#include <windows.h>
#include <string>
#include <iostream>

std::string executeCommand(const std::string& cmd) {
    std::string result;
    HANDLE hReadPipe, hWritePipe;
    SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE};

    if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
        return "";
    }

    STARTUPINFO si = {sizeof(STARTUPINFO)};
    si.hStdOutput = hWritePipe;
    si.hStdError = hWritePipe;
    si.dwFlags |= STARTF_USESTDHANDLES;

    PROCESS_INFORMATION pi;
    if (!CreateProcess(nullptr, const_cast<char*>(cmd.c_str()), nullptr, nullptr, TRUE, 0, nullptr, nullptr, &si, &pi)) {
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        return "";
    }

    CloseHandle(hWritePipe);

    char buffer[4096];
    DWORD bytesRead;
    while (ReadFile(hReadPipe, buffer, sizeof(buffer)-1, &bytesRead, nullptr) && bytesRead > 0) {
        buffer[bytesRead] = '\0';
        result += buffer;
    }

    CloseHandle(hReadPipe);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return result;
}

调用这个函数的时候,直接传你的WMIC命令就行:

std::string cmdOutput = executeCommand("wmic PROCESS WHERE name='LeagueClientUx.exe' GET commandline");

第二步:用正则表达式提取端口和token

WMIC的输出可能会有多余的换行、空格,所以先处理一下(比如去掉重复空白字符),然后用正则匹配--app-port=和--remoting-auth-token=后面的内容。这里用C++11及以上的<regex>库:

#include <regex>
#include <algorithm>

// 辅助函数:清理多余的空白字符
std::string cleanWhitespace(const std::string& input) {
    std::string result;
    bool inWhitespace = false;
    for (char c : input) {
        if (std::isspace(static_cast<unsigned char>(c))) {
            if (!inWhitespace) {
                result += ' ';
                inWhitespace = true;
            }
        } else {
            result += c;
            inWhitespace = false;
        }
    }
    return result;
}

// 提取端口和token的函数
void extractLeagueClientInfo(const std::string& cmdOutput, std::string& port, std::string& token) {
    std::string cleaned = cleanWhitespace(cmdOutput);

    // 匹配端口:--app-port=数字
    std::regex portRegex(R"(--app-port=(\d+))");
    std::smatch portMatch;
    if (std::regex_search(cleaned, portMatch, portRegex)) {
        port = portMatch[1].str();
    }

    // 匹配token:--remoting-auth-token=任意非空白字符(直到下一个参数)
    std::regex tokenRegex(R"(--remoting-auth-token=(\S+))");
    std::smatch tokenMatch;
    if (std::regex_search(cleaned, tokenMatch, tokenRegex)) {
        token = tokenMatch[1].str();
    }
}

完整示例代码

把上面的部分整合起来,就能直接运行:

#include <windows.h>
#include <string>
#include <iostream>
#include <regex>
#include <algorithm>

std::string executeCommand(const std::string& cmd) {
    std::string result;
    HANDLE hReadPipe, hWritePipe;
    SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE};

    if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
        return "";
    }

    STARTUPINFO si = {sizeof(STARTUPINFO)};
    si.hStdOutput = hWritePipe;
    si.hStdError = hWritePipe;
    si.dwFlags |= STARTF_USESTDHANDLES;

    PROCESS_INFORMATION pi;
    if (!CreateProcess(nullptr, const_cast<char*>(cmd.c_str()), nullptr, nullptr, TRUE, 0, nullptr, nullptr, &si, &pi)) {
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        return "";
    }

    CloseHandle(hWritePipe);

    char buffer[4096];
    DWORD bytesRead;
    while (ReadFile(hReadPipe, buffer, sizeof(buffer)-1, &bytesRead, nullptr) && bytesRead > 0) {
        buffer[bytesRead] = '\0';
        result += buffer;
    }

    CloseHandle(hReadPipe);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return result;
}

std::string cleanWhitespace(const std::string& input) {
    std::string result;
    bool inWhitespace = false;
    for (char c : input) {
        if (std::isspace(static_cast<unsigned char>(c))) {
            if (!inWhitespace) {
                result += ' ';
                inWhitespace = true;
            }
        } else {
            result += c;
            inWhitespace = false;
        }
    }
    return result;
}

void extractLeagueClientInfo(const std::string& cmdOutput, std::string& port, std::string& token) {
    std::string cleaned = cleanWhitespace(cmdOutput);

    std::regex portRegex(R"(--app-port=(\d+))");
    std::smatch portMatch;
    if (std::regex_search(cleaned, portMatch, portRegex)) {
        port = portMatch[1].str();
    }

    std::regex tokenRegex(R"(--remoting-auth-token=(\S+))");
    std::smatch tokenMatch;
    if (std::regex_search(cleaned, tokenMatch, tokenRegex)) {
        token = tokenMatch[1].str();
    }
}

int main() {
    std::string cmdOutput = executeCommand("wmic PROCESS WHERE name='LeagueClientUx.exe' GET commandline");
    std::string port, token;
    extractLeagueClientInfo(cmdOutput, port, token);

    std::cout << "端口号:" << (port.empty() ? "未找到" : port) << std::endl;
    std::cout << "Remoting Auth Token:" << (token.empty() ? "未找到" : token) << std::endl;

    return 0;
}

注意事项

  • 确保你的项目是用C11或更高版本编译(因为用到了<regex>和C11的特性)
  • 如果WMIC输出有多个进程实例(比如开了多个客户端?不过一般不会),正则会匹配第一个找到的,你可以改成循环搜索处理多个实例
  • 有时候WMIC的输出开头会有"CommandLine"表头,清理空白后不影响正则匹配,因为正则是找具体的参数项

内容的提问来源于stack exchange,提问作者Lordi1000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 13:12:59