views:

216

answers:

2

Our Windows file server has an archive service installed that "stubs" files that have not been accessed for a defined period of time. When a request for the stubbed file is sent to the server, the archive service replaces the stub with the original document and serves it to the user.

A major complaint about the archive service was that thumbnails for photos were no longer available. I decided to create a program in C# that would allow the user to select a folder and unstub all the files in it. It does this by reading the first byte of each file in the folder:

if (Directory.Exists(path))
{
    DirectoryInfo di = new DirectoryInfo(path);
    FileInfo[] potentiallyStubbedFiles = di.GetFiles();
    foreach (FileInfo fi in potentiallyStubbedFiles)
    {
        //ignore Thumbs.db files
        if(!fi.Name.Equals("Thumbs.db"))
        {
            Console.WriteLine("Reading " + fi.Name);
            try
            {
                FileStream fs = File.Open(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.None);

                try
                {
                    //read the first byte of the file, forcing it to be unstubbed
                    byte[] firstByte = new byte[1];
                    fs.Read(firstByte, 0, 1);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("An error occurred trying to read " + fi.Name + ":");
                }

                fs.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("An error occurred trying to open " + fi.Name + ":");
            }
        }
    }
    Console.WriteLine("Finished reading files.");
}
else
{
    Console.WriteLine("\"" + path + "\" is not a valid directory.");
}

It works well, but I have one small problem that I would like to resolve.

In Windows 7, when the FileStream is closed, Windows Explorer refreshes the file and shows the correct thumbnail, so you can see the thumbnail of each file as they are unstubbed. In Windows XP, however, Explorer does not refresh the files until the program exits, forcing the user to wait until all files have been unstubbed before being able to browse them.

Is there any way to force Windows XP to recreate the thumbnail for the file immediately after reading it? What signal is being given to refresh the files after the program closes? Or am I going about this the wrong way completely?

+1  A: 

There doesn't appear to be an interface with Windows XP. Vista and above introduce the IThumbnailCache interface.

Could you not delete thumbs.db and force it that way?

The format of thumbs is undocumented but there's a project at http://vinetto.sourceforge.net/ that attempts to understand it that may give some pointers if you want to delve.

Thanks for the answer, but changing thumbs.db won't give me a live refresh of the file thumbnail.
Torai
A: 

Try SHChangeNotify with SHCNE_UPDATEITEM.

Sheng Jiang 蒋晟
I spent a lot of time trying to get SHChangeNotify to work with no success. It would be a great help if I could debug the dll method call. Is there a way to do this?
Torai
be careful to pass the correct SHCNF_PATH parameter (e.g, SHCNF_PATHW for Unicode). Pass the pidl of the file if you can.
Sheng Jiang 蒋晟
Thanks. I got it working eventually. Here is the ShellNotification class that I can call refreshThumbnail(fi.FullName) from after unstubbing the file: http://pastebin.com/7VnfiKX6 It's a bit rough at the moment, but does the job. Other sources I used are: http://viewontv.codeplex.com/SourceControl/changeset/view/52406#939762 and http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3d9c048a-1bcc-4842-be7c-08b545cd456e
Torai
You are leaking the pidl. Use ILFree to free the pidl allocated in SHParseDisplayName.
Sheng Jiang 蒋晟