在工作中,為了方便項(xiàng)目調(diào)試,一般情況下我們都會(huì)選擇開發(fā)一個(gè)上位機(jī)來(lái)實(shí)現(xiàn)簡(jiǎn)單的控制和數(shù)據(jù)讀取的功能;但是,這個(gè)工具僅限于研發(fā)人員使用。為了防止別有用心的測(cè)試或者其它人員將這個(gè)APP通過(guò)U盤的形式拷貝走然后到另外一臺(tái)電腦上運(yùn)行,我們可以有以下兩種簡(jiǎn)單的設(shè)計(jì)方案(以下內(nèi)容默認(rèn)用戶已了解QT上位機(jī)開發(fā),故屏蔽許多細(xì)節(jié)):
(1)設(shè)計(jì)一個(gè)簡(jiǎn)單的輸入密碼邏輯,當(dāng)輸入密碼與自己設(shè)定的密碼匹配時(shí),即進(jìn)入軟件界面。這種方法比較簡(jiǎn)單,也很容易被破解。
(2)提前通過(guò)另外一個(gè)軟件讀取本機(jī)的硬件信息(我們稱之為注冊(cè)機(jī)),然后通過(guò)某種編碼格式將該信息編碼為其它的格式并生成一個(gè)文件(將該文件放到系統(tǒng)較為隱蔽的目錄下)。當(dāng)我們使用的APP打開時(shí),按照約定格式打開并將該文件里的數(shù)據(jù)轉(zhuǎn)換為硬件信息,然后進(jìn)行匹配,如果發(fā)現(xiàn)沒(méi)有該文件或者硬件信息不匹配,則提示軟件未注冊(cè),否則,正常打開該軟件。
第一種方法比較簡(jiǎn)單,初學(xué)QT應(yīng)用編程的小白都可以很容易將它實(shí)現(xiàn),我們就不多說(shuō)了。我們重點(diǎn)來(lái)講解一下第二種方法的實(shí)現(xiàn)。
以下幾個(gè)命令可以在Window cmd上運(yùn)行即可以看到對(duì)應(yīng)的信息:
獲取cpu名稱 wmiccpugetName 獲取cpu核心數(shù) wmiccpugetNumberOfCores 獲取cpu線程數(shù) wmiccpugetNumberOfLogicalProcessors 查詢cpu序列號(hào) wmiccpugetprocessorid 查詢主板序列號(hào) wmicbaseboardgetserialnumber 查詢BIOS序列號(hào) wmicbiosgetserialnumber 查看硬盤 wmicdiskdrivegetserialnumber
這是我的電腦硬件信息:
其中,CPU序列號(hào)是一個(gè)唯一的ID號(hào),它是廠家在制造CPU的時(shí)候燒入到內(nèi)部的。我在工作中主要使用這個(gè)來(lái)進(jìn)行加密,當(dāng)然你也可以使用其它的內(nèi)容。接下來(lái)我們可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的注冊(cè)機(jī)邏輯:
實(shí)現(xiàn)獲取硬件信息接口
將硬件信息經(jīng)過(guò)Base64格式轉(zhuǎn)換
顯示Base64格式轉(zhuǎn)換為的結(jié)果
#include"mainwindow.h" #include"ui_mainwindow.h" #include//獲取cpu名稱:wmic cpu get Name //獲取cpu核心數(shù):wmic cpu get NumberOfCores //獲取cpu線程數(shù):wmic cpu get NumberOfLogicalProcessors //查詢cpu序列號(hào):wmic cpu get processorid //查詢主板序列號(hào):wmic baseboard get serialnumber //查詢BIOS序列號(hào):wmic bios get serialnumber //查看硬盤:wmic diskdrive get serialnumber QStringMainWindow::getMachineInfo(constQString&cmd) { QProcessp; p.start(cmd); p.waitForFinished(); QStringresult=QString::fromLocal8Bit(p.readAllStandardOutput()); QStringListlist=cmd.split(""); result=result.remove(list.last(),Qt::CaseInsensitive); result=result.replace(" ",""); result=result.replace(" ",""); result=result.simplified(); returnresult; } QByteArrayMainWindow::Encode(QByteArraydata) { returndata.toBase64(); } MainWindow::MainWindow(QWidget*parent) :QMainWindow(parent) ,ui(newUi::MainWindow) { ui->setupUi(this); this->setWindowTitle("注冊(cè)機(jī)"); } MainWindow::~MainWindow() { deleteui; } voidMainWindow::on_GenerateCode_clicked() { QStringCode=getMachineInfo("wmiccpugetprocessorid"); QFilefile("D:/Register.txt"); //打開文件,不存在則創(chuàng)建 file.open(QIODevice::ReadWrite|QIODevice::Text); //寫入文件需要字符串為QByteArray格式 if(file.write(Encode(Code.toLatin1()))>0) { ui->CodeDisplay->setText(Encode(Code.toLatin1())); QMessageBox::information(NULL,"提示","注冊(cè)成功",QMessageBox::Ok); } else QMessageBox::information(NULL,"提示","注冊(cè)失敗",QMessageBox::Ok); file.close(); }
編譯運(yùn)行后,當(dāng)我們點(diǎn)擊生成注冊(cè)碼時(shí),則會(huì)顯示硬件信息通過(guò)Base64編碼的結(jié)果,如下所示:
一個(gè)簡(jiǎn)單的注冊(cè)機(jī)寫完以后,APP在加載運(yùn)行的時(shí)候需要加上以下邏輯:
#include"mainwindow.h" #include#defineARRAY_SIZE(x)(sizeof(x)/sizeof(x[0])) QStringgetMachineInfo(constQString&cmd) { QProcessp; p.start(cmd); p.waitForFinished(); QStringresult=QString::fromLocal8Bit(p.readAllStandardOutput()); QStringListlist=cmd.split(""); result=result.remove(list.last(),Qt::CaseInsensitive); result=result.replace(" ",""); result=result.replace(" ",""); result=result.simplified(); returnresult; } intmain(intargc,char*argv[]) { uint8_tRunFlag=0; QByteArrayDecodeStr; QStringCpuSerialNumber; QApplicationa(argc,argv); //1.獲取CPU序列號(hào) CpuSerialNumber=getMachineInfo("wmiccpugetprocessorid"); //2.打開注冊(cè)碼文件,讀取加密字符串并進(jìn)行匹配加密字符串 QFilefile("D:/Register.txt"); if(!file.open(QIODevice::ReadOnly)) { QMessageBox::warning(NULL,"Error","注冊(cè)碼不存在,請(qǐng)導(dǎo)入注冊(cè)碼!",QMessageBox::Yes); return-1; } else { //讀取文件所有的內(nèi)存 QByteArrayEncodeStr=file.readAll(); //將讀取的內(nèi)容進(jìn)行解碼 DecodeStr=fromBase64(EncodeStr); //將解碼的結(jié)果與當(dāng)前PC的CPU序列號(hào)進(jìn)行比較 QStringStr(DecodeStr); if(0==Str.compare(CpuSerialNumber)) RunFlag=1; } //3.如果匹配成功,運(yùn)行軟件 if(RunFlag) { MainWindoww; w.show(); returna.exec(); } else { QMessageBox::warning(NULL,"Error","注冊(cè)碼無(wú)效,請(qǐng)聯(lián)系廠商獲取注冊(cè)碼!",QMessageBox::Yes); return-1; } return0; }
實(shí)現(xiàn)注冊(cè)機(jī)更好的方案則可以直接將信息寫入注冊(cè)表,然后APP去注冊(cè)表中讀取相應(yīng)的內(nèi)容。關(guān)于硬件信息的加密和解密方式,用戶可以有其它的實(shí)現(xiàn)方法。
這里留一個(gè)問(wèn)題,如何將APP啟動(dòng)信息與其它平臺(tái)進(jìn)行關(guān)聯(lián)呢?例如Qt ARM端、Mac端、Android端?
審核編輯:湯梓紅
-
Window
+關(guān)注
關(guān)注
0文章
83瀏覽量
37614 -
上位機(jī)
+關(guān)注
關(guān)注
27文章
967瀏覽量
55782 -
Qt
+關(guān)注
關(guān)注
2文章
314瀏覽量
39074 -
注冊(cè)機(jī)
+關(guān)注
關(guān)注
9文章
55瀏覽量
23942
原文標(biāo)題:Qt上位機(jī)開發(fā)之如何讓自己的APP啟動(dòng)與硬件信息綁定(Win端)
文章出處:【微信號(hào):嵌入式應(yīng)用研究院,微信公眾號(hào):嵌入式應(yīng)用研究院】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
EtherCAT運(yùn)動(dòng)控制器上位機(jī)開發(fā)之Python+Qt(三):PDO配置與SDO讀寫

QT從零開始作單片機(jī)上位機(jī)-串口調(diào)試助手+波形顯示

基于QT的簡(jiǎn)單的上位機(jī)

QT篇QT上位機(jī)串口編程

QT|編寫一個(gè)簡(jiǎn)單的上位機(jī)

QT實(shí)現(xiàn)簡(jiǎn)單的上位機(jī)軟件

STM32+ESP8266連接電腦Qt網(wǎng)絡(luò)上位機(jī)——QT篇

基于Qt的簡(jiǎn)單arduino上位機(jī)

QT設(shè)計(jì)風(fēng)速儀上位機(jī)實(shí)例

USB3.0開發(fā)之bulkLoop上位機(jī)程序

STM32 IAP升級(jí)固件與上位機(jī)例程

QT上位機(jī)開發(fā)之串口助手(下)

Qt上位機(jī)開發(fā)實(shí)戰(zhàn)案例

EtherCAT運(yùn)動(dòng)控制器上位機(jī)之Python+Qt(一):鏈接與單軸運(yùn)動(dòng)

評(píng)論