问题描述
我有这个代码清除缓存在C#WebBrowser控件。它的问题是它也清除cookie。我似乎是整个互联网上唯一不想要的人。
我需要保存cookie,但是丢弃缓存。
特别感兴趣的是这一行:
const int CACHEGROUP_SEARCH_ALL = 0x0; code>
似乎定义了哪些缓存组(无论是什么)都被清除,我希望cookie是一个缓存组,我可以跳过某种方式。然而,试图找到任何关于这一点的信息只产生了一个惊人的头痛。
此代码最初是从MSDN文章,但它甚至不是提及Cookie或缓存组。
您可以在代码顶部看到MSDN文章。
/ **
*修改自此处最初发现的代码:http://support.microsoft.com/kb/326201
** /
使用系统;
using System.Runtime.InteropServices;
使用System.Runtime.InteropServices.ComTypes;
using System.Diagnostics;
命名空间Goop
{
//删除缓存的类别
public static class WebBrowserHelper
{
#region定义/ DLL导入
//用于PInvoke:包含有关Internet缓存中条目的信息
[StructLayout(LayoutKind。显式,大小= 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;
}
//对于PInvoke:启动Internet缓存中缓存组的枚举
[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:检索缓存组枚举中的下一个缓存组
[DllImport(@wininet,
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint =FindNextUrlCacheGroup,
CallingConvention = CallingConvention.StdCall)]
public static extern bool FindNextUrlCacheGroup(
IntPtr hFind,
ref long lpGroupId,
IntPtr lpReserved);
//对于PInvoke:释放指定的GROUPID和缓存索引文件中的任何关联状态
[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:开始互联网缓存的枚举
[DllImport(@wininet,
SetLastError = true,
CharSet = CharSet.Auto,
(
[MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern,
IntPtr lpFirstCacheEntryInfo,
ref int lpdwFirstCacheEntryInfoBufferSize);
// For PInvoke:检索Internet缓存中的下一个条目
[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:如果文件存在,从缓存中删除与源名称相关联的文件
[DllImport(@wininet,
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint =DeleteUrlCacheEntryA,
CallingConvention = CallingConvention.StdCall)]
public static extern bool DeleteUrlCacheEntry(
IntPtr lpszUrlName);
#endregion
#region公共静态函数
///
///清除Web浏览器的缓存
///
public static void ClearCache()
{
//指示用户系统中的所有缓存组应该枚举
const int CACHEGROUP_SEARCH_ALL = 0x0;
//指示应该删除与缓存组
//相关联的所有缓存条目,除非该条目属于另一个缓存组。
const int CACHEGROUP_FLAG_FLUSHURL_ONDELETE = 0x2;
//找不到文件。
const int ERROR_FILE_NOT_FOUND = 0x2;
//没有找到更多的项目。
const int ERROR_NO_MORE_ITEMS = 259;
//指向GROUPID变量的指针
long groupId = 0;
//局部变量
int cacheEntryInfoBufferSizeInitial = 0;
int cacheEntryInfoBufferSize = 0;
IntPtr cacheEntryInfoBuffer = IntPtr.Zero;
INTERNET_CACHE_ENTRY_INFOA internetCacheEntry;
IntPtr enumHandle = IntPtr.Zero;
bool returnValue = false;
//首先删除组。
//组可能不总是存在于系统上。
//有关更多信息,请访问下面的Microsoft网站:
// http://msdn.microsoft.com/library/?url=/workshop/networking/wininet/overview/cache.asp
//默认情况下,一个URL不属于任何组。因此,即使未使用CacheGroup API,该缓存也可能变为
//空,因为现有URL不属于任何组。
enumHandle = FindFirstUrlCacheGroup(0,CACHEGROUP_SEARCH_ALL,IntPtr.Zero,0,ref groupId,IntPtr.Zero);
//如果缓存中没有项,则表示完成。
if(enumHandle!= IntPtr.Zero && ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error())
{
return;
}
//循环通过缓存组,然后删除条目。
while(true)
{
if(ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error()|| ERROR_FILE_NOT_FOUND == Marshal.GetLastWin32Error())
{
break;
}
//删除特定的缓存组。
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;
}
//开始删除不属于任何组的URL。
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
}
}
$ b
- RANT -
在其中有许多错误(其他答案的源代码来自),我浪费了〜2天试图让它在所有必要的设置工作。它是复制粘贴在互联网上,并有基于操作系统和IE版本报告的许多错误。
Fiddler最初是由微软员工写的,由FiddlerCore .dll。 Fiddler的Telerik(目前的所有者/维护者/销售者)仍然可以免费更新,维护和赠送FiddlerCore。如果你不想添加一个引用FiddlerCore,你可以反汇编的dll,它显示了CORRECT的方式来调用所有这些可怕的记录的WinINet函数,但我认为发布它将是一个损害Telerik / plagarism。
目前,Fiddlercore托管在这里:
I have this code that clears the cache in a C# WebBrowser control. The problem with it is that it also clears the cookies. I seem to be the only person on the entire internet that doesn't want that.
I need to maintain cookies, but to throw away the cache.
Of particular interest is this line:
const int CACHEGROUP_SEARCH_ALL = 0x0;
It seems to define which "cache groups" (whatever the heck those are) are cleaned out, and I'm hoping that cookies are a cache group that I can skip somehow. However, trying to find any information on this at all has produced nothing but a pounding headache.
This code is originally taken from an MSDN article, but it doesn't even mention cookies or cache groups.
You can see the MSDN article at the top of the code.
/**
* 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
}
}
Any and all help greatly appreciated.
FiddlerCore exposes a method with exactly that signature. ClearCacheItems(bool clearCookies, bool clearFiles).
--RANT--
That kb article everyone links to has numerous errors in it (where the other answers' source code came from), and I've wasted ~2 days trying to get it to work in all necessary settings. It is copy pasted across the internet, and there are numerous bugs reported based on OS and IE version.
Fiddler was originally written by a Microsoft employee, and is powered by FiddlerCore.dll. Telerik (the current owners/maintainers/sellers) of Fiddler still update, maintain and give away FiddlerCore for free. If you don't want to add a reference to FiddlerCore, you can disassemble the dll, and it shows the CORRECT way to call all of these horribly documented WinINet functions, but I think posting it here would be a disservice to Telerik / plagarism.
Currently, Fiddlercore is hosted here: http://www.telerik.com/fiddler/fiddlercore
这篇关于C#WebBrowser控件:清除缓存而不清除Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!