编程语言:C++
类 别:(实用算法,其他)
主要功能:命令行查询IE和Explorer的打开文件记录并保存到文件(如果对方没有清除历史记录)
有的时候,我们想知道关心的人都在上什么网站?如果直接问不好意思怎么办?那只好自己去拿了.哈哈.
但是,一般来说,东西是在别人机子上的.我们能拿到的一般也是一个CMD一类的Shell.不能使用图形查看器,这时,却可以用一个命令行工具来得到我们想得到的一些信息.
基于类似的原因,我写了这个工具,但我在取之前,可是征求了对方的同意的.
// IEHView.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <atlbase.h>
#include <urlhist.h>
#include <shlguid.h>
#include <string>
#include <iostream>
#include <sstream>
#include <list>
#include <algorithm>
#include <fstream>

#include <ATLComTime.h>
#include <atlfile.h>

using namespace std;


class UrlItem


{
public:
UrlItem(LPCTSTR szUrl, LPCTSTR szTitle, LPFILETIME ftLastUpdated, LPFILETIME ftLastVisited)
: url(szUrl), update(*ftLastUpdated),visite(*ftLastVisited)

{
if(szTitle)

{
title = szTitle;
}
}

virtual ~UrlItem()

{}

public:
wstring url;
wstring title;
COleDateTime update;
COleDateTime visite;

};

class UrlItem_Compare

{
public:
bool operator()(const UrlItem& rl,const UrlItem& rr) const

{
return rl.visite > rr.visite;
}
};


typedef list<UrlItem> UrlItemList;

void GetUrlHistory(UrlItemList& urlHist);
void PrintUrlList(const UrlItemList& urList);
void SortUrlListByDate(UrlItemList& urlList);
void SaveToFile(const UrlItemList& urlList);

/**//*
打印帮助信息
*/
void ShowUsage(void);


/**//*
功能:解析命令行参数
*/
bool ParseCmdLine(int argc, _TCHAR* argv[]);




/**///////////////////////////////
// 全局变量

/**////////////////////////////////
wstring argOutput;
wstring argTimeRange; //20070212-20070212
wstring argKeyString;

COleDateTime dtTimeStart;
COleDateTime dtTimeEnd;


int _tmain(int argc, _TCHAR* argv[])


{
//解析命令行参数
if(!ParseCmdLine(argc,argv))
return 0;

locale loc(""),oldloc;
oldloc=wcout.imbue(loc);//设置以便输出中文


UrlItemList urlList;

wcout << _T("正在查询历史记录
");

//初始化COM环境
::CoInitialize(NULL);
//查询IE历史列表
GetUrlHistory(urlList);
//清理COM环境
::CoUninitialize();

wcout << _T("完成!") << endl << _T("共打到") << urlList.size() << _T("条记录!") << endl;

wcout << _T("正在按时间进行排序
");

//按时间排序
SortUrlListByDate(urlList);

wcout << _T("完成!") << endl ;

if(argOutput.length() > 0)

{
wcout << _T("正在保存文件
");
::SaveToFile(urlList);
wcout << _T("完成!") << endl ;
}
else

{
wcout << _T("结果是:") << endl;
//打印结果
PrintUrlList(urlList);
wcout << endl << _T("完成!") << endl ;
}

wcout.imbue(oldloc); //用完恢复

return 0;
}


/**//*
功能:解析命令行参数
*/
bool ParseCmdLine(int argc, _TCHAR* argv[])


{
if(argc > 1)

{
wstring* pArgv = NULL;
for(int i = 0; i < argc; ++i)

{
if(pArgv)

{
*pArgv = argv[i];
pArgv = NULL;
}
else

{
if(0 == ::_wcsicmp(argv[i],_T("-h")))

{
ShowUsage();
return false;
}
else if(0 == ::_wcsicmp(argv[i],_T("-r")))

{
pArgv = &argTimeRange;
}
else if(0 == ::_wcsicmp(argv[i],_T("-k")))

{
pArgv = &argKeyString;
}
else if(0 == ::_wcsicmp(argv[i],_T("-o")))

{
pArgv = &argOutput;
}
}
}

if(argTimeRange.length() > 0)

{
wstring::size_type pos = argTimeRange.find_first_of('-');
if(pos == wstring::npos)

{
if(argTimeRange.length() != 8)
return false;

wstring time = argTimeRange.substr(0,4) + _T("-") + argTimeRange.substr(4,2) + _T("-") + argTimeRange.substr(6,2);
if(!dtTimeStart.ParseDateTime(time.c_str()))
return false;

dtTimeEnd = dtTimeStart + COleDateTime(0,0,1,0,0,0);
}
else if(argTimeRange.length() == 8 || argTimeRange.length() == 9 || argTimeRange.length() == 17 )

{
wstring start = argTimeRange.substr(0,pos);
if(start.length() == 8)

{
wstring time = start.substr(0,4) + _T("-") + start.substr(4,2) + _T("-") + start.substr(6,2);

if(!dtTimeStart.ParseDateTime(time.c_str()))
return false;
}
else if(start.length() == 0)

{
dtTimeStart.SetDateTime(2000,1,1,0,0,0);
}
else

{
return false;
}

wstring end = argTimeRange.substr(pos + 1);
if(end.length() == 8)

{
wstring time = end.substr(0,4) + _T("-") + end.substr(4,2) + _T("-") + end.substr(6,2);
if(!dtTimeEnd.ParseDateTime(time.c_str()))
return false;
}
else if(end.length() == 0)

{
dtTimeEnd = COleDateTime::GetCurrentTime();
}
else

{
return false;
}

}
}

return true;
}
else

{
ShowUsage();
return false;
}
}

void GetUrlHistory(UrlItemList& urlHist)


{
//声明智能指针
CComPtr<IUrlHistoryStg> pUhs = NULL;

//创建对象
if(SUCCEEDED(pUhs.CoCreateInstance(CLSID_CUrlHistory)))

{
CComPtr<IEnumSTATURL> pEnum;
//开始枚举历史列表
if(SUCCEEDED(pUhs->EnumUrls(&pEnum)))

{
STATURL statUrl;
::ZeroMemory(&statUrl,sizeof(statUrl));
statUrl.cbSize = sizeof(STATURL);
statUrl.pwcsUrl = (LPWSTR)STATURL_QUERYFLAG_NOURL;
statUrl.pwcsTitle = (LPWSTR)STATURL_QUERYFLAG_NOTITLE ;
statUrl.dwFlags = STATURL_QUERYFLAG_NOURL;
ULONG celtFetched = 0;

//枚举URL
while(SUCCEEDED(pEnum->Next(1,&statUrl,&celtFetched)))

{
if(celtFetched == 0)
break;
if(!statUrl.pwcsUrl)
continue;

UrlItem urlItem(statUrl.pwcsUrl,statUrl.pwcsTitle,&statUrl.ftLastUpdated,&statUrl.ftLastVisited);
if(dtTimeStart <= urlItem.visite && dtTimeEnd >= urlItem.visite)

{
if(argKeyString.length() == 0)

{
//保存记录
urlHist.push_back(urlItem);
}
else if((urlItem.url.find_first_of(argKeyString) != wstring::npos)
|| (urlItem.title.find_first_of(argKeyString) != wstring::npos)
)

{
//保存记录
urlHist.push_back(urlItem);
}
}
//释放内存
::CoTaskMemFree(statUrl.pwcsTitle);
::CoTaskMemFree(statUrl.pwcsUrl);
}
}
}
}

void SortUrlListByDate(UrlItemList& urlList)


{
urlList.sort(UrlItem_Compare());
}

void PrintUrlList(const UrlItemList& urlList)


{
locale loc(""),oldloc;
oldloc=wcout.imbue(loc);//设置以便输出中文

for(UrlItemList::const_iterator iter = urlList.begin(); iter != urlList.end() ; ++iter)

{
wcout << (LPCTSTR)(iter->visite.Format(_T("%Y-%m-%d %H:%M:%S"))) << _T("\t") << iter->title << _T("(") << iter->url << _T(")") << endl;
if(wcout.bad())

{
wcout.clear();
wcout << endl;
}
}
wcout.imbue(oldloc); //用完恢复
}
void SaveToFile(const UrlItemList& urlList)


{
wofstream ofs(argOutput.c_str(),ios::app | ios::binary);
locale loc(""),oldloc;
oldloc=ofs.imbue(loc);//设置以便输出中文

for(UrlItemList::const_iterator iter = urlList.begin(); iter != urlList.end() ; ++iter)

{
ofs << (LPCTSTR)(iter->visite.Format(_T("%Y-%m-%d %H:%M:%S"))) << _T("\t") << iter->title.c_str() << _T("(") << iter->url.c_str() << _T(")") << endl;
if(ofs.bad())

{
ofs.clear();
ofs << endl;
}
}
ofs.imbue(oldloc); //用完恢复
}




/**//*
打印帮助信息
*/
void ShowUsage()


{
wcout << _T("coder: evlon 2007-5-15 v0.5") << endl
<< _T("data: 2007-5-15 v0.5") << endl
<< _T("version: v0.5") << endl
<< _T("usage: iehview -k http -r <20070512-20070512 | 20070512- | -20070512 | 20070512> -o result.log") << endl
<< _T("-k URL OR TITLE keyWord") << endl
<< _T("-o result file name") << endl
<< _T("-r date range:20070212-20070516") << endl;
}

好了.
这次我编译了程序,免得大家再次编译了.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述