?
Solved

Clearing IE Cache using VB.NET

Posted on 2007-10-09
18
Medium Priority
?
1,725 Views
Last Modified: 2010-08-05
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
Comment
Question by:chuckalicious
  • 11
  • 6
18 Comments
 
LVL 53

Expert Comment

by:Dhaest
ID: 20039213
0
 
LVL 4

Expert Comment

by:jimstar
ID: 20039278
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
 
LVL 4

Author Comment

by:chuckalicious
ID: 20039400
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 4

Expert Comment

by:jimstar
ID: 20039418
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
 
LVL 4

Expert Comment

by:jimstar
ID: 20039566
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
 
LVL 4

Author Comment

by:chuckalicious
ID: 20039621
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
 
LVL 4

Author Comment

by:chuckalicious
ID: 20039686
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
 
LVL 4

Expert Comment

by:jimstar
ID: 20039700
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
 
LVL 4

Accepted Solution

by:
jimstar earned 500 total points
ID: 20039792
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
 
LVL 4

Expert Comment

by:jimstar
ID: 20039799
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
 
LVL 4

Author Comment

by:chuckalicious
ID: 20039816
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
 
LVL 4

Expert Comment

by:jimstar
ID: 20039823
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
 
LVL 4

Expert Comment

by:jimstar
ID: 20039851
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
 
LVL 4

Author Comment

by:chuckalicious
ID: 20039869
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
 
LVL 4

Expert Comment

by:jimstar
ID: 20039887
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
 
LVL 4

Author Comment

by:chuckalicious
ID: 20039955
Alright, one last question, does this clear just the cache, or does it clear cookies and completed form information as well?
0
 
LVL 4

Expert Comment

by:jimstar
ID: 20039986
This code clears everything.
0
 
LVL 4

Expert Comment

by:jimstar
ID: 20039991
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

Featured Post

Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Simulator games are perfect for generating sample realistic data streams, especially for learning data analysis. It is even useful for demoing offerings such as Azure stream analytics, PowerBI etc.
Google currently has a new report that is in beta and coming soon to Webmaster Tool accounts. This Micro Tutorial will highlight new features for Google Webmaster Tools.
This Micro Tutorial will demonstrate how to add subdomains to your content reports. This can be very importing in having a site with multiple subdomains.
Suggested Courses
Course of the Month15 days, 23 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question