title: AppDomain code to load DLL works in VB but not in C#
body: <p>Some time ago, I wrote a program in VB (called QueryViewer) that as part of it, loads dlls into a new app domain and executes them successfully.  I have since moved over to C# and converted this program from VB into C# but I've been never been able to get what I think is the correctly converted C# routine to work.  It always fails on the appdomain.CreateInstanceAndUnwrap call even though this code (in VB though) works fine.</p>
  
  <p>Here is the original VB code that works:</p>
  
  <pre><code>Imports System.Reflection
  Imports System.Security
  Imports System.Security.Policy
  Imports System.Security.Permissions
  
  Public Class ClassLocalLoader
      Inherits MarshalByRefObject
  
      Private _appDomain As AppDomain
      Private _clsRemoteLoader As classRemoteLoader
  
      Public Sub New()
  
          Dim strAsmName As String
          Dim adSetup As AppDomainSetup
  
          Try
  
              strAsmName = [Assembly].GetExecutingAssembly.GetName.Name
  
              adSetup = New AppDomainSetup()
              adSetup.ApplicationName = "Plugin"
              adSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
  
              Dim permSet As PermissionSet = New PermissionSet(PermissionState.None)
              permSet.AddPermission(New SecurityPermission(SecurityPermissionFlag.AllFlags))
  
              Dim ev As Evidence = New Evidence()
              ev.AddHostEvidence(New Zone(SecurityZone.MyComputer))
  
              permSet = SecurityManager.GetStandardSandbox(ev)
  
              _appDomain = AppDomain.CreateDomain("Plugin", Nothing, adSetup, permSet, New StrongName() {})
  
              _clsRemoteLoader = CType(_appDomain.CreateInstanceAndUnwrap(strAsmName, strAsmName &amp; ".ClassRemoteLoader"), classRemoteLoader)
  
          Catch logerrorex As Exception When TCA.Display.ShowLine(logerrorex)
  
          Catch ex As Exception
  
          End Try
  
      End Sub
  
      Public Sub LoadAssembly(ByVal strFilename As String)
  
          _clsRemoteLoader.LoadAssembly(strFilename)
  
      End Sub
  
      Public Function CreateInstance(ByVal bindingFlags As BindingFlags, ByVal constructorParams As Object()) As MarshalByRefObject
  
          Return _clsRemoteLoader.CreateInstance(bindingFlags, constructorParams)
  
      End Function
  
      Public Sub Unload()
  
          If _appDomain IsNot Nothing Then
  
              AppDomain.Unload(_appDomain)
              _appDomain = Nothing
  
          End If
  
      End Sub
  
  End Class
  </code></pre>
  
  <p>And now, here is the converted C# code that doesn't:</p>
  
  <pre><code>using System;
  using System.Reflection;
  using System.Security;
  using System.Security.Permissions;
  using System.Security.Policy;
  using KellermanSoftware.NetLoggingLibrary;
  
  public class ClassLocalLoader : MarshalByRefObject
  {
      private AppDomain _appDomain;
      private ClassRemoteLoader _classRemoteLoader;
  
      public ClassLocalLoader()
      {
          try
          {
              String asmName = Assembly.GetExecutingAssembly().GetName().Name;
  
              var adSetup = new AppDomainSetup
              {
                  ApplicationName = "Plugin",
                  ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
              };
  
              PermissionSet permSet = new PermissionSet(PermissionState.None);
              permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.AllFlags));
  
              Evidence ev = new Evidence();
              ev.AddHostEvidence(new Zone(SecurityZone.MyComputer));
  
              permSet = SecurityManager.GetStandardSandbox(ev);
              if (permSet != null)
              {
                  _appDomain = AppDomain.CreateDomain("Plugin", null, adSetup, permSet);
                  _classRemoteLoader = (ClassRemoteLoader)_appDomain.CreateInstanceAndUnwrap(asmName, asmName + ".ClassRemoteLoader");
              }
          }
          catch (Exception ex)
          {
              Log.LogExceptionEx(ex, "Exception raised while trying to load plugin.");
          }
      }
  
      public void LoadAssembly(string filename)
      {
          Assembly.LoadFrom(filename);
      }
  
      public MarshalByRefObject CreateInstance(BindingFlags bindingFlags, Object[] constructorParams)
      {
          return _classRemoteLoader.CreateInstance(bindingFlags, constructorParams);
      }
  
      public void Unload()
      {
          if (_appDomain != null)
          {
              AppDomain.Unload(_appDomain);
              _appDomain = null;
  
          }
      }
  }
  </code></pre>
  
  <p>The C# code fails with the following error:</p>
  
  <p>Could not load type 'QueryViewer.ClassRemoteLoader' from assembly 'QueryViewer, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null'.</p>
  
  <p>The call that is made that causes the failure is just the following:</p>
  
  <pre><code>    classLocalLoader = new ClassLocalLoader();
  </code></pre>
  
  <p>Anyone see anything wrong with my converted C# routine that would cause this to fail?</p>
  
  <p>Thanks,
  Don B.</p>