How can I use .NET 4.7 assembly in .NET 2 project? - c#

I want to reference an assembly which is written in .NET 4.7 in a .NET 2.0 project in Visual Studio. I'm aware of a former practical solution to my question (here) but honestly I didn't quite understand that (I even read the solution in CodeProject). I even exported the assembly as COM (using tlbexp.exe), whenever I want to import that (using tlbimp.exe) or add a reference to, I got an error saying that I cannot use an assembly which is exported from a .NET assembly. Could someone please guide me through it from the first place? When I come to COM programming, I'm almost lost.

The only way I can see is you take the assembly compiled against .NET 4.7 and with COM-visible types and host it into a separate host .exe (thus making an out-of-process COM server). You'll need to read-up on this on how to create an OoP COM Server in .NET.
Your .NET 2 client .exe can then refer to the COM types registered by the host. As far as .NET is concerned it is talking to COM. The fact that it is .NET 4.7 under the hood is incidental.
You will end up with two processes talking to each other over a COM "wire". COM is a binary protocol and is language independent.
I even exported the assembly as COM (using tlbexp.exe), whenever I want to import that (using tlbimp.exe) or add a reference to, I got an error saying that I cannot use an assembly which is exported from a .NET assembly.
You would not have been able to to this because you are mixing a .NET 2 process with 4.7 types (in-process COM). That's why we went out-of-process.
Remember, your .NET client will have to add a COM-reference and not a .NET assembly reference. Treat everything as COM and it could work.
Note:
As per TheGeneral's point below, you may need to ensure that the .NET 2 CLR is installed on the client machine as well as .NET 4.7

Related

How To Create A VB Backward Compatible ActiveX COM DLL (w/ DllRegisterServer Entry Point) In C#

I did look at the following question, however, it doesn't resolve my issue.
- Unable to register DLL using Regsv32 - error "Dll was loaded but the entry-point DllRegisterServer was not found"
Unable to register DLL using Regsv32 - error "Dll was loaded but the entry-point DllRegisterServer was not found"
The problem I am facing is that a new DLL created w/ C# has to literally work within a legacy POS system running in Windows XP .NET 4.0 that was originally created with Visual Basic 6.0, which automatically created all of the proper entry-points (such as DLLRegisterServer) within the DLL assembly. However, these ActiveX COM entries, since they are no longer used, are not created with C# in Visual Studio 2012/2013. So, my question is, How can I create a Windows XP .NET 4.0 (VB backward compatible) ActiveX COM DLL with C# in Visual Studio 2012/2013, to replace the original VB DLL ? Can these entries be entered manually (& successfully compiled) in the C# DLL (i.e., using ???.??? STDAPI DllRegisterServer(void) { return true; }) ?
Your terminology is a little confusing: there is no such thing as "Windows XP .NET 4.0", but it sounds like you want to use .NET 4.0 on Windows XP. That would be OK. Note that your POS must be running Windows XP SP3. Note that .NET 4.5 and above are not supported in Windows XP. Your new DLLs must be compiled under .NET 4.0 or earlier. There are special complications if your POS software already uses .NET for anything else. I'll assume here that you are using .NET 4.0 and that the POS doesn't otherwise depend on .NET.
You do need to install on the POS machines an appropriate version of the .NET runtime (the version under which your DLL has been compiled is the best choice). But after that - yes, of course RegAsm will allow you to register a COM DLL (not RegSvr32 however; RegSvr32 doesn't know how to register a .NET DLL). As I mentioned in a my previous comment, the details in the registry will necessarily be different from the details for the VB6 DLL.
The installers for the different supported .NET runtimes are available from Microsoft. There are two options:
The ".NET 4.0 Client Profile installer" is currently available here:
http://www.microsoft.com/en-us/download/details.aspx?id=24872
The "Full .NET installer" is currently available here:
http://www.microsoft.com/en-us/download/details.aspx?id=17718
If you can help it, you want to compile your DLL using the ".NET 4.0 Client Profile" option, which is a subset of the whole runtime with only the most commonly used features. The Client Profile is significantly smaller. You will know immediately if your application is compatible with the Client Profile simply by trying to compile it with that option. If you are using something that is not included in the Client Profile, your DLL will fail to compile. In that case, try first to see if you can accomplish the same functionality without using the non-client-profile feature. If you can't, then use the full runtime.
Now the hard part: you don't specify if your DLL exposes a bunch of custom interfaces, whether it only consumes interfaces declared by the application, or a combination of both. You also don't specify how the POS software knows about your DLL and whether it uses Automation (IDispatch) like VBScript would or "custom" interfaces, and you don't say who declares the interfaces. Setting up the appropriate interfaces in C#/VB.NET can be a tricky problem because VB6 doesn't exactly make it easy to look at the details.
You can pull the most critical information from the existing DLL by registering it and looking at the resulting classes via the "OLE View" tool. The rest of the details will depend on how the main POS application uses your DLL. The full details of what to do can be complex and are well outside of the scope of any one single answer in Stack Overflow.
So basically you are trying to create dotnet based COM component. Set your project property as COM visible and Register your assembly using Regasm
regasm myDotnetCOM.dll
OR
regasm /codebase myDotnetCOM.dll
Now you can use CreateObject for this COM component.

install a c# com dll for use by vbscript classic asp website

I have a Classic ASP website with vb6 dll's and all is ok with the world, but now I have some extra functionality that has been completed using c# into a COM DLL. In the dev environment this is working, but now I wish to move this DLL onto another machine.
My question is what is the best way to do this?
I have seen answers such as "add it to the GAC" or, "in needs a strong name", etc.
What happened to the good old regsvr32?
Regsvr32 is still relevant today but you can't use it with .NET, only native DLLs. .NET has a special way to register COM-types as we shall soon see.
Regsvr32 works by invoking the DllRegisterServer export. DllRegisterServer gives the library a chance to register COM classes; type libraries; interfaces etc. This export is not present in .dlls created by .NET which makes sense because they are not COM by default. You can easily see these differences if you open up a .NET or non-.NET .dll in Dependency Walker/Viewer.
Here's a native c++ ActiveX dll I made earlier (Note the DllRegisterServer export on the right):
And here is a managed .dll. (Note there are no exports let alone DllRegisterServer):
If you have marked your c# class as COM-visible then you can complete the COM-registration by invoking:
regasm assemblyFile[options]
Tell me more
This will place the necessary entries into the Windows Registry.
There is no need for the GAC because native COM clients (VB6) do not use the GAC

Loading DLLs with Microsoft Visual C# 2010 Express

I'm using Microsoft C# 2010 Express with the FrameLink Express drivers from Imperx. When I try to load the DLL at runtime, I get an exception:
Unable to load DLL 'VCECLB.dll': The specified module could not be
found. (Exception from HRESULT:0x8007007E)
If I try to add the DLL as a reference, I get this message:
A reference to 'C:\\VCECLB.dll' could not be added. Please
make sure that the file is accessible, and that it is a valid assembly
or COM component.
Two questions:
Is this an Express problem (i.e. some limitation with Express causing the problem)? I believe the source for the DLL is written in C++, but I wouldn't think that would matter.
Is there a different way to reference the DLL and/or add it to the project? Something I'm doing wrong?
Finally, I've tried adding both the x86 and x64 versions, debug and release. Same failure to add as a reference every time.
That DLL doesn't seem to be .NET (nor COM) code - therefore you cannot load it, nor add a reference to it.
Doesn't have anything to do with your Express version - it's just not a .NET "compatible" DLL and thus you can't load or reference it.
In order to use its functionality, you'll probably have to dive into more "arcane" (and more elaborate and more complicated) methods of calling raw C++ code from .NET - or find a .NET compatible counterpart or version of it.
Actually, the answer appears to be in the first line of the message:
Unable to load DLL 'VCECLB.dll': The specified module could not be found. (Exception from HRESULT:0x8007007E
It says it cannot find the DLL, not that the DLL is not compatible.
The DLL should be located with the other DLLs with your program, and you need to add the DLL to the solution.
If by some chance the DLL is compiled as Native C/C++ (i.e., Not .NET style), it can be called from a C/C++ that is a .NET style, but not a C# routine.
So, if the problem is that the module can be found but not loaded, you need to write a C++ (.NET) routine to call from your C# routine (.NET) to call the C++ (Not .NET).
All code that talks directly to hardware must do this at some level. Most do this for you using multiple DLLs.

Call .NET 4.0 WPF Class Library From .NET 2.0 Application

I have an application written in .NET 4.0 that i compile into a DLL file. I want to be able to use this DLL file in a Windows Forms .NET 2.0 application. I don't need the application to really interact much, except just passing a couple string values to the 4.0 DLL. The DLL is pretty much a bunch of Windows which i converted to UserControls and i just need to be able to reference them to display the UserControls from the 2.0 application without having to use a different exe and having to package them separately. What is the best way to do this? Because when i try to add the reference to the DLL to the 2.0 application, it gives me and error saying the DLL is built in a newer version of .NET so i can't do it that way. Is this where a COM object would come in? Any information and links i would really appreciate, thanks.
If the application can really and truly be called from a 2.0 application then the best approach is to compile it as a 2.0 application. Visual Studio 2010 (and 2008) support the notion of multi-targetted solutions. That is you can use it to compile a project for various versions of the CLR.
I would take the approach of compiling my application twice
Once for 4.0
Once for 2.0
This way you can use the DLL directly in your 2.0 application. No messy COM tricks needed
Calling a .ne 4.0 from a .net 2.0 is indeed possible. The problem is not that, but i dont think you can send the usercontrols across!
Im doing this in a couple of soultions where im passing simple classes from 4.0 to my 2.0 assemblies. The trick is to register the 4.0 assembly as a ServicedComponent (COM+), then share an interface (.net 20) betwewen these assemblies. Then in your .net 2.0 assembly instantiate the ServicedComponent and retrieve an instance of your interface from the "middleware" assembly.
As stated, you can only transfer interfaces through this, and marshalling a complex type as a UserControl i think will be very difficult.

How to use com components

i hav created a COM component using vs2005 .
Now let me know can i use the dll which i have create on vs2005(which uses f/w 2.0) in vs2003(which uses f/w 1.1)??
I assume your real question is wether or not you can mix .NET versions in a single app as long as they use COM to interact.
I believe the answer is "no". An AppDomain can only have one .NET runtime loaded. Multiple runtimes is a feature of .NET 4.
In .NET projects add a reference into the "references" branch of the solution and a using directive into each file you want to use that component. In C++ projects use import directive.

Categories

Resources