Strange issue with shell extesnsions.File returns after delete

370 views Asked by At

I am having a strange problem.I am using the Windows API Code Pack for Microsoft .NET Framework for displaying custom thumbnails for my custom file extensions.I have used the Microsoft.WindowsAPICodePack.ShellExtensions namespace methods as mentioned in the documentation and I can successfully show a thumbnail.But i am encountering a strange problem.While the shell thumbnail handler is registered, I cannot delete the file for which the thumbnail is shown.The file gets deleted alright for normal delete but while using Shift+del the file disappears form explorer without errors but will return when i refresh the folder.The file will stay there until I restart explorer.exe process or if I focus the window and wait for 60secs the file disappears on its own.The returned file doesn't allow to get deleted again giving an access denied error message.I tried using LockHunter and it shows that explorer.exe is locking the file.I am confused guys.What am I doing wrong ?. How can I fix this?.

I am using Windows 7 64 bit,visual studio 2010

My code is as follows

namespace CustomThumbnail
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("CustomThumbnail.XYZThumbnailer")]
    [Guid("439a0bd3-8a44-401d-931c-3021ad8b1ad6")]
    [ThumbnailProvider("XYZThumbnailer", ".xyz", ThumbnailAdornment = ThumbnailAdornment.VideoSprockets)]
    public class MyThumbnailProvider : ThumbnailProvider, IThumbnailFromStream
    {
        public Bitmap ConstructBitmap(System.IO.Stream stream, int sideSize)
        {
            try
            {
                LogMessageToFile("Hello Stream");


                XyzFileDefinition file = new XyzFileDefinition(stream);

                using (MemoryStream mstream = new MemoryStream(Convert.FromBase64String(file.EncodedImage)))
                {
                    LogMessageToFile("using Stream");
                    Bitmap bmp = new Bitmap(mstream);
                    LogMessageToFile(bmp.ToString());
                    return bmp;
                }
            }
            catch (Exception ex)
            {
                LogMessageToFile(ex.ToString());
                throw;
            }

        }

        public void LogMessageToFile(string msg)
        {
            System.IO.StreamWriter sw = System.IO.File.AppendText(@"D:\test\testdoc.txt");
            try
            {
                string logLine = System.String.Format(
                    "{0:G}: {1}.", System.DateTime.Now, msg);
                sw.WriteLine(logLine);
            }
            finally
            {
                sw.Close();
            }
        }
    }
}

New Code

  public Bitmap ConstructBitmap(Stream stream, int sideSize)
    {
        try
        {
            Assembly assembly = Assembly.LoadFile(@"C:\Users\xxxx\Documents\Visual Studio 2010\Projects\MyThumbnailTest\Bin\Data\Data.dll");
            Type type = assembly.GetType("Data.ThumbnailData");


            MethodInfo foo = type.GetMethod("GetThumbnail");
           var c= foo.Invoke(Activator.CreateInstance(type), new object[] { stream });

            return (Bitmap)c;
        }
        catch (Exception ex)
        {
            LogMessageToFile("error "+ex.Message.ToString());
            throw ex;
        }
        finally
        {
            stream.Close();
            stream.Dispose();
        }

    }

And my GetThumbnail Method goes like this

 public class ThumbnailData
    {
        public Bitmap GetThumbnail(Stream stream)
        {
            using (ZipFile zip = ZipFile.Read(stream))
            {
                ZipEntry image = zip.Entries.Where(p => p.FileName.ToLower().IndexOf(".png") > 0).FirstOrDefault();
                if (image != null)
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        image.Extract(ms);
                        Bitmap bmp = new Bitmap(ms);
                        return bmp;
                    }
                }
                return new Bitmap(150, 150);
            }
        }
    }
1

There are 1 answers

5
Richard Schneider On

Without seeing the code, this is all I can think of:

Is your custom thumbnail code not closing the Stream for the file after it produces the thumbnail?

As my comment suggested try this:

  public Bitmap ConstructBitmap(System.IO.Stream stream, int sideSize)
    {
        try
        {
            LogMessageToFile("Hello Stream");


            XyzFileDefinition file = new XyzFileDefinition(stream);

            using (MemoryStream mstream = new MemoryStream(Convert.FromBase64String(file.EncodedImage)))
            {
                LogMessageToFile("using Stream");
                Bitmap bmp = new Bitmap(mstream);
                LogMessageToFile(bmp.ToString());
                return bmp;
            }
        }
        catch (Exception ex)
        {
            LogMessageToFile(ex.ToString());
            throw;
        }
        finally 
        {
            stream.Close();
        }
    }