The DeleteUrlCacheGroups subroutine enumerates the cache groups that exist in the WinInet cache database. The script then gathers information (e.g., how much disk space the group consumes) about each cache group, as the code excerpt in Listing 4 shows. Notice that the block of code at callout A in Listing 4 uses a trick to assign an array of values to a hash. This trick works because the order of the array is well known. However, the block would cause errors if the code didn't disable the use of strict for that block. The code excerpt that Listing 5 shows deletes and clears the cache (assuming you've directed the script to do so, as I explain later).
The DeleteUrlCacheFiles subroutine does essentially the same thing as the DeleteUrlCacheGroups subroutine but deletes individual cache entries as opposed to a cache group and is much more complicated than the DeleteUrlCacheGroups subroutine. Each cached entry contains information and attributes such as the date and time when the file was cached, the URL that maps to the entry, and the cached file's expiration time. Each cached entry can be a different size, so the script first allocates a 1KB buffer to the $pCacheInfo variable. The code excerpt that Listing 6 shows begins the enumeration process but must determine whether the buffer is large enough to hold the cache entry data. If the buffer in insufficient, the script reallocates the buffer. The script uses this strategy each time it accesses a cache entry. The code excerpt that Listing 7 shows uses the same technique as the code in Listing 4 to unpack the cached entry data into a %Cache hash. After extracting the cache data, the script determines the cache entry type (i.e., a cookie, URL history entry, or cached file).
The CleanDirectory subroutine makes a call to the OS's SHGetFolderpath() function. By passing in a class identifier (CLSID) value, the function returns the full path to a specialized directory such as the My Documents directory, the Recent File list, or the Temporary Internet Files directory. (For more information about how the script discovers paths, see the sidebar "Discovering Paths," page 16.) The function returns a Unicode string, and the block removes any NULL character in the string; this action can be a problem for paths that actually use Unicode characters. The subroutine then calls the CleanDirectoryAndFiles() function to remove files from the directory. If the deletion of a file fails, the script attempts to rename the file so that it can easily be identified for cleanup later.
The ClearRegistryKey() subroutine removes all values from a specified registry subkey. The script calls this subroutine several times to clear out the Run MRU list, IE's form data, and IE's Typed URL list.
The EmptyRecycleBin subroutine queries the machine's Recycle Bin for statistics (such as how many files are in the bins) and empties the Recycle Bins. When the script calls the SHEmptyRecycleBin() Windows function to empty the bins, the function passes in several flags to prevent a confirmation dialog box from being offered to the user. The flags also suppress any sound signaling that the bins are being purged and any dialog box showing the progress of such purging.
Running the Script
The script uses the Win32::API::Prototype module, which you can install using the Perl Package Manager (PPM). To do so, enter the following on a command line:
ppm install http://www.roth.net/perl/
packages/win32-api-prototype.ppd
This module relies on the Win32-API extension, which comes standard with ActiveState's build of Perl. You can also get the extension at http://dada.perl.it/#api and use PPM to install it with the command
ppm install win32-api
When you run the script without passing in any parameters, it will collect information regarding how much disk space the cache is using, how many items are cached, how many items are in the MRU list, and so forth. The script then will display a tally of this information but won't delete any items or clean out the cache. When you run the script with the /v parameter, the script's display will be verbose. When you run the script with the /s parameter, the script will run in silent mode and won't display any text; this parameter overrides the /v parameter. When you run the script with the /d parameter, the script will delete cached files, clear the cache database, and clear the other types of data I discussed earlier.
The success of the script depends on exclusive access to the cache database. If another process is using the WinInet library, the cache database might not be cleaned out fully. For this reason, you should terminate all instances of IE, including instances embedded in other applications such as WMP's Media Guide, before running the script. In addition, some poorly written services use the WinInet library and should be stopped before you run the script.
You might also notice that even after you run the script with the /d parameter, Windows Explorer's Run MRU list might not appear to have been cleared. Windows Explorer loads the MRU list into memory and doesn't necessarily reload it from storage. To show the cleared MRU list, terminate and restart Windows Explorer by logging off and logging back on.