Isolation-mode (regfree) COM references defined twice (build error MSB3180) - com

I have several C# projects in one solution which reference some isolation-mode (regfree) COM DLLs. Some projects reference the same DLL, and when I build, I get error [MSB3180][1]: COM component 'SomeDll.dll' is defined in both 'Native.SomeProject.manifest' and 'Native.SomeOtherProject.manifest'".
The projects must reference the same COM DLL, since they both use it, and both are completely independent of one another. It gets more complicated since I want to support non-isolation mode for Debug builds.
Any ideas or suggestions?

All those projects could reference a new DLL that acts as a wrapper to the singular DLL that references the Reg-Free COM.

Related

Replace COM DLL with new managed COM Callable assembly

Is there a smart way to scaffold a COM callable .NET class library from an existing native COM DLL?
Scenario
Suppose you have a COM based C++ Win32 application and you want to replace one of the COM DLLs with something written from scratch.
Constraints
The new library shall be written in C#, targeting the .NET Framework (4.x)
No modifications to the rest of the existing unmanaged application shall be required.
No recompilation of the unmanaged code shall be required.
What I already know
You can create .NET assemblies which are COM callable.
You can import the type library IDL from an existing COM DLL.
Based on this question, what I want should be possible, even if arduous.
Question
Is there a smart / efficient way to generate the scaffolding code for a COM callable .NET class library with the exact same signature as an existing unmanaged COM DLL so I can replace the DLLs?
There does not need to be any implementation at first, every method could just throw a NotImplementedException for example.

COM "class is not registered" in case if using additional dll. How to debug this error?

The situation is that. I run Labview and from one via ActiveX pallet call my COM object method. And it works, I walk through my code with debugger.
But when I start to use (uncomment) code from side dll I see "class is not registered" error in Labview. My additional dll and its dependencies located in separate directory. So I tried to set PATH environment variable to this directory and after that run Labview. But is still doesn't work.
So the question is how to debug this situation? I looked through event logger but didn't found anything related.
P.S. I created my own synthetic application in C++ which calls the same method as Labview via COM too. And it works.
The problem was in hard defined base dll address. Labview used this address and COM dlls couldn't use that space.
I suppose report is incorrect ("class is not registered") because class is registered, but corresponding dll couldn't be loaded.

COM DLL c++ not visible in Object Viewer

i have create a c++ DLL with COM interface with Visual Studio 2013.
The DLL get's installed along with registration.
In the Ole Object Viewer, i can see typelibrary of this DLL with all
exported functions.
regsvr32 completes without any error.
Just within C# i can't use, because creation fails with error 0x80040154 -
class not found or not registered.
It is not a platform issue. The 64bit version is in system32 and the 32bit
version in syswow64 and they are registered there and typelibary information
in OLE Object Viewer confirms this.
But the class is not listed in the OLE Object Viewer tree.
Habe noe idea what's missing or wrong.
More over, i have a simliar VC++ project and this COM/DLL can be seen
in the view in the OLE Object viewer. It is compiled, linked
and installed in exactly the same manner.
I already compared all Compiler, Linker and MIDL settings, checked the .idl
file in the projects, the .rgs files... all seems to be the same, except
different names and guids.
So it is really strange: One is shown as COM object in the tree
of OLE Object viewer and can be used in C# program, the other not.
Please note: There is no compiler error in C# project using this DLL/COM.
There is a runtime error on creation 0x80040154.
Summary: i have to COM/DLL, both visual studion projects, deployed in the same
manner, the one can be seen in the OLE object tree and can be used in C#, the other not.
Are there any key points i could check and which are required for a successfull
listing as OLE COM object ?
PS: The only difference is the MSIL compiler version indicated in the type library view: The good COM/DLL has MSIL 7.xxx the bad one 8.xxx
but i don't know where at all to selected MSIL compiler. Both DLL/COM are built
by VS2013
OLE/COM Object Viewer shows the registration. When an application attempts to create an instance, there are further steps involved: registration points to server implementation, the library is loaded, class factory is located, class factory is called to created an instance. A failure in these steps results in instantiation failure nevertheless the registration itself is present and valid.
Your typical steps to troubleshoot the problems are:
Setting a break point in constructor of your COM class, in class factory construction, in DllGetClassObject exported function of your DLL, finally in its DllMain - to find out how close the system reaches trying to create an instance. Then step from there to get to the root of the problem.
Using Process Monitor to track registry/file activity around instantiation call and identify issues there (esp. if your DLL with COM server implementation is not even loaded).
If the class is not even listed in OLE/COM Object Viewer, then there is a problem even at registration stage. Your first troubleshooting attempt is to re-register manually and see if you have any registration error, or if it fixes the problem. There is a number of reasons for the registration to fail, a typical is that you have your COM class in your type library, however there is no implementation connected and referenced by OBJECT_ENTRY. With failed registration instantiation is expectedly not working because system cannot pick your implementation up and you see what you see: REGDB_E_CLASSNOTREG error code.
Found the problem: The typelibrary was not associated with object, because the typelibrary CLSID in .rgs file was different from that in .idl file, just by a space which was most likey introduced accidently.
in .rgs file:
TypeLib = s '{7DAA7049 -AAB2-4689-8635-FB6E03423F34}'
in .idl
uuid(7DAA7049-AAB2-4689-8635-FB6E03423F34),
Now i can use the DLL as COM in my C# project.
The COM/DLL was not listed in the object tree, because in the .rgs file was no name defined. This is a definition with name and this is the name of the COM/DLL in object viewer; the name follows to s which was previously empty (s'').
ForceRemove {4763F309-D922-227A-A1A8-CDFF29893BBD} = s 'myDllCom Class'

how to ildasm/ilasm round trip a dll exposing COM objects

I want to round trip a dll that exposes COM objects (interop).
With ildasm i dumped the dll.
In the ildasm dump i renamed all occurances of the class name.
An Ilasm with DLL switch and inclusion of the resources produced the new dll.
I dont know how to register this new dll (Win7).
Regasm/Regedit complains about a strong name.
What else do i have to adjust?
Thank you.
Seppe
A strong name for an assembly explicitly prevents you from doing this. Strong names were designed to detect somebody tampering with the code of an assembly, useful when the assembly is stored in an insecure location like a website. You are definitely tampering with the DLL so you'll break the strong name. Resigning it is required and that requires access to the private key that was used originally.
That said, there are some mitigating factors in the specific case of a [ComVisible] assembly. There isn't any way for an application to verify the strong name since the client of such an assembly is native code that doesn't know beans about strong names. The strong name is only required to allow the assembly to be registered in the GAC. Which in general is a good place for such assemblies since it helps to avoid DLL Hell.
So there are two things you can do to solve this problem:
Read the regasm.exe message carefully. It probably only displays a warning if you use the /codebase option. "RegAsm : warning RA0000 : Registering an unsigned assembly with /codebase can cause your assembly to interfere with other applications that may be installed on the same computer. The /codebase switch is intended to be used only with signed assemblies. Please give your assembly a strong name and re-register it." Which really means "You are about to commit yourself to DLL Hell". There are various degrees of DLL Hell, the name+location of the DLL is a fairly mild one. The far more important one is that the interfaces and classes get a new [Guid]. Which they'll automatically get since you changed the names, assuming that there is not a [Guid] attribute present in the original code.
Just sign the assembly with your own key, using sn.exe. Since nobody can actually check the strong name, any is good enough.
And do keep your eye on the ball, the actual name of the [ComVisible] interface and class names is immaterial in COM. Only the [Guid] matters, that's what the COM client uses to find the types back.

ActiveX Component Can't Create Object

I have VB6 ActiveXDLL called A.dll , I am referencing this DLL into my VB.Net Application.
Now I am calling a function of A.dll in this project. A.dll function is referring to the function of B.dll, C.dll, C.dll further referrer to Z.dll and so on.
when I am executing application it gives an error from B.dll that ActiveX component can't create an object.
My first thought would be to make sure all dlls are registered.
Assuming the ActiveX DLL is VB6 and you have access to the VB6 IDE, ensure the class's Instancing property is set to Multiuse.
Use OLE View (comes with visual studio) to browse ther TypeLib entry and check it has the correct GUID and that there is onely one registration. Can you create an object instance from the DLL with CreateObject? If not it is not registered correctly.
Also check any dependencies / references used by A.dllIf it can't find something then it's going to fail.These are the four common causes of the error:
1. You do not have a required TLB or ActiveX DLL/OCX file.
2. A TLB or ActiveX DLL/OCX needed by the project is present but not registered on your system.
3. The VB runtimes are an earlier version than the one you need to run the project.
4. A required TLB or ActiveX DLL/OCX file is corrupt.