C++获取浏览器浏览历史(兼容谷歌、IE、火狐)

我参考: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 谷歌 火狐 浏览器记录 代码我已经调试通过了。希望对大家有所帮助

猜你喜欢

转载自blog.csdn.net/u011569253/article/details/76177404