c# 代码访问WinINET cache
网上搜索了一下, 关于这个的很少. 自己写了一下, 记录一下, 以便将来能用到.大部分code来源于stackoverflow的一个帖子, 自己稍微改了一下, 去掉cacheGroup相关的部分.
原来代码比较坑的地方是这个写错了:
DeleteUrlCacheEntry(internetCacheEntry.lpszLocalFileName); // 他用到是另外一个lpszSourceUrlName, 然而不对.
public static class WinINetCacheHelper
{
#region WINAPI
[DllImport("wininet", EntryPoint = "DeleteUrlCacheEntryA", SetLastError = true)]
public static extern bool DeleteUrlCacheEntry(IntPtr lpszUrlName);
[DllImport("wininet", SetLastError = true)]
public static extern bool DeleteUrlCacheGroup(long GroupId, int dwFlags, IntPtr lpReserved);
[DllImport("wininet", EntryPoint = "FindFirstUrlCacheEntryA", SetLastError = true)]
public static extern IntPtr FindFirstUrlCacheEntry(string lpszUrlSearchPattern, IntPtr lpFirstCacheEntryInfo, ref int lpdwFirstCacheEntryInfoBufferSize);
[DllImport("wininet", SetLastError = true)]
public static extern IntPtr FindFirstUrlCacheGroup(int dwFlags, int dwFilter, IntPtr lpSearchCondition, int dwSearchCondition, ref long lpGroupId, IntPtr lpReserved);
[DllImport("wininet", EntryPoint = "FindNextUrlCacheEntryA", SetLastError = true)]
public static extern bool FindNextUrlCacheEntry(IntPtr hFind, IntPtr lpNextCacheEntryInfo, ref int lpdwNextCacheEntryInfoBufferSize);
[DllImport("wininet", SetLastError = true)]
public static extern bool FindNextUrlCacheGroup(IntPtr hFind, ref long lpGroupId, IntPtr lpReserved);
#endregion
[StructLayout(LayoutKind.Explicit)]
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;
}
public static bool IsLocalCached(string uri)
{
bool detectedUriInLocal;
OperateCache(true, uri, out detectedUriInLocal);
return detectedUriInLocal;
}
public static void CleanupLocalCache(string uri)
{
bool detectedUriInLocal;
OperateCache(false, uri, out detectedUriInLocal);
}
private static void OperateCache(bool queryOnly, string uri, out bool detectedLocalCache)
{
detectedLocalCache = false;
// 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 ERROR_NO_MORE_ITEMS = 259;
// Start to delete URLs that do not belong to any group.
IntPtr enumHandle = IntPtr.Zero;
int cacheEntryInfoBufferSizeInitial = 0;
enumHandle = FindFirstUrlCacheEntry(null, IntPtr.Zero, ref cacheEntryInfoBufferSizeInitial);
if (enumHandle == IntPtr.Zero && ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error())
return;
IntPtr cacheEntryInfoBuffer = IntPtr.Zero;
int cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial;
cacheEntryInfoBuffer = Marshal.AllocHGlobal(cacheEntryInfoBufferSize);
enumHandle = FindFirstUrlCacheEntry(null, cacheEntryInfoBuffer, ref cacheEntryInfoBufferSizeInitial);
bool returnValue = false;
while (true)
{
INTERNET_CACHE_ENTRY_INFOA internetCacheEntry = (INTERNET_CACHE_ENTRY_INFOA)Marshal.PtrToStructure(cacheEntryInfoBuffer, typeof(INTERNET_CACHE_ENTRY_INFOA));
cacheEntryInfoBufferSizeInitial = cacheEntryInfoBufferSize;
string cachedUri = Marshal.PtrToStringAnsi(internetCacheEntry.lpszLocalFileName);
if (cachedUri.Contains(uri))
{
detectedLocalCache = true;
if (!queryOnly)
returnValue = DeleteUrlCacheEntry(internetCacheEntry.lpszLocalFileName);
break;
}
else
{
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);
}
}
// release memory
Marshal.FreeHGlobal(cacheEntryInfoBuffer);
}
}
顺便记一下:
(Win10)的cache在 %appdata%\..\Local\Microsoft\Windows\INetCache
Win 7 和 Win 10的 cache路径不一样, 可能在这里: %appdata%\..\Local\Microsoft\Windows\Caches

浙公网安备 33010602011771号