I am randomly getting InvalidCastException when showing FolderBrowserDialog and also many clients have reported this.
I have not been able to find anything relevant on the internet. Does anyone know what causes this/how to fix this?
My code:
        using (FolderBrowserDialog fbd = new FolderBrowserDialog())
        {
            fbd.ShowNewFolderButton = false;
            if (fbd.ShowDialog() == DialogResult.OK)
Stack trace:
Error: System.InvalidCastException: 
'Unable to cast object of type 'System.__ComObject' to type 'IMalloc'.'.
    Stack trace:    
at System.Windows.Forms.UnsafeNativeMethods.Shell32.SHGetMalloc(IMalloc[] ppMalloc)
at System.Windows.Forms.FolderBrowserDialog.GetSHMalloc()
at System.Windows.Forms.FolderBrowserDialog.RunDialog(IntPtr hWndOwner)
at System.Windows.Forms.CommonDialog.ShowDialog(IWin32Window owner)
at System.Windows.Forms.CommonDialog.ShowDialog()
EDIT: Additional information: I have been able to reproduce this only when running in VS2008 debugger.
When running out of debugger, it happens only very rarely (happened once or twice in 6 months) on my 64 bit Windows 7 and goes away after restart.
The clients are certainly not running the app in debugger so it is surely reproducible out of debugger.
Here is a couple of thoughts:
As far as I can tell from using Reflector.Net this is getting thrown in the finally block just after the actual dialog returns. Here is basically where your getting the problem:
IntPtr pszPath = IntPtr.Zero;
try
{
    UnsafeNativeMethods.BROWSEINFO lpbi = new UnsafeNativeMethods.BROWSEINFO();
    hglobal = Marshal.AllocHGlobal((int) (260 * Marshal.SystemDefaultCharSize));
    pszPath = Marshal.AllocHGlobal((int) (260 * Marshal.SystemDefaultCharSize));
    ... /*init structure*/
    pidl = UnsafeNativeMethods.Shell32.SHBrowseForFolder(lpbi);
    if (pidl != IntPtr.Zero)
    {
        UnsafeNativeMethods.Shell32.SHGetPathFromIDList(pidl, pszPath);
        ...
    }
}
finally
{
    UnsafeNativeMethods.IMalloc sHMalloc = GetSHMalloc(); /* Boom! */
    sHMalloc.Free(zero);
    ...
If your not seeing the dialog at all the exception above is probably masking the real error. Try running with 'Break on Exception' and disable Tools->Debugging->Just my code. The code in the try block looks pretty basic, the most risky thing they are doing is PInvoke on shell32.dll's SHBrowseForFolder I'd be surprised if it's generating a 'random' error.
If you are seeing the dialog and only upon closing do you get this error then you could just ignore it at the expense of leaking memory when this happens:
    using (FolderBrowserDialog fbd = new FolderBrowserDialog())
    {
        fbd.ShowNewFolderButton = false;
        DialogResult r;
        try { r = fbd.ShowDialog(); }
        catch (InvalidCastException) 
        { r = DialogResult.OK; /* you might check the path first */ }
        if (fbd.ShowDialog() == DialogResult.OK)
            ...
Of course you can always PInvoke the SHBrowseForFolder yourself and not use the dialog class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With