• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1935
  • Last Modified:

Clearing IE Cache using VB.NET

Deleting Internet Explorer Cache using VB.Net

I need to be able to clear the IE cache using VB.Net.

I currently have a simple app that does a few things with a new IE window, created using:

CreateObject("InternetExplorer.Application")

Any help greatly appreciated
0
chuckalicious
Asked:
chuckalicious
  • 11
  • 6
1 Solution
 
DhaestCommented:
0
 
jimstarCommented:
Here's some code that will get the History folder via the .NET SpecialFolders, and then get files within that for deletion. Essentially, you want to get rid of everything within that special folder. Some may not be accessible if they are in use though.

private void frmMain_Load(object sender, System.EventArgs e)
{
path = Environment.GetFolderPath(Environment.SpecialFolder.History) + "\\";
getList(path);

}

private void getList(string thepath)
{
DirectoryInfo dir = new DirectoryInfo(thepath);
DirectoryInfo[] dirs = dir.GetDirectories();
FileInfo[] files = dir.GetFiles();
foreach(DirectoryInfo d in dirs)
{
getList(d.FullName);
}

foreach(FileInfo f in files)
{
lstHistory.Items.Add(f.FullName);
}
}

private void clrHist()
{
for(int i = 0; i < lstHistory.Items.Count; i++)
{
try
{
File.Delete(lstHistory.Items[i].Text);
}
catch(IOException e)
{
MessageBox.Show("Error: \n\n\n" + e.Message);
}
}
}
0
 
chuckaliciousAuthor Commented:
jimstar,

I've pasted that code into MS VB 2005 Basic Edition and it's just throwing up lots of errors about end of statements exptected and delcations expected. Should this code work in 2005 Basic Edition?

Note I'm very new to VB so the above might be a stupid question!
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
jimstarCommented:
Oops, sorry! That is C# code. I'll see if I can convert it over, though it's been a while since I've done VB.NET. :)
0
 
jimstarCommented:
I found an article that gives VB.NET code for clearing the IE cache, written by Microsoft Support. Give this a try:

http://support.microsoft.com/kb/262110/EN-US/

0
 
chuckaliciousAuthor Commented:
THanks JimStar

When I paste that code in, it tells me that VB no longer supports Type and I should use Structure instead and that the variables aren't declared.
So I go from this:
Private Type INTERNET_CACHE_ENTRY_INFO
   dwStructSize As Long
    szRestOfData(1024) As Long
End Type

to this:

Private Structure INTERNET_CACHE_ENTRY_INFO
    Dim dwStructSize As Long
    Dim szRestOfData(1024) As Long
 End Structure

I then get the error of "Arrays declared as structure members cannot be declared with an initial size" for the line Dim szRestOfData(1024) As Long

I have no idea what this means :(

0
 
chuckaliciousAuthor Commented:
JimStar, the code you posted in C# seems a lot more straight forward than the code in the link you provided, which is erroring with something about an unbalanced stack.....

Would it be possible for you to convert it from C# to vb.net?

Thanks
0
 
jimstarCommented:
It was actually an error on my part - I converted it already, but the code didn't work. Deleting the files is not possible because explorer.exe has them open all the time.

The only option appears to be using the functions that are specifically designed for clearing the cache.

I'm working on a solution right now. The problem is that older versions of VB use Long, and newer versions need to use Integer to pass information around. There are a few issues with the code on Microsoft's site that I am trying to correct.
0
 
jimstarCommented:
Got it working. I verified this using Visual Studio VB .NET 8.0. The formatting is a little messy.

================================

1. In your application, create a new class by using New --> Class (leave it named Class1). Paste the following code into the class:

Imports System.Runtime.InteropServices
'Class for deleting the cache.
Public Class Class1
    'For PInvoke: Contains information about an entry in the Internet cache
        _
    Public Structure INTERNET_CACHE_ENTRY_INFOA
        Public dwStructSize As UInt32
        Public lpszSourceUrlName As IntPtr
        Public lpszLocalFileName As IntPtr
        Public CacheEntryType As UInt32
        Public dwUseCount As UInt32
        Public dwHitRate As UInt32
        Public dwSizeLow As UInt32
        Public dwSizeHigh As UInt32
        Public LastModifiedTime As FILETIME
        Public ExpireTime As FILETIME
        Public LastAccessTime As FILETIME
        Public LastSyncTime As FILETIME
        Public lpHeaderInfo As IntPtr
        Public dwHeaderInfoSize As UInt32
        Public lpszFileExtension As IntPtr
        Public dwReserved As UInt32
        Public dwExemptDelta As UInt32
    End Structure

    'For PInvoke: Initiates the enumeration of the cache groups in the Internet cache

    <DllImport("wininet.dll", _
           CharSet:=CharSet.Auto, _
           EntryPoint:="FindFirstUrlCacheGroup", _
           CallingConvention:=CallingConvention.StdCall)> _
        Shared Function FindFirstUrlCacheGroup( _
        ByVal dwFlags As Int32, _
        ByVal dwFilter As Integer, _
        ByVal lpSearchCondition As IntPtr, _
        ByVal dwSearchCondition As Int32, _
        ByRef lpGroupId As Long, _
        ByVal lpReserved As IntPtr) As IntPtr
    End Function

    'For PInvoke: Retrieves the next cache group in a cache group enumeration
    <DllImport("wininet.dll", _
          SetLastError:=True, _
      CharSet:=CharSet.Auto, _
      EntryPoint:="FindNextUrlCacheGroup", _
      CallingConvention:=CallingConvention.StdCall)> _
   Shared Function FindNextUrlCacheGroup( _
       ByVal hFind As IntPtr, _
       ByRef lpGroupId As Long, _
       ByVal lpReserved As IntPtr) As Boolean
    End Function

    'For PInvoke: Releases the specified GROUPID and any associated state in the cache index file
    <DllImport("wininet.dll", _
          SetLastError:=True, _
      CharSet:=CharSet.Auto, _
      EntryPoint:="DeleteUrlCacheGroup", _
      CallingConvention:=CallingConvention.StdCall)> _
   Shared Function DeleteUrlCacheGroup( _
       ByVal GroupId As Long, _
       ByVal dwFlags As Int32, _
       ByVal lpReserved As IntPtr) As Boolean
    End Function

    'For PInvoke: Begins the enumeration of the Internet cache
    <DllImport("wininet.dll", _
        SetLastError:=True, _
      CharSet:=CharSet.Auto, _
      EntryPoint:="FindFirstUrlCacheEntryA", _
      CallingConvention:=CallingConvention.StdCall)> _
   Shared Function FindFirstUrlCacheEntry( _
    ByVal lpszUrlSearchPattern As String, _
        ByVal lpFirstCacheEntryInfo As IntPtr, _
        ByRef lpdwFirstCacheEntryInfoBufferSize As Int32) As IntPtr
    End Function

    'For PInvoke: Retrieves the next entry in the Internet cache
    <DllImport("wininet.dll", _
          SetLastError:=True, _
      CharSet:=CharSet.Auto, _
      EntryPoint:="FindNextUrlCacheEntryA", _
      CallingConvention:=CallingConvention.StdCall)> _
   Shared Function FindNextUrlCacheEntry( _
         ByVal hFind As IntPtr, _
         ByVal lpNextCacheEntryInfo As IntPtr, _
         ByRef lpdwNextCacheEntryInfoBufferSize As Integer) As Boolean
    End Function

    'For PInvoke: Removes the file that is associated with the source name from the cache, if the file exists
    <DllImport("wininet.dll", _
      SetLastError:=True, _
      CharSet:=CharSet.Auto, _
      EntryPoint:="DeleteUrlCacheEntryA", _
      CallingConvention:=CallingConvention.StdCall)> _
    Shared Function DeleteUrlCacheEntry( _
    ByVal lpszUrlName As IntPtr) As Boolean
    End Function

End Class

==========================================

2. Create a new module in your project and paste the following code into it:

Imports System.Runtime.InteropServices

Module Module1
    Sub Main()
        'Indicates that all of the cache groups in the user's system should be enumerated
        Const CACHEGROUP_SEARCH_ALL = &H0
        'Indicates that all of the cache entries that are associated with the cache group should be deleted,
        'unless the entry belongs to another cache group.
        Const CACHEGROUP_FLAG_FLUSHURL_ONDELETE = &H2
        'File not found.
        Const ERROR_FILE_NOT_FOUND = &H2
        'No more items have been found.
        Const ERROR_NO_MORE_ITEMS = 259
        'Pointer to a GROUPID variable
        Dim groupId As Long = 0

        'Local variables
        Dim cacheEntryInfoBufferSizeInitial As Integer = 0
        Dim cacheEntryInfoBufferSize As Integer = 0
        Dim cacheEntryInfoBuffer As IntPtr = IntPtr.Zero
        Dim internetCacheEntry As Class1.INTERNET_CACHE_ENTRY_INFOA
        Dim enumHandle As IntPtr = IntPtr.Zero
        Dim returnValue As Boolean = 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 CacheGroup APIs are not used because the existing URL does not belong to any group.    

        enumHandle = Class1.FindFirstUrlCacheGroup(0, CACHEGROUP_SEARCH_ALL, IntPtr.Zero, 0, groupId, IntPtr.Zero)
        'If there are no items in the Cache, you are finished.
        If (Not enumHandle.Equals(IntPtr.Zero) And ERROR_NO_MORE_ITEMS.Equals(Marshal.GetLastWin32Error)) Then
            Exit Sub
        End If

        'Loop through Cache Group, and then delete entries.
        While (True)
            'Delete a particular Cache Group.
            returnValue = Class1.DeleteUrlCacheGroup(groupId, CACHEGROUP_FLAG_FLUSHURL_ONDELETE, IntPtr.Zero)

            If (Not returnValue And ERROR_FILE_NOT_FOUND.Equals(Marshal.GetLastWin32Error())) Then
                returnValue = Class1.FindNextUrlCacheGroup(enumHandle, groupId, IntPtr.Zero)
            End If

            If (Not returnValue And (ERROR_NO_MORE_ITEMS.Equals(Marshal.GetLastWin32Error()) Or ERROR_FILE_NOT_FOUND.Equals(Marshal.GetLastWin32Error()))) Then
                Exit While
            End If
        End While
        'Start to delete URLs that do not belong to any group.
        enumHandle = Class1.FindFirstUrlCacheEntry(vbNull, IntPtr.Zero, cacheEntryInfoBufferSizeInitial)

        If (Not enumHandle.Equals(IntPtr.Zero) And ERROR_NO_MORE_ITEMS.Equals(Marshal.GetLastWin32Error())) Then
            Exit Sub
        End If

        cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial
        cacheEntryInfoBuffer = Marshal.AllocHGlobal(cacheEntryInfoBufferSize)
        enumHandle = Class1.FindFirstUrlCacheEntry(vbNull, cacheEntryInfoBuffer, cacheEntryInfoBufferSizeInitial)

        While (True)
            internetCacheEntry = CType(Marshal.PtrToStructure(cacheEntryInfoBuffer, GetType(Class1.INTERNET_CACHE_ENTRY_INFOA)), Class1.INTERNET_CACHE_ENTRY_INFOA)
            cacheEntryInfoBufferSizeInitial = cacheEntryInfoBufferSize
            returnValue = Class1.DeleteUrlCacheEntry(internetCacheEntry.lpszSourceUrlName)

            If (Not returnValue) Then
                'Console.WriteLine("Error Deleting: {0}", Marshal.GetLastWin32Error())
            End If

            returnValue = Class1.FindNextUrlCacheEntry(enumHandle, cacheEntryInfoBuffer, cacheEntryInfoBufferSizeInitial)
            If (Not returnValue And ERROR_NO_MORE_ITEMS.Equals(Marshal.GetLastWin32Error())) Then
                Exit While
            End If

            If (Not returnValue And cacheEntryInfoBufferSizeInitial > cacheEntryInfoBufferSize) Then

                cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial
                Dim tempIntPtr As New IntPtr(cacheEntryInfoBufferSize)
                cacheEntryInfoBuffer = Marshal.ReAllocHGlobal(cacheEntryInfoBuffer, tempIntPtr)
                returnValue = Class1.FindNextUrlCacheEntry(enumHandle, cacheEntryInfoBuffer, cacheEntryInfoBufferSizeInitial)
            End If
        End While
        Marshal.FreeHGlobal(cacheEntryInfoBuffer)

    End Sub

End Module

============================

3. Compile and run the application.
0
 
jimstarCommented:
Depending on your specific project, you may need to rename Sub Main() to a different name that you call when you want to clear the cache.

Let me know if you have any trouble.
0
 
chuckaliciousAuthor Commented:
Thanks. A few things with that. According to my VB Studio, instead of Imports System.Runtime.InteropServices we should be using Imports System.Runtime.InteropServices.ComTypes.FILETIME

and also it wants the variables Marshal and DllImport declared. What should I declare them as?

Thanks again
0
 
jimstarCommented:
Marshal and DllImport are under System.Runtime.InteropServices, which is why it gets imported. When you changed it to ... ComTypes.FILETIME, it made it so that the Marchal and DllImport couldn't be found.

What specifically is the error you get when you just use:
Imports System.Runtime.InteropServices
?
0
 
jimstarCommented:
One option that should fix any issue with Marshal and DllImport would be to prepend the System.Runtime.InteropServices string to them.

So, wherever you see:
Marshal

Make it:
System.Runtime.InteropServices.Marshal

... and the same with DllImport.

It's odd that you're getting issues with the general import, but the above tip should fix any problem.
0
 
chuckaliciousAuthor Commented:
Ok no errors, now, the last question :) How do I call this? My code is being run via a button on a form.

Thanks
0
 
jimstarCommented:
To call it from a form, you'll want to rename Sub Main() in Module1 to something like Sub ClearCacheNow(). Then, you should be able to double click on the button on your form, and then type ClearCacheNow() in the button's subroutine.
0
 
chuckaliciousAuthor Commented:
Alright, one last question, does this clear just the cache, or does it clear cookies and completed form information as well?
0
 
jimstarCommented:
This code clears everything.
0
 
jimstarCommented:
I should clarify - it clears "Temporary Internet Files", which contains cached files and cookie information. I don't believe it includes the autocomplete data, typed URLs, or history.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

  • 11
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now