受项目的需求,需要实现程序临时使用一段时间且25天后再次登录就不能再使用,基于VC++,使用的方法是通过读写注册表的首次登录时间和最近登录时间来实现记录天数,从而实现该功能。
void LimitLoginByReg()
{
char retKeyValFirst[500]{};//第一次登录时间
CString strTimeFirst{};
CTime TimeFirst{};
char retKeyValLast[500]{};//最近一次登录时间
CString strTimeLast{};
CTime TimeLast{};
CString strTimeNow{};//当前时间
CTime timetemp = CTime::GetCurrentTime();//获取时间长度
strTimeNow = timetemp.Format("%Y-%m-%d %H:%M:%S");
DWORD size = strTimeNow.GetLength() + 1;
unsigned char tmp[500]{};
CString tmpString = tmp;
HKEY hKEY;
DWORD type = REG_SZ;
CString path = "Software\\Local SPCS-3000 DCS\\SPCS-3000 DCS 系统管理程序\\Initialization";
//注册表项为HKEY_CURRENT_USER,注意这里要给KEY_ALL_ACCESS,才能对注册表同时进行读与写
long ret = ::RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_ALL_ACCESS, &hKEY);
if (ret != ERROR_SUCCESS) {
MessageBox("不能打开注册表!", "错误", MB_ICONERROR);
return;
}
//获取第一次登录时间
ret = ::RegQueryValueEx(hKEY,"LimitTimeFirst", NULL, &type, (LPBYTE)retKeyValFirst, &size);
if (ret != ERROR_SUCCESS) {
//处理首次登录
HKEY subhKey = NULL;
DWORD dwOptions = REG_OPTION_NON_VOLATILE;
DWORD dwDisposition;
RegCreateKeyEx(hKEY,"LimitTimeFirst" , 0, NULL, dwOptions, KEY_WRITE, NULL, &subhKey, &dwDisposition);
timetemp = CTime::GetCurrentTime();
CString date = timetemp.Format("%Y-%m-%d %H:%M:%S");
strcpy(retKeyValFirst, date);
ret = ::RegSetValueEx(hKEY, "LimitTimeFirst", NULL, type,(LPBYTE)retKeyValFirst, size);
}
strTimeFirst += retKeyValFirst;
//获取第二次登录时间
ret = ::RegQueryValueExA(hKEY, "LimitTimeLast", NULL, &type, (LPBYTE)retKeyValLast, &size);
if (ret != ERROR_SUCCESS) {
//处理首次登录
HKEY subhKey = NULL;
DWORD dwOptions = REG_OPTION_NON_VOLATILE;
DWORD dwDisposition;
RegCreateKeyEx(hKEY, "LimitTimeLast", 0, NULL, dwOptions, KEY_WRITE, NULL, &subhKey, &dwDisposition);
CTime time = CTime::GetCurrentTime();
CString date = time.Format("%Y-%m-%d %H:%M:%S");
strcpy(retKeyValLast, date);
int nlength = date.GetLength();
ret = ::RegSetValueEx(hKEY, "LimitTimeLast", NULL, type, (LPBYTE)retKeyValLast, size);
}
strTimeLast += retKeyValLast;
//这里使用VC++里面自带的计算时间差的类CTime
int nYear, nMonth, nDate, nHour, nMin, nSec;
sscanf(strTimeFirst,"%d-%d-%d %d:%d:%d", &nYear, &nMonth, &nDate, &nHour, &nMin, &nSec);
CTime t1(nYear, nMonth, nDate, nHour, nMin, nSec);
sscanf(strTimeLast, "%d-%d-%d %d:%d:%d", &nYear, &nMonth, &nDate, &nHour, &nMin, &nSec);
CTime t2(nYear, nMonth, nDate, nHour, nMin, nSec);
CTimeSpan tmSpan = t2 - t1;
int idays = tmSpan.GetDays();
if (idays >= 25)
exit(0);
sscanf(strTimeNow, "%d-%d-%d %d:%d:%d", &nYear, &nMonth, &nDate, &nHour, &nMin, &nSec);
CTime t3(nYear, nMonth, nDate, nHour, nMin, nSec);
tmSpan = t3 - t2;
idays = tmSpan.GetSeconds();
if (idays >= 0) {
//把最近一次登录时间写入注册表
char retKeyValNow[1000]{};//当前时间
strcpy(retKeyValNow, strTimeNow);
::RegSetValueEx(hKEY, "LimitTimeLast", NULL, type, (LPBYTE)retKeyValNow, size);
}
else
exit(0);//若是通过修改系统时间则不能登录
::RegCloseKey(hKEY);
}
运行的结果如下图所示,可以看到最后的结果是以二进制显示的,如果你想让这不能修改,你可以对时间进行加密再写入注册表。读取解密再转换为时间。