2

I use VCProjectEngine.dll, and there are 2 versions for Visual Studio 2010 and Visual Studio 2012. I want to replace the DLL versions dynamically i would unload the old version, and then to load the new DLL.

I understood from this post that I can't unload DLL, but unload all domain. So I try to unload the domain:

AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase = System.Environment.CurrentDirectory;
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
AppDomain domain = AppDomain.CreateDomain("MyDomain", adevidence, domaininfo);

AppDomain.Unload(domain);

and now I try to load the new DLL version:

AppDomain.CurrentDomain.Load(new AssemblyName("Microsoft.VisualStudio.VCProjectEngine, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"));

but it didn't help, Visual Studio 2012 doesn't know the VCProject type, because the old version is incorrect for it.

What's wrong in my code? or maybe there is other way to replace the DLL programmatically?

Community
  • 1
  • 1
  • Note that you should not use AppDomain.Load for this purpose. Have a look at this answer on how to load assemblies in a specific AppDomain http://stackoverflow.com/a/17324102/850119. – Panos Rontogiannis Jan 13 '14 at 09:11

1 Answers1

2

As you said, you can't unload DLLs -you can unload app-domains.

However, for unloading app-domains to work, you need to load the DLL in the domain you are unloading. In your example, you're unloading some app-domain, then loading the DLL in your app's default domain.

You should load the DLL inside that domain, and call its methods there. Note you'll need all your return values and arguments to be serializable, as they will be marshaled. This also means the objects exposed by your DLLs should be MarshalByRef objects.

zmbq
  • 38,013
  • 14
  • 101
  • 171
  • so, I need to replace `AppDomain.CurrentDomain.Load` with `domain.Load`? –  Jan 12 '14 at 12:03
  • 1
    Yes. And you need to call the DLL across domain boundries. – zmbq Jan 12 '14 at 12:06
  • 1
    How I call the DLL? I just want to declare static type of interface that exist in the DLL, like `VCProject pro=solution.Projects.Item(1).Object;` – user3114639 Jan 12 '14 at 12:09
  • You create an instance of a class in the DLL. That's what I meant by 'call the DLL'. All access to that instance will be across domain boundries. – zmbq Jan 12 '14 at 12:10
  • The problem is that those types exist in the old dll and in the new both, and the debugger take the class which appear in the old dll, instead of the new one. –  Jan 12 '14 at 12:16
  • How are you instantiating that class? You should use `AppDomain.CreateInstanceAndUnwrap` – zmbq Jan 12 '14 at 12:17
  • You are right, but I need to create static type of **interface**, so when I use `AppDomain.CreateInstanceAndUnwrap` I get an error `Constructor on type 'Microsoft.VisualStudio.VCProjectEngine.VCProject' not found.` –  Jan 12 '14 at 12:26
  • You can't create an instance of an interface, and interfaces do not have static members. You need to create an instance of a class and cast it to an interface. – zmbq Jan 12 '14 at 12:32
  • As I said, I don't want to create a **dynamic** type, but **static** type. like the example above: I put the `solution.Projects.Item(1).Object` in `VCPoject`- interface type. –  Jan 12 '14 at 12:37