SecurityException, caspol and .net programs

If you’re trying to run your .net program from a network share you’ve probably found out the hard way about the security permissions for .net programs.

A helpful post by Chunsheng Tang pointed my to some useful articles explaining what the deal is and how to make my program work but I’m still unsure about what to do about making it work from an installer.

http://www.codeproject.com/KB/security/UB_CAS_NET.aspx

http://support.microsoft.com/kb/815170

http://msdn2.microsoft.com/en-us/library/2bc0cxhc(vs.80).aspx

For now I just want to prevent my program from dying with the embarrassing ‘your program has stopped working’ error.

My problem is primarily that the program dies before any of my code is executed so I can’t even setup an error handler. When the loader looks at my program’s dependencies it tries to load the dll’s in the same folder which causes a security exception.

My best idea at the moment is to use a loader program to load up the app dynamically so that it’s my code executing the assembly loading so that I can catch the exceptions and display my own error message.

A simple .net program with no external dll’s to load or files to read will load up fine. Then I try to run my program If it works then great, the program’s running; if not I catch the exception and display an error message explaining the situation.

Here is a snippet of my proof of concept to check that the idea would work. I still need to develop the idea to make it do everything I need but it does demonstrate that the idea works.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        AppLoader("MyApp", "Form1");
    }

    public static void AppLoader(string app, string className)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        bool loaded = false;
        try
        {
            RunApp(app, className);
            loaded = true;
        }
        catch (SecurityException)
        {
            Debug.Write("Security exception");
        }
        catch (Exception)
        {
            Debug.Write("Exception");
        }
        if (!loaded)
            MessageBox.Show("Unable to run from a network share");
    }

    protected static void RunApp(string program, string className)
    {
        Form f = null;
        bool found = false;
        Assembly a = Assembly.Load(program);
        Module[] modules = a.GetModules();
        foreach (Module m in modules)
        {
            Type[] types = m.FindTypes(Module.FilterTypeNameIgnoreCase, className);
            foreach (Type t in types)
            {
                if (t.IsSubclassOf(typeof(Form)))
                {
                    ConstructorInfo constructor = t.GetConstructor(Type.EmptyTypes);
                    if (constructor != null)
                    {
                        f = (Form)constructor.Invoke(null);
                        found = true;
                    }
                    if (found)
                        break;
                }
            }
            if (found)
                break;
        }
        if(found)
            Application.Run(f);
    }
}