Friday, March 26, 2010 4:14 PM
I hope I have the correct forum for this question.
Friday, March 26, 2010 5:05 PMModerator
Re 1) No idea. It depends on the application and which APIs it uses. There were breaking changes in .NET 4 and this application is likely hitting one. You have to debug it to find out more details.
Re 2) You can use COM objects from 3.5 which will be implemented in 4.0 and vice versa. However you cannot interact between 3.5 and 4.0 without the COM layer in between. They (3.5 and 4.0) don't know about each other. Check out more about in-proc SxS:
- Marked As Answer by Notre Wednesday, March 31, 2010 4:13 PM
Friday, March 26, 2010 6:10 PM
Thank you Karel for your comments! I'll review the various links you provided. I had another idea, that may equally not work, but I'd like to run it past you just in case.
I got the idea of creating a separate app domain. To test it, I created a WinForm project targeting .NET 2. I then created a class library targeting .NET 4. In my WinForm project, I added the following code:
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = "path to .NET 4 assembly";
setup.ConfigurationFile = System.Environment.CurrentDirectory +
// Set up the Evidence
Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
Evidence evidence = new Evidence(baseEvidence);
// Create the AppDomain
AppDomain dotNet4AppDomain = AppDomain.CreateDomain("DotNet4AppDomain", evidence, setup);
Assembly doNet4Assembly = dotNet4AppDomain.Load(
new AssemblyName("MyDotNet4Assembly, Version=184.108.40.206, Culture=neutral, PublicKeyToken=66f0dac1b575e793"));
My DotNet4AppDomain.exe.config file looks like this:
<supportedRuntime version="v4.0" />
Unfortunately, this throws the BadImageFormatException when dotNet4AppDomain.Load is executed
Thank you for any further comments you can give.
Friday, March 26, 2010 9:38 PM
After reviewing the links you provided, and based in particular on a comment Rick Byers made in the channel 9 video about thinking of CLR SxS as being between the AppDomain and process boundaries, I think the AppDomain idea I have above likely won't work either. (Although if you can confirm that either way, that would be great).
You mentioned that if I have a COM layer, then it should work. So, going back to my sample application above, I marked my .NET 4 assembly's class as ComVisible, did the RegAsm thing to register my component with the registry, and then installed the assemby into the GAC. Now, how can I:
1) Call this .NET 4 assembly's class as if it were a COM object from my .NET 2 runtime client application? I tried finding my .NET 4 assembly in the COM Add Reference tab of my .NET 2 class' project, but it doesn't show up. I used OLE/View, and also couldn't find my .NET 4 component's type library entry. Finally, I re-ran regasm with the regfile switch so I can see what is to being dumped into the registry. In the output reg file, I don't see any entries for HKEY_CLASSES_ROOT\TypeLib.
2) Assuming I could somehow reference and call my .NET based COM component from my .NET 2 based application, how would I specify that the COM component should load the .NET 4 runtime? Or would it magically figure it out somehow, since I compiled the .NET based COM component to target the .NET 4 runtime?
Friday, March 26, 2010 9:59 PM
I figured out why entries were not being added to HKEY_CLASSES_ROOT\TypeLib; I failed to include the "tlb" switch with regasm. Now, it shows up in OLE/View and I can see it in VS' COM reference tab. However, when I select COM object in VS's COM reference dialog tab, it says:
A reference to '<myAssemblyName>' could not be added.
The ActiveX type library '<path to type library file>' was exported from a .NET assembly and cannot be added as a reference.
Add a reference to the .NET assembly instead.
I think this behaviour is as designed. However, referencing the .NET assembly isn't going to work for me because of the multiple runtime versions involved.
So, I'm back to my original problem, where I can't directly reference or use reflection (even in a separate ApDomain) to an assembly in a different runtime. And I tried to fake having a COM layer in between as just described, but I can't get that working either. Please advise.
Saturday, March 27, 2010 2:01 AMModerator
2.0 runtime cannot load 4.0 assemblies, that's why your AppDomain trick doesn't work. 2.0 runtime also cannot reflect over 4.0 assemblies as it is newer format potentiallly breaking.
Check out this link: http://www.vistadb.net/blog/post/2009/12/03/How-Dot-Net-4-Side-by-Side-will-impact-API-writers.aspx
The Visual Studio error you got means, that you will have to do some extra manual steps: Manually create a COM import class in your main app for your COM export in your addin/library.
I will try to test it out on my VM once it is set up.
Saturday, March 27, 2010 7:01 PM
Thank you Karel. That makes sense re: app domains and .NET 2 runtime not being able to load 4.0 assemblies.
I eagerly look forward to the results of your testing. Assuming that what you suggest works, I would appreciate any guidance (e.g. web links) on 'manually creating a COM import class in your main app for your COM export in your addin/library', because I don't know how do do this.
- Edited by Notre Saturday, March 27, 2010 7:14 PM request help with COM import class
Tuesday, March 30, 2010 1:05 AM
I've created my own ATL based COM object, which I would use as the go between the .NET 2 runtime assembly and .NET 4 runtime assembly. I tried to export my C# based .NET 4 class to COM. I can get the ATL based COM component to compile and sort of reference the C# project, and I can see the type library but all the list of methods appears empty :( (Well, not completely empty - I get the standard IUnknown and IDispatch methods, but none of my application specific methods).
When I look at the generated .tlh file, I can see entries for coclasses, interfaces, smart pointers, etc. But when I look at any of the interfaces in the .tlh file, they appear to be empty. For example:
_Comment : IDispatch
Even though in my C# code, I had explicitly implemented an interface on the class, made the whole assembly ComVisible, assigned guids to the class and interfaces. All the methods in the class' (implicit) implementation of the interface are public.
I've been trying to follow this tutorial: http://msdn.microsoft.com/en-us/library/aa645738(VS.71).aspx
I'm not sure if the problem (not seeing methods) is related to importing mscorlib.tlb or something else I'm doing wrong. I remember from one of the videos that the .NET 4 runtime is separate from the .NET 2 runtime, even in separate DLLs. So, this might not be the right type library to import to make use of .NET 4 functionality...
- Edited by Notre Tuesday, March 30, 2010 1:56 AM provide info on .tlh file
Wednesday, March 31, 2010 4:13 PM
Good news - I got this working. I went with the ATL based COM object, as described above. I was able to resolve the problem of the 'empty' list of methods (other than IDispatch and IUnkown). The problem was that my .NET 4 code's interface was not made public (even though the class was public) and also I missed the Guid in the AssemblyInfo.cs file. After correctly these two problems, I was able to properly reference the .NET based COM object in my ATL code, and my .NET 2 runtime client was able to make use of the .NET 4 runtime code, by using the ATL COM object as a go between.
Thanks for your help, Karel!