2009-08-14 24 views
8

我在.Net中使用WebBrowser控件來執行一些第三方聯盟營銷轉換。緩存和.B中的WebBrowser控件

我有一個數據庫中的隊列表與所有腳本/圖像執行。我通過WebBrowser控件在WinForms應用程序中循環所有這些。執行腳本/圖像後,我配置WebBrowser控件,將其設置爲null,並使用新的WebBrowser控件實例對其進行更新。

考慮一下這個網址:http://renderserver/RenderScript.aspx?id=1

RenderScript.aspx顯示圖像具有例如一個網址:http://3rdparty/img.ashx?id=9343

我使用Fiddler查看所有請求和響應,並在執行兩次相同的URL,它使用某種緩存。該緩存存在於WebBrowser控件本身的下面。

此緩存表示img.ashx未被調用。

我嘗試使用Internet Explorer請求網址:http://renderserver/RenderScript.aspx?id=1並點擊F5。然後它被完美地要求。

但是,如果我點擊地址欄並點擊Enter再次導航到相同的URL - 它不會被請求。當我使用Firefox時,無論使用F5還是從地址欄導航,都會每次請求頁面和圖像。

我發現一些能夠清除緩存的Win32 API調用(http://support.microsoft.com/kb/326201)。它在我的本地機器上運行。然後,該應用程序被部署到運行Windows Server 2003 Standard x64的服務器(我自己的機器是Vista x86)。

現在,調用清除緩存的API不起作用。

關於爲什麼API調用在Windows Server上不起作用的任何想法,但適用於Vista?兩臺機器都運行IE8。

回答

4

我的S ame問題(相當)一陣子回來。微軟有一個網頁,是這個非常有幫助:

http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q326/2/01.asp&NoWebContent=1

我創建了一個類從微軟的樣品,但是我也不得不添加一對夫婦如果在沒有更多項目的發言停止處理;它已經有一段時間了,但我敢肯定它會拋出一個錯誤(請參閱下面的代碼ERROR_NO_MORE_ITEMS)。

我希望它有幫助!

using System; 
using System.Runtime.InteropServices; 

// copied from: http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q326/2/01.asp&NoWebContent=1 

namespace PowerCode 
{ 
    public class IECache 
    { 
     // 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 FILETIME LastModifiedTime; 
      [FieldOffset(40)] 
      public FILETIME ExpireTime; 
      [FieldOffset(48)] 
      public FILETIME LastAccessTime; 
      [FieldOffset(56)] 
      public 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); 

     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()) { 
        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); 
     } 
    } 
} 

要在代碼中使用它,只要致電:

IECache.ClearCache() 

調用導航方法之前。

0

提琴手從根本上使用相同的代碼知識庫文章以清除的Win​​INET緩存中,我每天都使用它WIN2K3。

不是擦拭用戶的整個高速緩存中,適當的解決方法是設置適當的HTTP響應報頭禁止高速緩存。您可以瞭解更多有關的WinINET緩存在這裏:http://www.enhanceie.com/redir/?id=httpperf

(或者,你可以簡單地添加一個隨機的查詢字符串參數;這樣一來,每個控制遇到了資源的請求時,URL是不同的緩存從而自動旁路)

+0

負。它與緩存標題無關。他們已經正確設置,以避免緩存。正如我指出的那樣,其他瀏覽器不會緩存。 – MartinHN 2009-08-14 19:10:59

+0

而隨機參數也不起作用。因爲ScriptRender頁面加載的第三方HTML完全不受我的控制。所以我只能將參數添加到RenderScript頁面。圖片標籤(有時是IFrame,有時是javascript)會加載靜態網址。 – MartinHN 2009-08-14 19:13:01

+0

對不起,但你錯了。如果設置了適當的響應頭文件,WinINET/IE/WebOCs將不會重用緩存的響應。 什麼是ASHX發送的確切標題?你能給我一個網絡捕捉(www.fiddlercap.com)嗎? – EricLaw 2009-08-15 23:16:02

-1

這應該做的伎倆:

Response.Cache.SetCacheability(HttpCacheability.NoCache); 
+1

-1:他不是在談論ASP.NET。他在談論IE。 – 2011-01-30 02:06:31

0

嘗試......

[DllImport("wininet.dll", SetLastError = true)] 
     private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength); 
private const int INTERNET_OPTION_END_BROWSER_SESSION = 42; 
private void clearCache() 
{ 
    try 
    { 
     Utilities.Web.WebBrowserHelper.WebBrowserHelper.ClearCache(); 
     InternetSetOption(IntPtr.Zero, INTERNET_OPTION_END_BROWSER_SESSION, IntPtr.Zero, 0); 
    } 
    catch (Exception exception) 
    { 
     //throw; 
    } 

} 
+1

'Utilities.Web.WebBrowserHelper.WebBrowserHelper.ClearCache();'定義在哪裏? – Nate 2013-03-27 17:04:38

0

人人都知識庫文章鏈接到具有中有許多錯誤(在所選擇的答案的源代碼來自),我已經浪費了〜2天的努力得到它在所有必要的設置工作。它是複製粘貼在互聯網上,並且有許多基於操作系統和IE版本報告的錯誤。

提琴手最初是由微軟員工寫的,是由FiddlerCore.dll供電。 Teleid(當前所有者/維護者/賣家)的Fiddler仍然免費更新,維護和放棄FiddlerCore。如果你不希望添加到FiddlerCore一個參考,你可以拆卸的DLL,它顯示了正確的方法來調用所有的這些可怕的記錄WinInet函數,但我想在這裏張貼這將是幫倒忙Telerik的/抄襲。

目前,Fiddlercore在這裏舉行:http://www.telerik.com/fiddler/fiddlercore

0

https://support.microsoft.com/en-us/kb/326201 原代碼似乎馬車

檢查MSDN文檔,也是VB版本在這裏: https://support.microsoft.com/en-us/kb/262110

我修改了代碼像這一點,現在它的工作對我來說(這個問題是在FindNextUrlCacheGroup和FindNextUrlCacheEntry執行):

using System; 
using System.Runtime.InteropServices; 

namespace Q326201CS 
{ 
    // Class for deleting the cache. 
    public class DeleteIECache 
    { 
     // 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 FILETIME LastModifiedTime; 
      [FieldOffset(40)] public FILETIME ExpireTime; 
      [FieldOffset(48)] public FILETIME LastAccessTime; 
      [FieldOffset(56)] public 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); 


     public static void doDelete() 
     { 
      // 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 || (!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()) 
       { 
        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);  
     } 
    } 
}