2012-07-27 27 views
5

Ich verwende P/Invoke mit C#, um Cache-Einträge wie folgt zu löschen. Der Code scheint bis zu Windows 7 auf 32 und 64 Bit zu funktionieren. Auf dem Windows 8 Release Candidate hängt es unter dem DeleteUrlsFromGroup-Aufruf.Wininet-Cache-API hängt in Windows 8

[DllImport(@"wininet", 
    SetLastError = true, 
    CharSet = CharSet.Auto, 
    EntryPoint = "FindFirstUrlCacheGroup", 
    CallingConvention = CallingConvention.StdCall)] 
private 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)] 
private 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)] 
private 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)] 
private 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)] 
private 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)] 
static extern bool DeleteUrlCacheEntry(string lpszUrlName); 

/// <summary> 
/// Clears the cache of the web browser 
/// </summary> 
[HandleProcessCorruptedStateExceptions] 
public static void ClearCache(Uri hostName) 
{ 
    if (hostName == null) 
    { 
     return; 
    } 

    long groupId = 0; 
    try 
    { 
     // Delete the groups first. 
     IntPtr enumHandle = FindFirstUrlCacheGroup(0, CACHEGROUP_SEARCH_ALL, IntPtr.Zero, 0, ref groupId, IntPtr.Zero); 
     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. 
      // Hangs on WIndows 8 
      bool 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; 
     } 
     DeleteUrlsFromGroup(hostName); // this hangs on Windows 8 
    } 
    catch (AccessViolationException) 
    { 

    } 
} 

Alle Einblicke/Verweise auf Änderungen in der Win-API für Windows 8?

Vielen Dank im Voraus.

+0

Sie eine Lösung gefunden? –

+0

Noch nicht. Musste eine Versionsüberprüfung durchführen, um den fehlerhaften Code für Windows 8 zu überspringen. – jimbojones

Antwort

1

Dieser KB-Artikel, auf den alle verweisen, enthält zahlreiche Fehler (wo der Quellcode der anderen Antwort herkommt), und ich habe ~ 2 Tage verschwendet, um ihn in allen notwendigen Einstellungen zum Laufen zu bringen. Es ist eine Kopie über das Internet eingefügt, und es gibt zahlreiche Fehler gemeldet, basierend auf OS und IE-Version.

Fiddler wurde ursprünglich von einem Microsoft-Mitarbeiter geschrieben und wird von FiddlerCore.dll angetrieben. Telerik (die derzeitigen Eigentümer/Betreuer/Verkäufer) von Fiddler aktualisieren, pflegen und verschenken FiddlerCore kostenlos.Wenn Sie keine Referenz zu FiddlerCore hinzufügen möchten, können Sie die DLL zerlegen, und es zeigt die korrekte Methode, alle diese schrecklich dokumentierten WinINet-Funktionen aufzurufen, aber ich denke, es hier zu veröffentlichen wäre für Telerik/Plagarismus ein schlechter Dienst.

Derzeit Fiddlercore wird hier gehostet: http://www.telerik.com/fiddler/fiddlercore

1

Ich sehe eine pinvoke Erklärung nicht für DeleteUrlsFromGroup, nur DeleteUrlCacheEntry. Ich nehme an, dass das die Methode ist, die hängt?

Wenn das der Fall ist, scheint es seltsam, Sie sind die ANSI-Version der Funktion explizit aufrufen:

EntryPoint = "DeleteUrlCacheEntryA" 

Aber spezifizieren auch:

CharSet = CharSet.Auto 

, die mir zeigen würden Sie sind Übergeben einer Unicode-Zeichenfolge an eine Funktion, die eine ANSI-Zeichenfolge erwartet. Von MSDN:

Automatisches Marshales Strings entsprechend für das Zielbetriebssystem. Der Standardwert ist Unicode unter Windows NT, Windows 2000, Windows XP und der Windows Server 2003-Produktfamilie. Der Standard ist Ansi unter Windows 98 und Windows Me.

Entweder geben Sie keine Funktion mit dem * A * oder W-Erweiterung als pinvoke Schicht wird das für Sie Karte, oder rufen Sie die * W-Versionen der Funktionen, da Sie mit CharSet.Auto Unicode-Strings sind vorbei . Wenn Sie explizit die ANSI/Unicode-Version einer Funktion aufrufen, wäre ich auch explizit mit dem passenden CharSet.

+0

Er hat 'DeleteUrlCacheGroup'. "DeleteUrlsFromGroup" in der Frage scheint ein Tippfehler zu sein, da es keine solche API gibt. –

+0

Ich nahm an, es war DeleteUrlCacheEntry, da diese Methode mindestens mit der Signatur der nicht existenten Methode übereinstimmt, die er aufruft, ein einzelner String-Parameter. – joncham

+0

Danke für das Update. Ich werde dies auf unserer Test Windows8 Box testen und als akzeptiert markieren, wenn es funktioniert. Der Grund dafür ist die 'CharSet.Auto'- und die '* A'-Version des Imports, weil sie direkt von http://support.microsoft.com/kb/326201 übernommen wurde. Ich muss den Code von Microsoft genauer überprüfen. – jimbojones

2

hatte auch das gleiche Problem, aber für C++ (von diesem KB http://support.microsoft.com/kb/815718). Ich habe nur überprüft, ob die DeleteUrlCacheGroup() weiterhin versucht, den gleichen groupId Wert zu löschen.

Ich verfolge die vorherige groupId, wenn es mit der aktuellen übereinstimmt, breche ich nur die Schleife.

2

@jimbojones: Ich bin nicht sicher, ob Sie noch nach einer Antwort suchen, aber ich habe gerade das gleiche Problem und eine Abhilfe gefunden. Das Problem ist nicht mit „DeleteUrlCacheGroup“, sein in der while-Schleife

while (true) 
     { 
      if (ERROR_NO_MORE_ITEMS == Marshal.GetLastWin32Error() || ERROR_FILE_NOT_FOUND == Marshal.GetLastWin32Error()) 
      { 
       break; 
      } 

      // Delete a particular Cache Group. 
      // Hangs on WIndows 8 
      bool 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; 
     } 

Wenn Ihr Code mit groupdid aufgerufen wird ‚0‘ wird es nie falsch zurückgeben und damit Ihre Schleife verursacht unendlich zu sein, die tatsächlich verursacht Ihre App zum Aufhängen. Ich habe dieses Problem nicht unter Windows 8, sondern unter Windows 7 selbst erkannt. Szenario könnte anders sein, aber ich denke, dass Sie vor dem gleichen Problem stehen.