在C#获取IE临时文件

大家知道,在我们访问一个网站的时候。系统会把这个网站上的图片,动画等内容全部缓存到Internet临时文件夹中。

我们可以通过 <Drives>:\Documents and Settings\<user>\Local Settings\Temporary Internet Files访问。但是可能我们都没有想到,里面的文件实际却不同于我们系统中其他的文件夹和文件的关系。

举例说明,我们在VS.net下写一个函数来返回指定文件夹中的文件夹和所有文件时,但我们把Internet临时文件夹的地址传进去时,系统只会返回一个文件,那就是desktop.ini(每个文件夹都有),还有一个隐藏的文件夹。所以这就证明了在临时文件夹中的文件并不是按照普通的文件夹与文件的方式存在的。

其实windows是把临时文件全部存在一个隐藏的文件夹中,这个文件夹是我们都看不到的,然后靠一个index.dat的索引把内容全部读出来回显给用户。

那我们怎么用程序来读取其中的内容呢? 因为这几天在帮同学完成他的毕业设计,所以研究了一下。 首先要引用一个user.dll,在系统文件夹中。然后利用它其中的一些函数就可以遍历整个文件夹,并获得其中每个文件的信息。

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr FindFirstUrlCacheEntry(
    [MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern,
    IntPtr lpFirstCacheEntryInfo,
    ref int lpdwFirstCacheEntryInfoBufferSize);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool FindNextUrlCacheEntry(
    IntPtr hEnumHandle,
    IntPtr lpNextCacheEntryInfo,
    ref int lpdwNextCacheEntryInfoBufferSize);

[DllImport("wininet.dll")]
public static extern bool FindCloseUrlCache(IntPtr hEnumHandle);

引入以上三个函数来遍历临时文件夹,然后再引用

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int FileTimeToSystemTime(
    IntPtr lpFileTime,
    IntPtr lpSystemTime);

用来把 FileTime时间格式转化成c#中的string类型,以便我们进一步操作。

主体程序如下:


#region 引入dll

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct INTERNET_CACHE_ENTRY_INFO
{
    public int dwStructSize;
    public IntPtr lpszSourceUrlName;
    public IntPtr lpszLocalFileName;
    public int CacheEntryType;
    public int dwUseCount;
    public int dwHitRate;
    public int dwSizeLow;
    public int dwSizeHigh;
    public FILETIME LastModifiedTime;
    public FILETIME ExpireTime;
    public FILETIME LastAccessTime;
    public FILETIME LastSyncTime;
    public IntPtr lpHeaderInfo;
    public int dwHeaderInfoSize;
    public IntPtr lpszFileExtension;
    public int dwExemptDelta;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SYSTEMTIME
{
    public short wYear;
    public short wMonth;
    public short wDayOfWeek;
    public short wDay;
    public short wHour;
    public short wMinute;
    public short wSecond;
    public short wMilliseconds;
}

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int FileTimeToSystemTime(
    IntPtr lpFileTime,
    IntPtr lpSystemTime);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr FindFirstUrlCacheEntry(
    [MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern,
    IntPtr lpFirstCacheEntryInfo,
    ref int lpdwFirstCacheEntryInfoBufferSize);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool FindNextUrlCacheEntry(
    IntPtr hEnumHandle,
    IntPtr lpNextCacheEntryInfo,
    ref int lpdwNextCacheEntryInfoBufferSize);

[DllImport("wininet.dll")]
public static extern bool FindCloseUrlCache(
    IntPtr hEnumHandle);

const int ERROR_NO_MORE_ITEMS = 259;

#endregion

#region FileTimeToSystemTime

private string FILETIMEtoDataTime(FILETIME time)
{
    IntPtr filetime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FILETIME)));
    IntPtr systime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SYSTEMTIME)));
    Marshal.StructureToPtr(time, filetime, true);
    FileTimeToSystemTime(filetime, systime);
    SYSTEMTIME st = (SYSTEMTIME)Marshal.PtrToStructure(systime, typeof(SYSTEMTIME));
    string Time = st.wYear.ToString() + "." + st.wMonth.ToString() + "." + st.wDay.ToString() + "." + st.wHour.ToString() + "." + st.wMinute.ToString() + "." + st.wSecond.ToString();
    return Time;
}

#endregion

#region 加载数据
private void FileOk_Click(object sender, System.EventArgs e)
{
    int nNeeded = 0, nBufSize;
    IntPtr buf;
    INTERNET_CACHE_ENTRY_INFO CacheItem;
    IntPtr hEnum;
    bool r;

    FindFirstUrlCacheEntry(null, IntPtr.Zero, ref nNeeded);

    if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
        return;

    nBufSize = nNeeded;
    buf = Marshal.AllocHGlobal(nBufSize);
    hEnum = FindFirstUrlCacheEntry(null, buf, ref nNeeded);
    while (true)
    {
        CacheItem = (INTERNET_CACHE_ENTRY_INFO)Marshal.PtrToStructure(buf,
            typeof(INTERNET_CACHE_ENTRY_INFO));

        string modifiedTime = FILETIMEtoDataTime(CacheItem.LastModifiedTime);
        string expireTime = FILETIMEtoDataTime(CacheItem.ExpireTime);
        string accessTime = FILETIMEtoDataTime(CacheItem.LastAccessTime);
        string syncTime = FILETIMEtoDataTime(CacheItem.LastSyncTime);

        #region 获得数据,存入数据库
        try
        {
            //此處遍歷CacheItem即可
            //例如
            string s = Marshal.PtrToStringAuto(CacheItem.lpszSourceUrlName);
        }
        catch
        {
            //異常處理
        }
        #endregion

        string s = Marshal.PtrToStringAuto(CacheItem.lpszSourceUrlName);

        nNeeded = nBufSize;
        r = FindNextUrlCacheEntry(hEnum, buf, ref nNeeded);

        if (!r && Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
            break;

        if (!r && nNeeded > nBufSize)
        {
            nBufSize = nNeeded;
            buf = Marshal.ReAllocHGlobal(buf, (IntPtr)nBufSize);
            FindNextUrlCacheEntry(hEnum, buf, ref nNeeded);
        }
    }
    MessageBox.Show("系统数据加载完毕!");
    Marshal.FreeHGlobal(buf);
}

#endregion
Contributors: FHL