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

猜你喜欢

转载自www.cnblogs.com/-cxy/p/11993272.html
今日推荐