网上搜索了一下, 关于这个的很少. 自己写了一下, 记录一下, 以便将来能用到.大部分code来源于*的一个帖子, 自己稍微改了一下, 去掉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