COM application referenced dlls troubleshooting - c#

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.

Related

COM CLASS Library . ASP.net MVC DLL

Is there a way to make a COM or Interop work on IIS Server Deployed ASP.net MVC?
I created an MVC Site which have a reference to a custom maid Interop COM to a scanner machine.
It works on Debug mode on VS but, when I try to deploy it on IIS and access it. It gives me Retrieving the COM class factory for component with CLSID {3FEDB614-C25B-448C-AED3-2D38A6C95765} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
The Thing is, the dll it self is already installed on my Machine, I think it is working on debug mode cause the IIS from VS is running differently or because I have a reference of the DLL needed.
But in IIS Deployment. Error Occurs. Any Ideas?
My main goal here is, to run the site on a Local Network and everyone can communicate with that site that has the Scanner Installed on.
Easy Idea, but hard implementation for me. And I am not even sure, if the call that I am doing is going to be made in the Host, rather than the Client.
Looks like IIS application Bin folder doesn't have Interop dll, copy the Interop dll, it's named as Interop.[YourCom].dll. YourCom is nothing but original COM. So if the COM name is MyCom.dll, so Interop should be Interop.MyCom.dll. If it's working on Debug mode on VS, then it should be available in VS application Bin folder.
Prerequisite of Interop dll: COM should be register in same the system.
It ends up that, Even Registering it Manually, doesn't Help in my case, don't ask I HAVE NO IDEA WHY.
I resolve it by letting the VS studio Project Settings/Build Tab/ Register COM check mark do the Rest. But the trick is to Run VS in Administrator or you will have an error. Last step is right clicking the bin Folder and choosing add to project. Not really sure why it didn't work without it, because I am pretty sure it doesn't need to be in the current project since IIS will redirect anyway in the bin folder.
Interop name is already applied but like Maiti says, it is needed.

FileNotFoundException when calling remote C# dll from C++/CLR

My project is a plug in for a platform which is built in Native C++. And the plugin will reuse the current functionalities of an existing C# project, which is built upon .NET framework 4.0. We use the C++/CLR as the bridge to call C# codes. That is, the host application, built in unmanaged c++, calls into managed C++ dll which calls into C# dll.
The platform will run in one process and the plugin will run in another process.
And the way for the platform to find the plugin dll is that user will input a directory in the platform's user interface, thus the platform the load all plugin dlls in that directory into the plugin process.
This works well when my plugin folder is a local folder. However, when I set the plugin folder as the remote folder, and when I tried to instantiate a C# class from C++/CLR class, I got a FileNotFoundException, the detailed information is "Unknown URL protocol".
Our plugin project has both C++/CLR and C# codes, built into different dll files. In Debug mode, in the Visual Studio Modules view, it turns out that C++/CLR dlls are loaded while C# dll not loaded(both are in the app directory). And the exception happens when I tried to instantiate a managed class in C++/CLR codes, however, unfortunately there’s no stack call when I got the exception.
So how can I allow the host plugin process to load the remote C# dll properly?
After further investigation, we found the root cause is that the plugin's ApplicationBase is not set correctly. For some reason, if the folder is set as a remote folder, the platform passes the folder in Linux format rather than windows format, and our software is running on Windows only. This is why "FileNotFoundException" is thrown and it works well when my plugin folder is a local folder. We need to correct the ApplicationBase in windows path format.

What is the preferred way to register a .tlb on a build machine?

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.

Registration-free Interop between a 64-bit COM dll and a C#/.Net application

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.

Running App on dev machine won't run when deployed

I have a simple C# 4.5.1 x64 application which calls unmanaged dlls via a /clr C++ wrapper. App runs fine on my development machine. If I copy to Windows Server 2008 or Windows Server 2012 (with Framework 4.5.1 installed) I get an error that the wrapper won't load.
I have installed DependencyWalker on the deployment machine and I get this:
LoadLibraryExW("MyWrapper.dll", 0x000.., LOAD_WITH_ALTERED_SEARCH_PATH) called from ...
Loaded "MyWrapper.dll" at ... Successfully hooked module.
Loaded "XX.dll" at ... Successfully hooked module. (Dependency for MyWrapper.dll)
Loaded "YY.dll" at ... Successfully hooked module. (Dependency for MyWrapper.dll)
Unloaded "MyWrapper.dll"
Unloaded "XX.dll"
Unloaded "YY.dll"
LoadLibraryExW("MyWrapper.dll", 0x000.., LOAD_WITH_ALTERED_SEARCH_PATH) returned null. The specified module cannot be found.
Does anyone know why everything is loaded then unloaded and then cannot be found?
Make sure you have all the necessary redistributables (vcredist.exe) installed and you deploy a release build.
Any unmanaged c/c++ dll and also c++/cli dll links to msvcr. It is automatically installed with Visual Studio on the developer machine. It must be installed on the deployment machine together with the app. Make sure to redistribute the correct vcredist.exe version which corresponds to your version (and service pack) of VS. For vs2008 it resides in %ProgramFiles%\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages). Note: Dependency walker does not show missing dll if it is loaded using LoadModule() or methods are loaded using [DllImport("Sample.dll")] in c#. In that case, open the unmanaged dll directly in Dependency walker and check missing deps. Make sure, unmanaged dll is in search path of your app.

Categories

Resources