2010-01-08 56 views
2

我有這段代碼清除C#WebBrowser控件中的緩存。問題在於它也會清除cookie。我似乎是整個互聯網上唯一不想要的人。C#WebBrowser控件:清除緩存但不清除Cookie

我需要維護cookie,但要扔掉緩存。

特別感興趣的是這一行:

const int CACHEGROUP_SEARCH_ALL = 0x0;

似乎確定哪些「緩存組」(赫克無論那些)被清洗出來,我希望餅乾緩存組我可以跳過。然而,試圖找到任何有關這方面的信息只會產生令人頭疼的頭痛。

此代碼最初從MSDN文章拍攝,但它甚至沒有提及餅乾或高速緩存組。

您可以在代碼頂部看到MSDN文章。

/** 
* Modified from code originally found here: http://support.microsoft.com/kb/326201 
**/ 

using System; 
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.ComTypes; 
using System.Diagnostics; 

namespace Goop 
{ 
    // Class for deleting the cache. 
    public static class WebBrowserHelper 
    { 
     #region Definitions/DLL Imports 
     // For PInvoke: Contains information about an entry in the Internet cache 
     [StructLayout(LayoutKind.Explicit, Size = 80)] 
     public struct INTERNET_CACHE_ENTRY_INFOA 
     { 
      [FieldOffset(0)] 
      public uint dwStructSize; 
      [FieldOffset(4)] 
      public IntPtr lpszSourceUrlName; 
      [FieldOffset(8)] 
      public IntPtr lpszLocalFileName; 
      [FieldOffset(12)] 
      public uint CacheEntryType; 
      [FieldOffset(16)] 
      public uint dwUseCount; 
      [FieldOffset(20)] 
      public uint dwHitRate; 
      [FieldOffset(24)] 
      public uint dwSizeLow; 
      [FieldOffset(28)] 
      public uint dwSizeHigh; 
      [FieldOffset(32)] 
      public System.Runtime.InteropServices.ComTypes.FILETIME LastModifiedTime; 
      [FieldOffset(40)] 
      public System.Runtime.InteropServices.ComTypes.FILETIME ExpireTime; 
      [FieldOffset(48)] 
      public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime; 
      [FieldOffset(56)] 
      public System.Runtime.InteropServices.ComTypes.FILETIME LastSyncTime; 
      [FieldOffset(64)] 
      public IntPtr lpHeaderInfo; 
      [FieldOffset(68)] 
      public uint dwHeaderInfoSize; 
      [FieldOffset(72)] 
      public IntPtr lpszFileExtension; 
      [FieldOffset(76)] 
      public uint dwReserved; 
      [FieldOffset(76)] 
      public uint dwExemptDelta; 
     } 
     // For PInvoke: Initiates the enumeration of the cache groups in the Internet cache 
     [DllImport(@"wininet", 
      SetLastError = true, 
      CharSet = CharSet.Auto, 
      EntryPoint = "FindFirstUrlCacheGroup", 
      CallingConvention = CallingConvention.StdCall)] 
     public static extern IntPtr FindFirstUrlCacheGroup(
      int dwFlags, 
      int dwFilter, 
      IntPtr lpSearchCondition, 
      int dwSearchCondition, 
      ref long lpGroupId, 
      IntPtr lpReserved); 
     // For PInvoke: Retrieves the next cache group in a cache group enumeration 
     [DllImport(@"wininet", 
      SetLastError = true, 
      CharSet = CharSet.Auto, 
      EntryPoint = "FindNextUrlCacheGroup", 
      CallingConvention = CallingConvention.StdCall)] 
     public static extern bool FindNextUrlCacheGroup(
      IntPtr hFind, 
      ref long lpGroupId, 
      IntPtr lpReserved); 
     // For PInvoke: Releases the specified GROUPID and any associated state in the cache index file 
     [DllImport(@"wininet", 
      SetLastError = true, 
      CharSet = CharSet.Auto, 
      EntryPoint = "DeleteUrlCacheGroup", 
      CallingConvention = CallingConvention.StdCall)] 
     public static extern bool DeleteUrlCacheGroup(
      long GroupId, 
      int dwFlags, 
      IntPtr lpReserved); 
     // For PInvoke: Begins the enumeration of the Internet cache 
     [DllImport(@"wininet", 
      SetLastError = true, 
      CharSet = CharSet.Auto, 
      EntryPoint = "FindFirstUrlCacheEntryA", 
      CallingConvention = CallingConvention.StdCall)] 
     public static extern IntPtr FindFirstUrlCacheEntry(
      [MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern, 
      IntPtr lpFirstCacheEntryInfo, 
      ref int lpdwFirstCacheEntryInfoBufferSize); 
     // For PInvoke: Retrieves the next entry in the Internet cache 
     [DllImport(@"wininet", 
      SetLastError = true, 
      CharSet = CharSet.Auto, 
      EntryPoint = "FindNextUrlCacheEntryA", 
      CallingConvention = CallingConvention.StdCall)] 
     public static extern bool FindNextUrlCacheEntry(
      IntPtr hFind, 
      IntPtr lpNextCacheEntryInfo, 
      ref int lpdwNextCacheEntryInfoBufferSize); 
     // For PInvoke: Removes the file that is associated with the source name from the cache, if the file exists 
     [DllImport(@"wininet", 
      SetLastError = true, 
      CharSet = CharSet.Auto, 
      EntryPoint = "DeleteUrlCacheEntryA", 
      CallingConvention = CallingConvention.StdCall)] 
     public static extern bool DeleteUrlCacheEntry(
      IntPtr lpszUrlName); 
     #endregion 
     #region Public Static Functions 
     /// 
     /// Clears the cache of the web browser 
     /// 
     public static void ClearCache() 
     { 
      // Indicates that all of the cache groups in the user's system should be enumerated 
      const int CACHEGROUP_SEARCH_ALL = 0x0; 
      // Indicates that all the cache entries that are associated with the cache group 
      // should be deleted, unless the entry belongs to another cache group. 
      const int CACHEGROUP_FLAG_FLUSHURL_ONDELETE = 0x2; 
      // File not found. 
      const int ERROR_FILE_NOT_FOUND = 0x2; 
      // No more items have been found. 
      const int ERROR_NO_MORE_ITEMS = 259; 
      // Pointer to a GROUPID variable 
      long groupId = 0; 
      // Local variables 
      int cacheEntryInfoBufferSizeInitial = 0; 
      int cacheEntryInfoBufferSize = 0; 
      IntPtr cacheEntryInfoBuffer = IntPtr.Zero; 
      INTERNET_CACHE_ENTRY_INFOA internetCacheEntry; 
      IntPtr enumHandle = IntPtr.Zero; 
      bool returnValue = false; 
      // Delete the groups first. 
      // Groups may not always exist on the system. 
      // For more information, visit the following Microsoft Web site: 
      // http://msdn.microsoft.com/library/?url=/workshop/networking/wininet/overview/cache.asp 
      // By default, a URL does not belong to any group. Therefore, that cache may become 
      // empty even when the CacheGroup APIs are not used because the existing URL does not belong to any group. 
      enumHandle = FindFirstUrlCacheGroup(0, CACHEGROUP_SEARCH_ALL, IntPtr.Zero, 0, ref groupId, IntPtr.Zero); 
      // If there are no items in the Cache, you are finished. 
      if (enumHandle != IntPtr.Zero && ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error()) 
      { 
       return; 
      } 
      // Loop through Cache Group, and then delete entries. 
      while (true) 
      { 
       if (ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error() || ERROR_FILE_NOT_FOUND == Marshal.GetLastWin32Error()) 
       { 
        break; 
       } 
       // Delete a particular Cache Group. 
       returnValue = DeleteUrlCacheGroup(groupId, CACHEGROUP_FLAG_FLUSHURL_ONDELETE, IntPtr.Zero); 
       if (!returnValue && ERROR_FILE_NOT_FOUND == Marshal.GetLastWin32Error()) 
       { 
        returnValue = FindNextUrlCacheGroup(enumHandle, ref groupId, IntPtr.Zero); 
       } 
       if (!returnValue && (ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error() || ERROR_FILE_NOT_FOUND == Marshal.GetLastWin32Error())) 
        break; 
      } 
      // Start to delete URLs that do not belong to any group. 
      enumHandle = FindFirstUrlCacheEntry(null, IntPtr.Zero, ref cacheEntryInfoBufferSizeInitial); 
      if (enumHandle != IntPtr.Zero && ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error()) 
      { 
       return; 
      } 
      cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial; 
      cacheEntryInfoBuffer = Marshal.AllocHGlobal(cacheEntryInfoBufferSize); 
      enumHandle = FindFirstUrlCacheEntry(null, cacheEntryInfoBuffer, ref cacheEntryInfoBufferSizeInitial); 
      while (true) 
      { 
       internetCacheEntry = (INTERNET_CACHE_ENTRY_INFOA)Marshal.PtrToStructure(cacheEntryInfoBuffer, typeof(INTERNET_CACHE_ENTRY_INFOA)); 
       if (ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error() || cacheEntryInfoBufferSize == 0) 
       { 
        break; 
       } 
       cacheEntryInfoBufferSizeInitial = cacheEntryInfoBufferSize; 
       returnValue = DeleteUrlCacheEntry(internetCacheEntry.lpszSourceUrlName); 
       if (!returnValue) 
       { 
        returnValue = FindNextUrlCacheEntry(enumHandle, cacheEntryInfoBuffer, ref cacheEntryInfoBufferSizeInitial); 
       } 
       if (!returnValue && ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error()) 
       { 
        break; 
       } 
       if (!returnValue && cacheEntryInfoBufferSizeInitial > cacheEntryInfoBufferSize) 
       { 
        cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial; 
        cacheEntryInfoBuffer = Marshal.ReAllocHGlobal(cacheEntryInfoBuffer, (IntPtr)cacheEntryInfoBufferSize); 
        returnValue = FindNextUrlCacheEntry(enumHandle, cacheEntryInfoBuffer, ref cacheEntryInfoBufferSizeInitial); 
       } 
      } 
      Marshal.FreeHGlobal(cacheEntryInfoBuffer); 
     } 
     #endregion 
    } 
} 
 

任何和所有的幫助非常感謝。

+0

老總岡納森,關於這個問題的任何更新? WebBrowserHelper的代碼中的任何更改? – Kiquenet 2010-07-20 18:46:45

+0

@alhambraeidos:不,我最終運行了一個控制檯命令。大約半秒鐘之後,我把焦點從我的窗戶上取下來,但是對於我的目的來說沒關係。 – Teekin 2010-07-30 16:09:10

回答

3

檢查文檔爲INTERNET_CACHE_ENTRY_INFOA,尤其是描述CacheEntryType部分:

位掩碼錶示緩存 條目及其屬性的類型。條目類型包括:歷史條目 (URLHISTORY_CACHE_ENTRY),曲奇 條目(COOKIE_CACHE_ENTRY)和 正常緩存內容 (NORMAL_CACHE_ENTRY)。

這個成員可以是零個或多個 以下屬性標誌,和高速緩存 下列種類的標誌。

下面,你得到的條目類型的列表,一個是

COOKIE_CACHE_ENTRY

這似乎是要檢查你拋開一切離開之前呢?

+0

由於時間限制,我最終通過命令行來完成它,但是你的帖子讓我走上了賽道。謝謝! – Teekin 2010-01-11 19:11:40

1

條件應該在下面,我用VB。

Dim icei As INTERNET_CACHE_ENTRY_INFO 

...... 

If (icei.CacheEntryType And COOKIE_CACHE_ENTRY) <> COOKIE_CACHE_ENTRY And _ 
       (icei.CacheEntryType And NORMAL_CACHE_ENTRY) = NORMAL_CACHE_ENTRY Then 

     cachefile = GetStrFromPtrA(icei.lpszSourceUrlName) 

     Call DeleteUrlCacheEntry(cachefile) 

End If 

這將刪除緩存的文件,但仍保留cookie。

0

添加下面的頁面

<meta http-equiv="cache-control" content="no-cache"> 
3

FiddlerCore meta標籤公開與正是簽名的方法。 ClearCacheItems(布爾clearCookies,布爾clearFiles)。

--RANT--

人人都知識庫文章鏈接到具有中有許多錯誤(在其他答案的源代碼來自),我已經浪費了〜2天試圖得到它的工作在所有必要的設置。它是複製粘貼在互聯網上,並且有許多基於操作系統和IE版本報告的錯誤。

Fiddler最初是由Microsoft員工編寫的,並且由FiddlerCore.dll提供支持。 Teleid(當前所有者/維護者/賣家)的Fiddler仍然免費更新,維護和放棄FiddlerCore。如果你不想添加對FiddlerCore的引用,你可以反彙編DLL,並且它顯示了正確的方式來調用所有這些可怕的記錄的WinINet函數,但是我認爲在這裏發佈它會對Telerik/plagarism造成損害。

目前,Fiddlercore在這裏舉行:http://www.telerik.com/fiddler/fiddlercore

+0

你是男人。而Fidder是我的朋友。 – imgen 2014-06-13 09:18:03

+2

我真的不知道爲什麼這個唯一正確的答案沒有得到太多讚揚。無論如何,這給了我成爲第一個的優勢。 – imgen 2014-06-13 09:19:37