c++获取程序的最后使用时间

杀软的软件管家里面,卸载列表会显示出软件的最近使用时间,以帮助用户清晰的查看该软件的使用频次,那这个时间是怎么获取到的呢。其实系统在打开一个软件时基本都有记录打开时间,当然并不是每一个可执行程序都能得到这个时间。

我们可以从注册表和Prefetch文件夹中获取最近打开时间,下面的例子我会优先选择从注册表获取,然后从Prefetch文件夹中补充。注册表位置:HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\UserAssist,Prefetch文件夹位置:C:\Windows\Prefetch。

从注册表中获取需要特殊注意,注册表UserAssist下有很多子健,只有两个子健是用于记录程序打开时间的,并且xp系统和非xp系统这个两个子健是不同的。这个两个子健就是两个GUID值,xp系统为:”75048700-EF1F-11D0-9888-006097DEACF9″和”5E6AB780-7743-11CF-A12B-00AA004AE837″,非xp系统为:”F4E57C4B-2036-45F0-A9AB-443BCFE33D9F”和”CEBFF5CD-ACE2-4F4F-9178-9926F41749EA”。

下面将给出参考代码,代码仅供参考,因为使用了google base里面的一些方法,无法直接编译通过。

 static const wchar_t* guides_XP[] = {
   L"75048700-EF1F-11D0-9888-006097DEACF9",
   L"5E6AB780-7743-11CF-A12B-00AA004AE837"
 };

 static const wchar_t* guides_WIN7[] = {
   L"F4E57C4B-2036-45F0-A9AB-443BCFE33D9F",
   L"CEBFF5CD-ACE2-4F4F-9178-9926F41749EA"
 };

 base::string16 rot13(const base::string16 &input) const {
   base::string16 r = input;
   int i = r.length();
   while (i--) {
     if (r[i] >= L'A' && r[i] <= L'M' || r[i] >= L'a' && r[i] <= L'm') 
        r[i] = (char)((int)(r[i] + 13));     
     else if (r[i] >= L'N' && r[i] <= L'Z' || r[i] >= L'n' && r[i] <= L'z')
       r[i] = (char)((int)(r[i] - 13));
   }
   return r;
 }

 std::map user_assist_
 void GetUserAssistList() {
   user_assist_.clear();
   base::Time tNow = base::Time::Now();
   bool is_xp_system = base::win::GetVersion() ==   
   base::win::Version::VERSION_XP;
   for (const base::string16& guid : is_xp_system ? guides_XP : 
     guides_WIN7) {
     base::string16 path =          
       base::StringPrintf(L"SOFTWARE\Microsoft\Windows\CurrentVersion\
        Explorer\UserAssist\{%ls}\Count", guid.c_str());
     base::win::RegistryValueIterator  user_assistant_iter(HKEY_CURRENT_USER, path.c_str());
     for (; user_assistant_iter.Valid(); ++user_assistant_iter) {
       base::string16 rot13_name = user_assistant_iter.Name();
       base::string16 name = rot13(rot13_name);
   unsigned char* achData = (unsigned char*)user_assistant_iter.Value();   unsigned long long winDate = 0, noNano = 0;   time_t last_run_time;   // last start (long long)   for (int i = 67; i >= 60; i--)     winDate = (winDate <<= 8) + achData[i];   // convert nanosec. in unix seconds since epoch (1970)   // and in normal date   if (winDate) {     noNano = winDate / 10000000;     last_run_time = noNano - 11644473600;   }   user_assist_.insert(std::make_pair(name, (tNow - base::Time::FromTimeT(last_run_time)).InDays())); }
 }
 }
 int ComputeLastRun(base::FilePath path) {
   base::Time tRet;
   base::FileEnumerator file_iter(path, true, base::FileEnumerator::FILES, FILE_PATH_LITERAL(".exe"));   for (base::FilePath name = file_iter.Next(); !name.empty(); name = file_iter.Next()) {     base::Time time;     base::FileEnumerator prefetcher_iter(base::FilePath(L"C:\Windows\Prefetch"), false, base::FileEnumerator::FILES, base::ToUpperASCII(name.BaseName().value()) + L"");
     for (base::FilePath prefetcher = prefetcher_iter.Next(); !prefetcher.empty(); prefetcher = prefetcher_iter.Next()) {
       base::File file(prefetcher, base::File::FLAG_OPEN | base::File::FLAG_READ);
       if (file.IsValid()) {
         base::File::Info info;
         file.GetInfo(&info);
         if (time < info.last_modified)
           time = info.last_modified;
       }
     }
     if (tRet < time)
       tRet = time;
   }
   if (tRet.is_null())
     return -1;
   return (base::Time::Now() - tRet).InDays();
 }

 void TestLastRun() {
   int last_run = 0;          // 最近打开的天数
   base::string16 install_location = "c:\xx\";
   base::string16 exe_name = "xx.exe";
   base::string16 exe_path = install_location + exe_name;
   const auto& user_assist = user_assist_.find(exe_path);
   if (user_assist != user_assist_.end())
     last_run = user_assist->second;
   else {
     base::win::RegKey regPrefetch;
     if (regPrefetch.Open(HKEY_LOCAL_MACHINE, _T("SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters"), KEY_READ)
       == ERROR_SUCCESS) {
       DWORD dwEnablePrefetcher = 0;
       if (regPrefetch.ReadValueDW(_T("EnablePrefetcher"), &dwEnablePrefetcher) == ERROR_SUCCESS && (int((int)dwEnablePrefetcher) & 0x1) == 1)
         last_run = ComputeLastRun(base::FilePath(install_location));
     }
   }
 }

本文为@艺文笔记原创文章,转载请注明出处:https://www.xuwenyan.com/archives/159,非常感谢!
上一篇:  下一篇: