我有这个代码清除C#WebBrowser控件中的缓存。它的问题是它也清除了cookie。我似乎是整个互联网上唯一不想要的人。
我需要维护cookie,但要丢弃缓存。
特别感兴趣的是这一行:
const int CACHEGROUP_SEARCH_ALL = 0x0;
它似乎定义了哪些“缓存组”(无论那些是什么)都被清除了,我希望cookie是一个缓存组,我可以以某种方式跳过。然而,试图找到关于此的任何信息只会产生令人头疼的问题。
此代码最初来自MSDN文章,但它甚至没有提及cookie或缓存组。
您可以在代码顶部看到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 :(得分:3)
查看INTERNET_CACHE_ENTRY_INFOA的文档,尤其是描述CacheEntryType的部分:
指示缓存类型的位掩码 条目及其属性。缓存 条目类型包括:历史条目 (URLHISTORY_CACHE_ENTRY),cookie 条目(COOKIE_CACHE_ENTRY),和 正常的缓存内容 (NORMAL_CACHE_ENTRY)。
该成员可以是零或更多 以下属性标志和缓存 下面列出了类型标志。
在下面你会得到一个条目类型列表,一个是
COOKIE_CACHE_ENTRY
在抛弃一切之前,这似乎是你要检查的内容?
答案 1 :(得分:3)
FiddlerCore公开了一个具有该签名的方法。 ClearCacheItems(bool clearCookies,bool clearFiles)。
- RANT -
每个链接到的kb文章中都有很多错误(其他答案的源代码来自哪里),我浪费了大约2天的时间让它在所有必要的设置中运行。它是通过互联网进行的复制粘贴,并且根据操作系统和IE版本报告了许多错误。
Fiddler最初由Microsoft员工编写,由FiddlerCore.dll提供支持。 Fiddler的Telerik(现任所有者/维护者/卖家)仍然免费更新,维护和赠送FiddlerCore。如果你不想添加对FiddlerCore的引用,你可以反汇编dll,它显示了调用所有这些可怕记录的WinINet函数的CORRECT方法,但我认为在这里发布它会对Telerik / plagarism造成伤害。
目前,Fiddlercore在此托管:http://www.telerik.com/fiddler/fiddlercore
答案 2 :(得分: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。
答案 3 :(得分:0)
在页面中添加以下元标记
<meta http-equiv="cache-control" content="no-cache">