当我们发布商业软件时,为了获取更多的盈利,我们会设置用户使用软件的期限。比如我们给到用户的软件试用期是3个月,过期之后就无法使用了,需要向销售方支付费用,开发者给与授权之后才能继续使用。
对于软件开发者,就博主个人而言,我是非常乐意做这种事情的。博主整理了自己项目中使用的方法,在这里分享一下,也方便自己后期回顾。
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class BMachineControl
{
public:
BMachineControl();
QString getWMIHWInfo(int type);
QString getCPUID1();
QString getCPUID2();
QString getHDLogicalID();
QString getMac();
QString getCPUManID();
QString getInfo();
// 根据设备信息、日期、可使用月份生成key
QString getKey(QString machineinfo, QString ddMMyyyy, int months);
// 注册key
bool activeKey(QString key);
// 拷贝至文件
void copyToFile(QSettings* reg, bool magic = false);
// 无注册表信息则初始化并返回true, 否则直接返回false
bool initializeReg();
// 比较是否与文件一致
bool judgeFile();
// 判断日期是否被故意修改
bool judgeDate();
// 判断key,返回剩余天数,过期则为负
int judgeKey();
// 刷新 DT1
void refreshDT1();
private:
const QString kReg = "HKEY_CURRENT_USER\\Software\\Lenovo\\App";
const QString kKey = "K";
const QString kDateTime0 = "DT0";
const QString kDateTime1 = "DT1";
const QString kDateTime2 = "DT2";
const QString kMonths = "M";
const int kForever = 1000000;
const QList kValidity = {1, 3, 6, 12, kForever};
const QString kFile = "C:/ProgramData/Lenovo/app.dat";
};
这里用到了 QAxObject 和 QNetworkInterface,记得在pro中导入Qt模块
QT += network axcontainer
QString BMachineControl::getWMIHWInfo(int type)
{
/*
* 注意:qt调用wmi时,对查询语句要求很严格,所以like之类的句子务必精确才能有结果出来
*
* 1. 当前原生网卡地址
* SELECT MACAddress ...
*
* 2. 硬盘***
* SELECT PNPDeviceID ...
*
* 3. 获取主板***
* SELECT SerialNumber ...
*
* 4. 处理器ID
* SELECT ProcessorId ...
*
* 5. BIOS***
* SELECT SerialNumber ...
*
* 6. 主板型号
* SELECT Product ...
*/
QString hwInfo;
QStringList sqlCmd;
sqlCmd.clear();
sqlCmd << "SELECT MACAddress FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))";
sqlCmd << "SELECT PNPDeviceID FROM Win32_DiskDrive WHERE( PNPDeviceID IS NOT NULL) AND (MediaType LIKE 'Fixed%')";
sqlCmd << "SELECT SerialNumber FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)";
sqlCmd << "SELECT ProcessorId FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)";
sqlCmd << "SELECT SerialNumber FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)";
sqlCmd << "SELECT Product FROM Win32_BaseBoard WHERE (Product IS NOT NULL)";
QStringList columnName;
columnName.clear();
columnName << "MACAddress";
columnName << "PNPDeviceID";
columnName << "SerialNumber";
columnName << "ProcessorId";
columnName << "SerialNumber";
columnName << "Product";
QAxObject *objIWbemLocator = new QAxObject("WbemScripting.SWbemLocator");
QAxObject *objWMIService = objIWbemLocator->querySubObject("ConnectServer(QString&,QString&)",QString("."), QString("root\\cimv2"));
QString query;
if ( type < sqlCmd.size() ) {
query = sqlCmd.at(type);
}
QAxObject *objInterList = objWMIService->querySubObject("ExecQuery(QString&))", query);
QAxObject *enum1 = objInterList->querySubObject("_NewEnum");
IEnumVARIANT *enumInterface = 0;
enum1->queryInterface(IID_IEnumVARIANT, (void**)&enumInterface);
enumInterface->Reset();
for ( int i = 0; i < objInterList->dynamicCall("Count").toInt(); ++i )
{
VARIANT *theItem = (VARIANT*)malloc(sizeof(VARIANT));
if ( enumInterface->Next(1, theItem, NULL) != S_FALSE )
{
QAxObject *item = new QAxObject((IUnknown *)theItem->punkVal);
if (item) {
if ( typedynamicCall(tempConstChar).toString();
}
}
}
}
return hwInfo;
}
QString BMachineControl::getKey(QString machineinfo, QString ddMMyyyy, int months)
{
QString originalStr120;
if ( machineinfo.isEmpty() ) {
originalStr120 = QString("machineinfo") + ddMMyyyy + QString::number(months);
} else {
originalStr120 = machineinfo + ddMMyyyy + QString::number(months);
}
QCryptographicHash sha1(QCryptographicHash::Sha1);
QByteArray datagram(originalStr120.toLatin1());
for ( int i = 0; i != datagram.size(); ++i )
{
datagram[i] = datagram[i] ^ 'q' ^ 'y';
}
const char* tempConstChar = datagram.data();
sha1.addData(tempConstChar);
QString activeCode = sha1.result().toHex();
return activeCode;
}
#include "mainwindow.h"
#include
#include
#include "bmachinecontrol.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 读取注册表中设置的软件使用期限
BMachineControl m_machine;
if ( m_machine.initializeReg() ) {
QMessageBox::information(nullptr, "Error", "No key ! ", QMessageBox::Ok);
return 0;
}
if ( !m_machine.judgeFile() ) {
QMessageBox::information(nullptr, "Error", "File Corruption ! ", QMessageBox::Ok);
return 0;
}
if ( !m_machine.judgeDate() ) {
QMessageBox::information(nullptr, "Error", "Invalid Key ! 0 ", QMessageBox::Ok);
return 0;
}
int days = m_machine.judgeKey();
if ( days == -1 ) {
QMessageBox::information(nullptr, "Error", "Invalid Key ! -1 ", QMessageBox::Ok);
return 0;
} else if ( days == -2 ) {
QMessageBox::information(nullptr, "Error", "Invalid Key ! -2 ", QMessageBox::Ok);
return 0;
} else {
if (days <= 7) {
QMessageBox::information(nullptr, "Info", "Days Remaining: " + QString::number(days) + " ! ", QMessageBox::Ok);
}
}
m_machine.refreshDT1();
MainWindow w;
w.show();
return a.exec();
}
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓