I need to write a plug-in for a MFC application:
- plug-in is deployed as dll.
- On the runtime, the MFC application will call the plugin and the plugin shows a custom dialog.
- the dll needs to be dynamically loaded, the MFC application should not be re-complied if the dll is updated.
I mainly code in .net and after playing with MFC, everything just seems too odd for me (no events/delegates etc). I'm fine to write a MFC dll but if I can do that in .net then I'll willing to give it a try. A possible solution is that I can write a C# dll and expose it as COM. Since I don't know anything about COM, here are my questions:
- Does the .net framework needs to be installed on client's machine?
- Can COM be dynamically loaded from a MFC application?
- I read something about registering the assembly with COM, does this happen on client's machine? (if yes, then the installer might need to be updated)
- Is it easy to use COM in a MFC application (this requires MFC devs to modify their code)
Or, given if there is too much effort to make the connection between .net, COM and MFC, would you suggest me to code in MFC? Thanks.
UPDATE:
I decide to use C++/CLI as a bridge between MFC and .Net. A mixed C++/CLI dll can be called from MFC application and the dll can utilize .net framework. Thus I can code the UI with C# in another dll and that dll can be called by C++/CLI.
References:
Native and .NET Interoperability
Integrate Windows Forms Into Your MFC Applications Through C++ Interop
Does the .net framework needs to be installed on client's machine?
Yes the frame work must be installed on the client's machine
Can COM be dynamically loaded from a MFC application?
It can, the MFC application will load your DLL dynamically, it can call it without being updated as long as your class's public interface doesn't change
I read something about registering the assembly with COM, does this happen on client's machine? (if yes, then the installer might need to be updated)
Yes the .NET COM object (or any COM object for that matter) must be registered on the client's machine. You can use the building setup project in Visual Studio do to that
Is it easy to use COM in a MFC application (this requires MFC devs to modify their code)
It should be reasonably easy, but that's more a question for the MFC dev's
Would you suggest me to code in MFC
Do you know C++ or MFC? If not it's probably a lot more work.
Another option would be to write the component in C++/CLR. It can expose unmanned functions/classes which would be directly callable from the MFC application.
Related
I have a WPF application, which I build as a dll COM component and install using installshieldLE, however I have some issues with some dependent dlls, when running my COM client.
My WPF dll references two other C# dlls (A & B) which reside within the same VS2012 solution.
My WPF dll has the register for COM interop option checked and provides a COM interface for running the WPF GUI application.
I have a C COM client program, which tests the WPF application. The problem I am having is that I need to include some of dll_A's referenced dlls, (which is a third party graphics package) in the folder of the client program for the application to run successfully. I don't have to include dll_A or dll_B in the local client directory.
Also, there are other (C) dlls referenced by the COM server dll and included in the installation that do not need to be present in the client directory, so this is difficult to understand.
I assume that this is not a WPF question but simply a question about com server installation in relation to other referenced assemblies.
I have output some debug messages in the primary dlls that confirm that the dlls A&B, along with the main COM dll are being run from the installation location. But I get exceptions further down the line when the third party dlls are missing from the local client folder.
Can someone help me troubleshoot this problem please. I can run the client program successfully from the installation location and am therefore certain that all required assemblies and dlls are present.
Thanks.
It sounds like you're encountering issues related to the DLL load path. A client application can load your COM DLL, but your COM DLL can't load its own dependencies (or dependencies of dependencies, etc) even through the dependencies exist in the same folder as the COM DLL. Is this correct?
If so, I believe this problem can be solved with a call to the AddDllDirectory function -- just have your COM DLL call this before loading any of its dependencies and call RemoveDllDirectory when it's done. For more information, see the Remarks section of the documentation for LoadLibrary.
The problem was caused by one of the referenced dlls being compiled using .Net 4.0, whereas the others were compiled using .Net 4.0 client. Recompiling with .Net 4.0 Client resolved the problem.
The problem seemed to occur when executing the application as a registered com component, with the client being executed from a different location. If the offending dlls were copied to the client directory, everything runs fine.
I have a C++ (Native code) DLL project developed for iOS and Android. I would like to port it to a C++ DLL (Universal Apps) to be consumed by a C# Universal Store Application. The code isn't HW dependent.
As a first step, before moving all the code, I created a small test solution as follows:
I created a C++ DLL (Universal Apps), myDll, that has a C++ Add1(int, int) function.
I created a C++ WinRT component (Universal Apps) that has C++ Add2(int, int) function.
I created a C# Universal Application, myApp, that calls Add2 which calls Add1.
Compilation passes OK, however when I run myApp the application crashes and report that myDll wasn't
loaded.
My questions are:
Is the scenario I described above possible? And If so, what can be the problem causing myApp to crash?
Is there a better way for me to port the iOS/Android C++ code to be consumed in a C# Universal Application?
Thx
1) Like Hans, my first guess is that you're not including the Dll in the apps package. If it's not deployed in the package it isn't available to be loaded. Since you can't add a reference to the DLL you'll need to add it explicitly:
Add the files to the project, open the files' properties in the Solution Explorer window, and mark them as content to be included in the app package.
Check that out is actually in the appx dir after you deploy.
2) That's probably the easiest. You could also include just the Dll and pinvoke. Either way you'll need to make sure the dll is valid for Windows Store apps
I have a .net solution with a C# project and a C++ project. The C++ project is an automation server (.exe). The C# project references an ActiveX interface produced by the C++ project (.tlb or registered interface on the machine). This works great on a development machine as I am registering the .tlb using regtlibv12.exe in a post build event in the C++ project. On the build machine, this fails because the service that runs the builds does not have rights to update the registry.
Is it typical to have the service that runs automated builds run as an administrator? Is there another preferred way to do this?
I also read that regtlibv12.exe is not always installed. Is there another way that is preferred to register a .tlb?
In a C# project just check if C++ application (automation server) is running and run it if not.
Then automation server (.exe) will register all available CLSID's in a system
I found no other way to register the type library in the build process other than using regtlibv12.exe. I had to make sure the automated build service is an administrator and everything works.
I am trying to get registration-free COM interop between a 64-bit COM dll and a C# app to work.
In the answers to a previous question of mine, I got help that allowed me to successfully call a HelloWorld method on the 64-bit COM dll for C#.
However, this was only possible by registering the COM dll globally using regsrv32.exe.
Based on this answer to a related question, I think that I need to set the Isolated flag on the reference of the COM dll to true. However, this leads to the following build error:
Problem isolating COM reference 'ComLibInteropLib':
No registered classes were detected for this component.
The answer to a question on MSDN social seems to indicate that there is a solution for this problem if one can compile a 32-bit version of the dll.
However, my COM interop library needs to link to a 'normal' C++ dll, for which I do not have the source and that is only available as x64.
So my question is: How can I enable the Isolated flag (or otherwise get side-by-side to work) between a 64-bit COM dll and a C# application?
I am happy to use regsrv32.exe on my machine or other developer's machine, but we cannot register any COM dlls on production machines, where the final application must run.
This is a side-effect of the original problem you had, the COM server wasn't getting registered properly. When you Isolated option to true, the build system auto-generates the required manifest entries for you. But the content of the manifest needs to come from somewhere, it uses the registry keys. Since they are not there, it can't generate the manifest.
You can write the manifest yourself but that requires enough insight in what the manifest should look like. With very high odds of making mistakes, the incantations are quite obscure. So avoid that, you just need to get the COM server registered to get ahead. Just on your build machine, it doesn't have to be registered on the client's machine since it will use the manifest.
You mentioned a 64-bit COM server, that's another possible failure mode. The build system is still 32-bit so you'll have high odds that it looks at the wrong keys. HKLM\Software\Wow6432Node instead of HKLM\Software. Battle that problem by building both flavors of the COM server. Beware of having the same kind of problem when you use Regsvr32.exe yourself, there are two of them. The one in c:\windows\syswow64 should be used to register the 32-bit version of the server, the one in c:\windows\system32 for the 64-bit version.
Is there a way to activate a COM component which is an EXE COM application and also it's dependent COM dlls? I want to activate this COM component from .NET application(VS 2005/VS 2008).
The path of call is C# application --> invoking out-of-proc exe(this is through COM) and then this out-of-proc invokes few COM dlls
Reg-free COM does not work for out of process components.
ActiveX EXE and ActiveX Document
project types cannot be used with
Reg-Free COM, as discussed in the
sidebar.
Simplify App Deployment with ClickOnce and Registration-Free COM
Look at Microsoft Forum Registration-Free EXE COM Server ?
So, There is no direct way to do this work whithot any additional code. As for me, the code still needs for classic registration to correct date marshaling.
Registration free activation is described here. Roughly speaking, it looks like you create your COM components and clients as usual, then put them all into the same directory with a manifest file which contains the COM registration information.