I noticed that displaying a FolderBrowserDialog
resulted in assemblies from any shell extensions loaded on my computer to be loaded into my application's AppDomain
. This was causing problems for my application as an old version of a library my application uses was being loaded. I thought that a potential fix for this would be to open the FolderBrowserDialog
in a different AppDomain
and then unload the AppDomain to unload all of the shell extension assemblies loaded. For example:
public class Form1 : Form
{
public Form1()
{
var setup = new AppDomainSetup()
{
ApplicationBase = System.Environment.CurrentDirectory,
DisallowBindingRedirects = false,
DisallowCodeDownload = true,
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
};
var ad = AppDomain.CreateDomain("FolderBrowser", null, setup);
var type = typeof(MyFolderBrowserDialog);
var diag = (MyFolderBrowserDialog)ad.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);
diag.ShowDialog();
AppDomain.Unload(ad);
}
}
public class MyFolderBrowserDialog : MarshalByRefObject
{
public DialogResult ShowDialog()
{
using (var diag = new FolderBrowserDialog())
{
return diag.ShowDialog();
}
}
}
This didn't work though. The shell extension assemblies are still loaded into the application's normal AppDomain and weren't loaded into the new AppDomain as I'd expected would happen. As a test I created my own class which calls the native SHBrowseForFolder
function in Shell32.dll and found that making that call was what was causing the assemblies to be loaded.
So if sandboxing with AppDomains only works with managed code, how do you sandbox unmanaged code called with P/Invoke? I could see this as being a potential security issue if you are running untrusted code or at the very least a reliability issue as there is no way for you to know what assemblies might be loaded on a customer's computer just by opening a save or browse dialog.