Вот пара мыслей:
Насколько я могу судить по использованию Reflector.Net, это происходит в блоке finally сразу после фактического возврата диалога. Вот в основном, где вы получаете проблему:
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);
...
Если вы вообще не видите диалоговое окно, исключение, приведенное выше, вероятно, маскирует реальную ошибку. Попробуйте запустить с «Break on Exception» и отключите Tools-> Debugging-> Just my code. Код в блоке try выглядит довольно простым, и самое рискованное, что они делают, это PInvoke для SHBrowseForFolder в shell32.dll. Я был бы удивлен, если он генерирует «случайную» ошибку.
Если вы видите диалог и только после закрытия вы получаете эту ошибку, то вы можете просто проигнорировать ее за счет утечки памяти, когда это произойдет:
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)
...
Конечно, вы всегда можете P самостоятельно вызвать SHBrowseForFolder и не использовать класс диалога.