Qt上位机开发之如何让自己的APP启动与硬件信息绑定(Win端)

简介: Qt上位机开发之如何让自己的APP启动与硬件信息绑定(Win端)

在工作中,为了方便项目调试,一般情况下我们都会选择开发一个上位机来实现简单的控制和数据读取的功能;但是,这个工具仅限于研发人员使用。为了防止别有用心的测试或者其它人员将这个APP通过U盘的形式拷贝走然后到另外一台电脑上运行,我们可以有以下两种简单的设计方案(以下内容默认用户已了解QT上位机开发,故屏蔽许多细节):


(1)设计一个简单的输入密码逻辑,当输入密码与自己设定的密码匹配时,即进入软件界面。这种方法比较简单,也很容易被破解。


(2)提前通过另外一个软件读取本机的硬件信息(我们称之为注册机),然后通过某种编码格式将该信息编码为其它的格式并生成一个文件(将该文件放到系统较为隐蔽的目录下)。当我们使用的APP打开时,按照约定格式打开并将该文件里的数据转换为硬件信息,然后进行匹配,如果发现没有该文件或者硬件信息不匹配,则提示软件未注册,否则,正常打开该软件。


第一种方法比较简单,初学QT应用编程的小白都可以很容易将它实现,我们就不多说了。我们重点来讲解一下第二种方法的实现。


以下几个命令可以在Window cmd上运行即可以看到对应的信息:

获取cpu名称
wmic cpu get Name
获取cpu核心数
wmic cpu get NumberOfCores
获取cpu线程数
wmic cpu get NumberOfLogicalProcessors
查询cpu序列号
wmic cpu get processorid
查询主板序列号
wmic baseboard get serialnumber
查询BIOS序列号
wmic bios get serialnumber
查看硬盘
wmic diskdrive get serialnumber

这是我的电脑硬件信息:

640.png

其中,CPU序列号是一个唯一的ID号,它是厂家在制造CPU的时候烧入到内部的。我在工作中主要使用这个来进行加密,当然你也可以使用其它的内容。下来我们可以实现一个简单的注册机逻辑:


  • 实现获取硬件信息接口
  • 将硬件信息经过Base64格式转换
  • 显示Base64格式转换为的结果
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
//获取cpu名称:wmic cpu get Name
//获取cpu核心数:wmic cpu get NumberOfCores
//获取cpu线程数:wmic cpu get NumberOfLogicalProcessors
//查询cpu序列号:wmic cpu get processorid
//查询主板序列号:wmic baseboard get serialnumber
//查询BIOS序列号:wmic bios get serialnumber
//查看硬盘:wmic diskdrive get serialnumber
QString MainWindow::getMachineInfo(const QString &cmd)
{
    QProcess p;
    p.start(cmd);
    p.waitForFinished();
    QString result = QString::fromLocal8Bit(p.readAllStandardOutput());
    QStringList list = cmd.split(" ");
    result = result.remove(list.last(), Qt::CaseInsensitive);
    result = result.replace("\r", "");
    result = result.replace("\n", "");
    result = result.simplified();
    return result;
}
QByteArray MainWindow::Encode(QByteArray data)
{
    return data.toBase64();
}
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("注册机");
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_GenerateCode_clicked()
{
    QString Code = getMachineInfo("wmic cpu get processorid");
    QFile file("D:/Register.txt");
    //打开文件,不存在则创建
    file.open(QIODevice::ReadWrite | QIODevice::Text);
    //写入文件需要字符串为QByteArray格式
    if(file.write(Encode(Code.toLatin1())) > 0)
    {
        ui->CodeDisplay->setText(Encode(Code.toLatin1()));
        QMessageBox::information(NULL, "提示", "注册成功", QMessageBox::Ok);
    }
    else
        QMessageBox::information(NULL, "提示", "注册失败", QMessageBox::Ok);
    file.close();
}

编译运行后,当我们点击生成注册码时,则会显示硬件信息通过Base64编码的结果,如下所示:

640.png

640.png

一个简单的注册机写完以后,APP在加载运行的时候需要加上以下逻辑:

#include "mainwindow.h"
#include <QApplication>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
QString getMachineInfo(const QString &cmd)
{
    QProcess p;
    p.start(cmd);
    p.waitForFinished();
    QString result = QString::fromLocal8Bit(p.readAllStandardOutput());
    QStringList list = cmd.split(" ");
    result = result.remove(list.last(), Qt::CaseInsensitive);
    result = result.replace("\r", "");
    result = result.replace("\n", "");
    result = result.simplified();
    return result;
}
int main(int argc, char *argv[])
{
    uint8_t RunFlag = 0;
    QByteArray DecodeStr;
    QString CpuSerialNumber;
    QApplication a(argc, argv);
    //1.获取CPU序列号
    CpuSerialNumber = getMachineInfo("wmic cpu get processorid");
    //2.打开注册码文件,读取加密字符串并进行匹配加密字符串
    QFile file("D:/Register.txt");
    if(!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(NULL, "Error", "注册码不存在,请导入注册码!",QMessageBox::Yes);
        return -1;
    }
    else
    {
        //读取文件所有的内存
        QByteArray EncodeStr = file.readAll();
        //将读取的内容进行解码
        DecodeStr = fromBase64(EncodeStr);
        //将解码的结果与当前PC的CPU序列号进行比较
        QString Str(DecodeStr);
        if(0 == Str.compare(CpuSerialNumber))
             RunFlag = 1;
    }
    //3.如果匹配成功,运行软件
    if(RunFlag)
    {
        MainWindow w;
        w.show();
        return a.exec();
    }
    else
    {
        QMessageBox::warning(NULL, "Error", "注册码无效,请联系厂商获取注册码!",QMessageBox::Yes);
        return -1;
    }
    return 0;
}

实现注册机更好的方案则可以直接将信息写入注册表,然后APP去注册表中读取相应的内容。关于硬件信息的加密和解密方式,用户可以有其它的实现方法。


这里留一个问题,如何将APP启动信息与其它平台进行关联呢?例如Qt ARM端、Mac端、Android端?


好了,今天的分享到此为止,如果对您有帮助,欢迎一键三连!

往期精彩

QT移植腾讯云C-SDK结合实现OTA更新


QT开发中延时的几种处理方法


嵌入式linux检测U盘拔插与QT界面开发相结合的实现思路


嵌入式Linux Qt应用开发WIFI搜索、显示与连接思路


Qt串口通信接收数据不完整,怎么解决?

目录
相关文章
|
5天前
|
移动开发 小程序
如何让uni-app开发的H5页面顶部原生标题和小程序的顶部标题不一致?
如何让uni-app开发的H5页面顶部原生标题和小程序的顶部标题不一致?
|
5天前
|
算法 编译器 Linux
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
30 0
|
1天前
|
Web App开发 JSON 小程序
苹果app开发apple-app-site-association文件配置
apple-app-site-association 是苹果的配置文件,用于建立app和网站关联,支持Universal Links,使点击网站链接能直接打开相应app内部页面。配置文件为JSON格式,需上传至服务器`.well-known`目录或根目录。通过检查三个链接来测试配置,确保Content-Type为`application/json`。成功配置后,点击链接能在iPhone备忘录或Safari中直接唤起app,但可能有24-48小时延迟。
17 6
|
5天前
|
网络协议 算法 网络性能优化
Qt TCP网络上位机的设计(通过网络编程与下位机结合)
Qt TCP网络上位机的设计(通过网络编程与下位机结合)
Qt TCP网络上位机的设计(通过网络编程与下位机结合)
|
5天前
|
区块链
【qt】最快的开发界面效率——混合编程3
【qt】最快的开发界面效率——混合编程
16 1
|
5天前
【qt】最快的开发界面效率——混合编程2
【qt】最快的开发界面效率——混合编程
14 1
|
5天前
【qt】最快的开发界面效率——混合编程1
【qt】最快的开发界面效率——混合编程
18 0
|
5天前
|
Web App开发 数据采集 移动开发
开发uniapp过程中对app、微信小程序与h5的webview调试
开发uniapp过程中对app、微信小程序与h5的webview调试
13 1
|
5天前
|
前端开发 Android开发 开发者
【Flutter前端技术开发专栏】Flutter中的混合应用(Hybrid Apps)开发
【4月更文挑战第30天】本文探讨了使用Flutter开发混合应用的方法。混合应用结合Web技术和原生容器,提供快速开发和低成本维护。Flutter,一款现代前端框架,以其插件系统和高性能渲染引擎支持混合应用开发。通过创建Flutter项目、添加平台代码、使用WebView、处理平台间通信以及发布应用,开发者可构建跨平台混合应用。虽然混合应用有性能和用户体验的局限,但Flutter的跨平台兼容性和丰富的插件生态降低了开发成本。开发者应根据项目需求权衡选择。
【Flutter前端技术开发专栏】Flutter中的混合应用(Hybrid Apps)开发
|
5天前
|
开发框架 编译器 C++
Qt:一个强大的跨平台C++应用程序开发框架
Qt:一个强大的跨平台C++应用程序开发框架
37 1

热门文章

最新文章

推荐镜像

更多