我参考:http://blog.csdn.net/anda0109/article/details/41385241 贴写但是发现很多问题,我就在这个类的基础上重新写的代码,来完成获取浏览器记录,代码如下:
#pragma once enum HistorySource { HistorySource_IE, HistorySource_Chrome, HistorySource_FireFox, }; struct BrowsData { public: // 网址 CString strURL; // last_visit_time CString strTime; // 对应网址访问次数 unsigned int nCount; // 重载<操作符 bool operator < (const BrowsData &m)const { return nCount > m.nCount; } HistorySource source; }; class BrowseHistory { public: BrowseHistory(); ~BrowseHistory(); // 获取浏览器历史记录 void ReadHistroy(void); void GetHistory(std::map<HistorySource, std::vector<BrowsData>>& vecHistory); private: void readIEHistory(); void readChromeHistory(); void readFireFoxHistory(); void getChromeVisitUrlTime(UINT64 milliSeconds, CString& strTime); void getFirefoxVisitUrlTime(UINT64 milliSeconds, CString& strTime); bool isRunning(CString exe); void convertUtf8ToGBK(CStringA &strUtf8); void urlFiltrateIE(LPWSTR lpszSourceUrlName, FILETIME visitTime); // Chrome网址过滤,如只取网址com前边的 void urlFiltrateChrome(CString strUrlName, UINT64 visitTime, int iCount); // Firefox网址过滤,如只去网址com前边的 void urlFiltrateFirefox(CString strUrlName, UINT64 visitTime, int iCount); private: std::map<HistorySource, std::vector<BrowsData>> m_BrowsHistroyMap;//我把不同浏览器记录放到不同的链表里去 bool m_bStatus = false; int m_timeZone = 0; };
#include "stdafx.h" #include "BrowseHistory.h" #include <wininet.h> #include <io.h> #include <tlhelp32.h> #include "CppSQLite3.h" #include "PcTime.h" BrowseHistory::BrowseHistory() { TIME_ZONE_INFORMATION timeZone = { 0 }; DWORD dwRet = GetTimeZoneInformation(&timeZone); if (dwRet == ERROR_SUCCESS) { m_timeZone = timeZone.Bias / -60; } } BrowseHistory::~BrowseHistory() { } void BrowseHistory::ReadHistroy(void) { readIEHistory(); readChromeHistory(); readFireFoxHistory(); } void BrowseHistory::GetHistory(std::map<HistorySource, std::vector<BrowsData>>& vecHistory) { vecHistory = m_BrowsHistroyMap; } void BrowseHistory::readIEHistory() { // 用来支持多次调用 m_bStatus = false; m_BrowsHistroyMap.clear(); // 获取IE的历史记录 HANDLE hCacheEnumHandle = NULL; LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL; DWORD dwSize = 4096; BrowsData browsDate; browsDate.nCount = 0; lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize]; lpCacheEntry->dwStructSize = dwSize; hCacheEnumHandle = FindFirstUrlCacheEntry(_T("visited:"), lpCacheEntry, &dwSize); if (hCacheEnumHandle != NULL) { urlFiltrateIE(lpCacheEntry->lpszSourceUrlName, lpCacheEntry->LastAccessTime); } else { switch (GetLastError()) { case ERROR_INSUFFICIENT_BUFFER: lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize]; lpCacheEntry->dwStructSize = dwSize; hCacheEnumHandle = FindFirstUrlCacheEntry(_T("visited:"), lpCacheEntry, &dwSize); if (hCacheEnumHandle != NULL) { urlFiltrateIE(lpCacheEntry->lpszSourceUrlName, lpCacheEntry->LastAccessTime); break; } else { // 查找失败 return; } default: { LOG_INFO(L"GetLastError : %d", GetLastError()); FindCloseUrlCache(hCacheEnumHandle); } } } bool bSign = true; do { if (FindNextUrlCacheEntry(hCacheEnumHandle, lpCacheEntry, &dwSize)) { urlFiltrateIE(lpCacheEntry->lpszSourceUrlName, lpCacheEntry->LastAccessTime); } else { switch (GetLastError()) { case ERROR_INSUFFICIENT_BUFFER: lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize]; memset(lpCacheEntry, 0, dwSize); lpCacheEntry->dwStructSize = dwSize; if (FindNextUrlCacheEntry(hCacheEnumHandle, lpCacheEntry, &dwSize)) { urlFiltrateIE(lpCacheEntry->lpszSourceUrlName, lpCacheEntry->LastAccessTime); break; } else { FindCloseUrlCache(hCacheEnumHandle); bSign = false; break; } break; case ERROR_NO_MORE_ITEMS: FindCloseUrlCache(hCacheEnumHandle); bSign = false; break; default: FindCloseUrlCache(hCacheEnumHandle); bSign = false; break; } } } while (bSign); } void BrowseHistory::readChromeHistory() { // 获取谷歌浏览器的历史记录 char path[MAX_PATH]; ::SHGetSpecialFolderPathA(NULL, path, CSIDL_LOCAL_APPDATA, FALSE); strcat_s(path, "\\google\\chrome\\User Data\\default\\History"); if (PathFileExistsA(path)) { // 谷歌浏览器正在运行,强制关闭;关闭后才能得到谷歌浏览器的历史记录 if (!isRunning(_T("chrome.exe"))) { try { CppSQLite3DB db; CppSQLite3Query query; db.open(path); query = db.execQuery("select * from urls where visit_count>1"); while (!query.eof()) { CStringA utf8url; utf8url = query.fieldValue("url"); sqlite_int64 visitTime = query.getInt64Field("last_visit_time"); convertUtf8ToGBK(utf8url); int icount = query.getIntField("visit_count"); urlFiltrateChrome((CString)utf8url, (UINT64)visitTime, icount); query.nextRow(); } db.close(); } catch (CppSQLite3Exception& e) { return; } } } } void BrowseHistory::getChromeVisitUrlTime(UINT64 milliSeconds, CString & strTime) { CPcTime timeBase; if (CPcTime::FromString(L"1601-01-01", timeBase)) { CPcTimeDelta delta = CPcTimeDelta::FromMicroseconds(milliSeconds); CPcTime time = timeBase + delta; TDateTime localTime = time.ToLocalDateTime(); localTime.hour += m_timeZone; strTime = localTime.ToString(YYYYMMDDHHmmss); } } void BrowseHistory::getFirefoxVisitUrlTime(UINT64 milliSeconds, CString& strTime) { struct tm *local; time_t t; t = milliSeconds/1000000; local = localtime(&t); strTime.Format(L"%d-%02d-%02d %02d:%02d:%02d", local->tm_year + 1900, local->tm_mon + 1, local->tm_mday, local->tm_hour, local->tm_min, local->tm_sec); } void BrowseHistory::readFireFoxHistory() { bool isFind = false; TCHAR strPath[MAX_PATH] = { 0 }; char path[MAX_PATH]; // 获取火狐浏览器的历史记录 ::SHGetSpecialFolderPathA(NULL, path, CSIDL_LOCAL_APPDATA, FALSE); std::string strDestPath(path); strDestPath.replace(strDestPath.length() - 5, strDestPath.length(), "Roaming"); strDestPath += "\\Mozilla\\Firefox\\Profiles\\"; //文件句柄 long hFile = 0; //文件信息 struct _finddata_t fileinfo; std::string p; if ((hFile = _findfirst(p.assign(strDestPath).append("\\*").c_str(), &fileinfo)) != -1) { do { if ((fileinfo.attrib & _A_SUBDIR)) { if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) { std::string str = fileinfo.name; if (str.find("default") != -1) { strDestPath += str; _findclose(hFile); isFind = true; break; } } } } while (_findnext(hFile, &fileinfo) == 0); } if (isFind) { strDestPath += "\\places.sqlite"; if (PathFileExistsA((LPCSTR)strDestPath.c_str())) { if (!isRunning(_T("firefox.exe"))) { try { CppSQLite3DB db; CppSQLite3Query query; db.open(strDestPath.c_str()); query = db.execQuery("select * from moz_places where visit_count>0"); while (!query.eof()) { CStringA utf8url; utf8url = query.fieldValue("url"); sqlite_int64 visitTime = query.getInt64Field("last_visit_date"); convertUtf8ToGBK(utf8url); int icount = query.getIntField("visit_count"); urlFiltrateFirefox((CString)utf8url, (UINT64)visitTime, icount); query.nextRow(); } db.close(); } catch (CppSQLite3Exception& e) { return; } } } } } bool BrowseHistory::isRunning(CString exe) { PROCESSENTRY32 pe32; HANDLE hprocess; hprocess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hprocess, &pe32)) { do { HANDLE h_id; h_id = OpenProcess(PROCESS_TERMINATE, false, pe32.th32ProcessID); CString exefile; exefile = pe32.szExeFile; exefile.MakeLower(); exe.MakeLower(); if (exefile == exe) { return true; } } while (Process32Next(hprocess, &pe32)); } return false; } void BrowseHistory::convertUtf8ToGBK(CStringA & strUtf8) { int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)strUtf8, -1, NULL, 0); unsigned short * wszGBK = new unsigned short[len + 1]; memset(wszGBK, 0, len * 2 + 2); MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)strUtf8, -1, (LPWSTR)wszGBK, len); len = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wszGBK, -1, NULL, 0, NULL, NULL); char *szGBK = new char[len + 1]; memset(szGBK, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wszGBK, -1, szGBK, len, NULL, NULL); strUtf8 = szGBK; delete[] szGBK; delete[] wszGBK; } void BrowseHistory::urlFiltrateIE(LPWSTR lpszSourceUrlName, FILETIME visitTime) { BrowsData browsDate; browsDate.nCount = 0; CString strTemp(lpszSourceUrlName); std::vector<BrowsData>::iterator iter; // 排除非必要的网址 if (strTemp.Find(_T("@http")) != -1) { strTemp.Delete(0, strTemp.Find(_T("@https")) >= 0 ? strTemp.Find(_T("@http")) + 9 : strTemp.Find(_T("@http")) + 8); // 排除非必要网址 if (strTemp.Find(_T(":")) != -1) { return; } SYSTEMTIME time; if (FileTimeToSystemTime(&visitTime, &time)) { time.wHour += m_timeZone; browsDate.strTime.Format(L"%04u-%02u-%02u %02u:%02u:%02u", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond); } int nIndex = strTemp.Find(_T("/")); std::map<HistorySource, std::vector<BrowsData>>::iterator itr = m_BrowsHistroyMap.find(HistorySource_IE); if (itr != m_BrowsHistroyMap.end()) { std::vector<BrowsData>::iterator iter; for (iter = itr->second.begin(); iter != itr->second.end(); iter++) { if (iter->strURL == strTemp.Left(nIndex)) { iter->nCount += 1; return; } } if (nIndex != -1) { browsDate.strURL = strTemp.Left(nIndex); } else { browsDate.strURL = strTemp; } browsDate.nCount = 1; browsDate.source = HistorySource_IE; itr->second.push_back(browsDate); } else { std::vector<BrowsData> vinfo; if (nIndex != -1) { browsDate.strURL = strTemp.Left(nIndex); } else { browsDate.strURL = strTemp; } browsDate.nCount = 1; browsDate.source = HistorySource_IE; vinfo.push_back(browsDate); m_BrowsHistroyMap.insert(std::pair<HistorySource, std::vector<BrowsData>>(HistorySource_IE, vinfo)); } } } void BrowseHistory::urlFiltrateChrome(CString strUrlName, UINT64 visitTime, int iCount) { // 删除开始的"https://" if (strUrlName.Find(_T("https://")) != -1) { strUrlName.Delete(0, 8); } else if (strUrlName.Find(_T("http://")) != -1) { strUrlName.Delete(0, 7); } int nIndex = strUrlName.Find(_T("/")); BrowsData browsDate; browsDate.nCount = 0; std::map<HistorySource, std::vector<BrowsData>>::iterator itr= m_BrowsHistroyMap.find(HistorySource_Chrome); if (itr != m_BrowsHistroyMap.end()) { std::vector<BrowsData>::iterator iter; for (iter = itr->second.begin(); iter != itr->second.end(); iter++) { if (iter->strURL == strUrlName.Left(nIndex)) { iter->nCount += iCount; return; } } if (nIndex != -1) { browsDate.strURL = strUrlName.Left(nIndex); } else { browsDate.strURL = strUrlName; } browsDate.nCount = iCount; browsDate.source = HistorySource_Chrome; if (visitTime > 0) { getChromeVisitUrlTime(visitTime, browsDate.strTime); } itr->second.push_back(browsDate); } else { std::vector<BrowsData> vinfo; if (nIndex != -1) { browsDate.strURL = strUrlName.Left(nIndex); } else { browsDate.strURL = strUrlName; } if (visitTime > 0) { getChromeVisitUrlTime(visitTime, browsDate.strTime); } browsDate.nCount = iCount; browsDate.source = HistorySource_Chrome; vinfo.push_back(browsDate); m_BrowsHistroyMap.insert(std::pair<HistorySource, std::vector<BrowsData>>(HistorySource_Chrome, vinfo)); } } void BrowseHistory::urlFiltrateFirefox(CString strUrlName, UINT64 visitTime, int iCount) { if (strUrlName.Find(_T("https://")) != -1) { strUrlName.Delete(0, 8); } else if (strUrlName.Find(_T("http://")) != -1) { strUrlName.Delete(0, 7); } int nIndex = strUrlName.Find(_T("/")); BrowsData browsDate; browsDate.nCount = 0; std::map<HistorySource, std::vector<BrowsData>>::iterator itr = m_BrowsHistroyMap.find(HistorySource_FireFox); if (itr != m_BrowsHistroyMap.end()) { std::vector<BrowsData>::iterator iter; if (nIndex != -1) { for (iter = itr->second.begin(); iter != itr->second.end(); iter++) { CString url =strUrlName.Left(nIndex); if (iter->strURL == url) { iter->nCount += iCount; return; } } browsDate.strURL = strUrlName.Left(nIndex); } else { for (iter = itr->second.begin(); iter != itr->second.end(); iter++) { if (iter->strURL == strUrlName) { iter->nCount += iCount; return; } } browsDate.strURL = strUrlName; } browsDate.nCount = iCount; browsDate.source = HistorySource_FireFox; if (visitTime > 0) { getFirefoxVisitUrlTime(visitTime, browsDate.strTime); } itr->second.push_back(browsDate); } else { std::vector<BrowsData> vinfo; if (nIndex != -1) { browsDate.strURL = strUrlName.Left(nIndex); } else { browsDate.strURL = strUrlName; } if (visitTime > 0) { getFirefoxVisitUrlTime(visitTime, browsDate.strTime); } browsDate.nCount = iCount; browsDate.source = HistorySource_FireFox; vinfo.push_back(browsDate); m_BrowsHistroyMap.insert(std::pair<HistorySource, std::vector<BrowsData>>(HistorySource_FireFox, vinfo)); } }这样就可以获取到ie 谷歌 火狐 浏览器记录 代码我已经调试通过了。希望对大家有所帮助