You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Windows下通过Qt/C++程序化修改网卡名称的技术问询

解决Qt/C++修改Windows网卡名称的问题

先直接给你结论:Qt本身没有内置的库可以直接修改Windows网卡名称,你要么解决QProcess调用netsh的两个问题,要么直接调用Windows原生API来实现。我给你分别讲清楚这两种方案:

一、修复QProcess调用netsh的问题

你遇到的权限和空格问题其实都有明确的解决办法:

1. 确保程序以管理员权限运行

有两种常用方式:

  • 添加Manifest文件:在Qt项目里创建一个app.manifest文件,内容如下,然后在.pro文件里加上RC_FILE += app.manifest,这样程序默认会请求管理员权限启动:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
            <requestedPrivileges>
                <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
            </requestedPrivileges>
        </security>
    </trustInfo>
</assembly>
  • 代码中检测权限并重启:如果不想默认提权,可以在程序启动时检查当前权限,若不够则用管理员权限重启自身,Qt里可以通过QProcess调用runas实现。

2. 处理网卡名称含空格的问题

关键是给带空格的网卡名称加上转义的双引号。比如你的netsh命令应该写成:

netsh interface set interface name="Old Network Name" newname="New Network Name"

在Qt的QProcess里,要注意字符串的转义,正确的写法是:

QProcess process;
QString oldName = "Old Network Name";
QString newName = "New Network Name";
QString command = QString("netsh interface set interface name=\"%1\" newname=\"%2\"").arg(oldName).arg(newName);
process.start(command);
process.waitForFinished();

这里用\"来表示命令里的双引号,确保空格被正确识别。

二、直接调用Windows原生API修改(无需netsh)

如果不想依赖netsh命令,可以调用Windows的NetConnectionRename函数(属于netapi32.dll),这是更底层的实现方式。

实现步骤与代码示例

  1. 首先需要获取目标网卡的GUID(每个网卡的唯一标识),可以通过GetAdaptersAddresses函数(来自iphlpapi.lib)获取网卡信息。
  2. 调用NetConnectionRename完成重命名。

示例代码:

#include <windows.h>
#include <iphlpapi.h>
#include <netcon.h>
#include <QString>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "netapi32.lib")

bool renameNetworkAdapter(const QString& oldFriendlyName, const QString& newFriendlyName) {
    // 第一步:获取网卡的GUID
    IP_ADAPTER_ADDRESSES* adapterAddresses = nullptr;
    ULONG bufferSize = 0;

    // 先获取所需缓冲区大小
    GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &bufferSize);
    adapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(bufferSize));
    if (!adapterAddresses) {
        return false;
    }

    DWORD result = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, adapterAddresses, &bufferSize);
    if (result != ERROR_SUCCESS) {
        free(adapterAddresses);
        return false;
    }

    GUID targetGuid;
    bool foundAdapter = false;
    IP_ADAPTER_ADDRESSES* currentAdapter = adapterAddresses;

    while (currentAdapter != nullptr) {
        QString currentName = QString::fromWCharArray(currentAdapter->FriendlyName);
        if (currentName == oldFriendlyName) {
            // 将GUID字符串转换为GUID结构
            if (CLSIDFromString(currentAdapter->AdapterName, &targetGuid) == NOERROR) {
                foundAdapter = true;
                break;
            }
        }
        currentAdapter = currentAdapter->Next;
    }

    free(adapterAddresses);
    if (!foundAdapter) {
        return false;
    }

    // 第二步:调用NetConnectionRename重命名
    DWORD renameResult = NetConnectionRename(
        nullptr,
        &targetGuid,
        reinterpret_cast<LPWSTR>(newFriendlyName.toStdWString().c_str()),
        nullptr
    );

    return renameResult == NO_ERROR;
}

注意事项

  • 这个方法同样需要管理员权限,所以程序必须以管理员身份运行,否则会调用失败。
  • 要确保包含对应的库文件(iphlpapi.libnetapi32.lib),否则编译会报错。

总结

如果你想避免调用外部命令,就用第二种Windows原生API的方式;如果觉得API调用太繁琐,修复QProcess的权限和空格问题也是完全可行的方案。

内容的提问来源于stack exchange,提问作者A. Fasih

火山引擎 最新活动