65.9K
CodeProject 正在变化。 阅读更多。
Home

清空 Cookies 文件夹

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.14/5 (8投票s)

2004年10月22日

5分钟阅读

viewsIcon

114788

downloadIcon

824

用于清理 Cookie 文件夹的命令行实用程序。

引言

前几天我浏览一些文件夹时,偶然发现了 Cookie 文件夹。看到里面有数千个文件,有些甚至有近三年的历史,我简直震惊了。我以为 IE 的 cookie 相关设置一定有问题,于是检查了 IE 的属性,一切看起来都很正常。我点击了“删除 Cookies”按钮,然后收到了一个“是否删除“Internet 临时文件”文件夹中的所有 cookies?”的消息。我选择了“是”,然后去检查 Cookie 文件夹。它竟然完好无损!不过,其他所有临时文件都被删除了。这时,我不确定 Cookie 文件夹是不是一个特殊情况,或者是我遗漏了什么显而易见的东西(这种情况经常发生)。我在其他几台机器上尝试了同样的操作,结果却参差不齐。有些机器上的 Cookie 文件夹被清空了。有些机器上的文件夹则未被触动。

在我做 Web 开发的时候,我好像记得 Cookies 集合有一个 Expires 属性,用于设置 cookie 过期的日期。在我们弄清楚 cookies 是否按预期工作之前,我就离开了那家公司。也许我想错了,以为它们在 Expires 属性指示的日期过后会自动清理。相反,也许它只是一个指示,告诉网页 cookie 太旧而无法使用,需要创建一个新的。我欢迎就这个谜团提供任何意见。

话虽如此,我想写一篇关于如何自动清理 Cookie 文件夹中任何旧的/未使用的文件的文章。以下各节将简要讨论这项工作。请随意修改代码以适应您的需求(例如,更多的选项、更高的灵活性、更完善的错误检查)。

请注意,我写这篇文章/创建这个实用程序并不是为了取代 IE 内部的任何功能。这仅仅是为了解决 IE 在管理其 Cookie 文件夹方面似乎存在的不一致性。如果 IE 在清理您的 Cookie 文件夹方面没有任何问题,那么这篇文章不适合您。但是,如果您发现 IE 没有清理您的 Cookie 文件夹,那么您可能会觉得这篇文章很有帮助。请享用!

定位 Cookie 文件夹

那么,Cookie文件夹到底在哪里?最简单的方法是使用 SHGetFolderPath() 函数。

// call GetBuffer() once instead of potentially calling it twice below

CString strCookiesPath;
LPTSTR lpszPath = strCookiesPath.GetBuffer(MAX_PATH);

// where is the 'jar' of cookies?

HRESULT hResult = SHGetFolderPath(NULL, CSIDL_COOKIES, 
                                  NULL, SHGFP_TYPE_CURRENT, lpszPath);
if (FAILED(hResult))
    hResult = SHGetFolderPath(NULL, CSIDL_COOKIES, 
                              NULL, SHGFP_TYPE_DEFAULT, lpszPath);

strCookiesPath.ReleaseBuffer();

此时,strCookiesPath 应该包含类似“C:\Documents and Settings\<user>\Cookies”这样的内容。要开始搜索此文件夹,我们只需添加一个反斜杠和一对通配符即可开始!在 MFC 之前,我会使用以下代码来完成此操作:

char szPath[256] = "C:\Documents and Settings\<user>\Cookies";
if (szPath[strlen(szPath)] != '\\')
    strcat(szPath, "\\");

这奏效了,但当我 1993 年开始使用 MFC 时,我改用了 CString 对象。这导致了

strCookiesPath = "C:\Documents and Settings\<user>\Cookies";
if (strCookiesPath.Right(1) != "\\")
    strCookiesPath += "\\";

这稍微干净了一些,但随后出现了本地化问题。硬编码反斜杠字符可能会带来麻烦。这与 Right() 方法有关。在 DBCS 语言(例如日语)中,这是一个常见错误,因为如果字符串的最后一个字符是双字节的,并且尾字节是 0x5C(反斜杠的值),代码就会错误地认为反斜杠已存在(感谢 Michael Dunn)。为了解决这个问题,我使用了 PathAddBackslash(),例如:

// add a backslash if necessary

PathAddBackslash(strCookiesPath.GetBuffer(MAX_PATH));
strCookiesPath.ReleaseBuffer();

处理 Cookie 文件夹

现在我们的字符串包含一个尾随的反斜杠。现在我们可以搜索(或处理)Cookie 文件夹了。为此,我使用了 CFileFind 对象。由于本文的整个前提是查找在特定天数内未被访问过的 cookie,我们只需将 cookie 的上次访问日期与某个用户配置的日期(即截止日期)进行比较。如果 cookie 足够旧,它将被添加到稍后要删除或显示的 cookie 列表中。我正在为此使用 Michael Dunn 的 CShellFileOp 类。这是一个围绕 SHFileOperation() 函数的 nice wrapper。

CShellFileOp shfo;
CTime        dateFile,
             dateCutoff;
CFileFind    fileFind;

BOOL bFound = fileFind.FindFile(strCookiesPath + _T("*.*"));
while (TRUE == bFound)
{
    bFound = fileFind.FindNextFile();

    if (! fileFind.IsDirectory())
    {
        // if the file was last written to before the cutoff date,

        // add it to the list of files to be removed

        fileFind.GetLastWriteTime(dateFile);
        if (CTime(dateFile.GetTime()) < dateCutoff)
            shfo.AddSourceFile(fileFind.GetFilePath());
    }
}

现在我们有了一个 cookie 列表,可以将其删除,也可以输出到屏幕上(也许您想查看那些将要被删除的 cookie)。要显示 cookie,只需遍历列表即可。CShellFileOp 提供了一个方法 GetSourceFileList() 来访问此列表。

const CStringList   &listSourceFiles = shfo.GetSourceFileList();
POSITION            pos;
CString             strFilename;

pos = listSourceFiles.GetHeadPosition();
while (NULL != pos)
{
    strFilename = listSourceFiles.GetNext(pos);
    cout << (LPCTSTR) strFilename << endl;
}

但是,如果我们确实想删除 cookie,我们将为此使用 CShellFileOp::Go() 方法。有关如何使用此类的更多信息,包括如何将 cookie 移动到回收站而不是删除它们,请参阅 Michael 的页面。

计算截止日期

可以通过简单地构造一个 CTimeSpan 对象并从当前日期减去它来计算截止日期。例如,如果您想删除在过去 15 天内未被访问过的 cookie,您将指定一个截止日期:

dateCutoff = CTime::GetCurrentTime() - CTimeSpan(15, 0, 0, 0);

现在,如果 cookie 的上次访问日期晚于截止日期,它将被删除。

注释

使用这个恰当地命名为 **cookiemonster** 的实用程序,在当前状态下,支持五个命令行开关。这些开关是通过 Paul DiLascia 的 CCommandLineInfoEx 类处理的。以下是每个开关的摘要:

/days ## 自 cookie 上次访问以来的天数。
/list 显示将要被删除的 cookie。如果使用此选项,Cookie 不受影响。
/verbose 显示程序正在执行的详细信息。
/recycle 将 cookie 移动到回收站。如果使用了 **/list**,则忽略。
/? 显示帮助屏幕。

在命令提示符下(也可以是计划任务)执行 **cookiemonster /days 2 /verbose /recycle**,在我的机器上产生了以下结果:

Deleting cookies last accessed before 10/19/04.
Cookies will be moved to the Recycle Bin.
Deleting cookies from C:\Documents and Settings\davidc\Cookies.
File: davidc@arstechnica[2].txt.
...Date: 10/21/04
File: davidc@arvest[2].txt
...Date: 10/19/04
...Added
File: davidc@ask[2].txt
...Date: 10/20/04
File: davidc@bbc.co[1].txt
...Date: 10/19/04
...Added
File: davidc@cardeals[2].txt
...Date: 10/20/04
File: davidc@celebritytrivia[1].txt
...Date: 10/20/04
File: davidc@channelintelligence[2].txt
...Date: 10/21/04
<balance of output deleted for brevity>

请注意,列表添加了两个文件,而有五个文件未被添加,因为它们的上次访问日期比截止日期要新。

参考文献

© . All rights reserved.