Generation of .tlb Files in Windows 7 Pro 32-bit - c#

I have a C++ DLL that imports a .tlb file generated in a C# project. The C++ DLL is a wrapper DLL containing functions that call the corresponding C# functions.
When I call the C++ functions on the computer that I built the projects, all works well. But when I copy the DLL's and generated tlb's to another computer with the same exact version of Windows and installed programs andI call the C++ functions, it breaks with a COM error. However, after recompiling the projects on the new computer, everything works again.
I already checked the "Work on All Computers" for both projects but this keeps happening. What else do I need to do for the DLL's to work on all computers?

The HRESULT you get would be crucial to diagnose this. Forced to guess: did you run Regasm.exe on that machine? Required to make the necessary registry entries so COM can find the server. It is automatic when you build in the IDE.

Related

Using C# dll in C++ codes without using Regasm

I have created a C++ application which uses a C# dll following the link as shown below.
http://support.microsoft.com/kb/828736
The application works fine on my development PC , but when I tried to run it on another PC , it fails.
The only way to make it work is to recompile the C# dll on that PC and run the Regasm command again on that PC to work .
Is there a way to build my C# dll in such a way so that I do not have to do this every single time on every PC my application is deployed to ?
What regasm does is generate a COM wrapper for your C# dll and then registers it as a COM object.
You do not need to recompile though, once you have a dll you can register it on the target PC using regasm.
The main other way to call a C# dll is to write a C++ .net program using the C++/CLI system from Microsoft. This is basically a way of creating .NET programs using a superset of C++ (hint: its not C++, which is a shame as the old managed extensions it replaces was much more transparent for this task). As its not 'true' C++ you'll end up with a .NET binary instead of a C++ one, so be aware of this. One aspect is that you could write a C++/CLI wrapper to the C# dll and call that from your C++ program, this is probably the preferred way of creating a bridge between the systems.
I did this, and it worked, copy and paste the code on cmd
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\regasm.exe MyAssembly.dll
Kindly vote if it works for you. :D

Simple C++ .dll called with pinvoke; Works for me, but no one else

I do not know anything about C++, but I figured out enough to get a .dll written for a specific purpose, because there was some code I could not get C# to do.
So I created this DLL using Visual Studio 2013 -> Win32 Project -> Dynamic Link Library as the type, selected "Empty Project", etc.
Now I go over to my C# program and I have pinvoke sections to call this dll by name (Legacy.dll). I compile the DLL from C++, and copy/paste it from the /release folder to the /bin/release and /bin/debug folder of my C# application, and run the C# application.
It works fine. I have no issues.
However, when I send the files - the .dll and the .exe to other people, it tells them it cannot find the very same DLL. But it is clearly there, it is clearly working for me....
So what could be the problem? I am compiling both the C# program and the DLL to 32-bit.
UPDATE
The problem was that my users had the C++ libraries, but it had been sneakily updated to need the 2013 ones, which did not appear in my first search. I had to do an EXPLICITLY specific search to find this.
What's your operating system? Are you running a 32 bit or a 64 bit version of Windows? For .NET programs to load 32 bit native DLLs you'll have to ensure that you set the architecture of your .NET project to "32 bit" as well. By default it's on "Any CPU", which will pick the architecture based on the computer running the program. If you run the program on a 64 bit system, it will expect the native DLL to be 64 bit as well (which will cause the problem).
I know this sounds silly, but are you checking for the DLL in your C# program? (Sometimes users can be... 'interesting')
For example:
void Initialize()
{
var path = Path.Combine(Environment.CurrentDirectory, "Legacy.dll");
if(!File.Exists(path))
{
// Alert the user that the accompanying DLL is missing...
}
}
Other than that I would check architecture. Are you on 32-bit while they are on 64-bit OSes?

Deploying .NET COM dlls, issues when used on another computer

I'm kinda new to C# programming, and I'd like your help on something.
A quick review of what I have to do first.
I have to create : - A DLL that produces several .h5 files (HDF5 format) and one xml file
- A WPF viewer for the graphs that are written in these HDF5 files.
The problem is mainly that they are going to be used in a software called Panorama E², which basically manages DLLs, in a very restrictive way. For instance, it does not allow .NET framework 4 (Which makes me use the 3.5 version of the framework).
More info on Panorama : http://uk.codra.net/panorama/panorama-e2-information-system
I'm using HDF5DotNet.dll, that I compiled in x64 for .NET 3.5, and DynamicDataDisplay for my WPF application.
All my DLLs are going to be used by another computer, where Panorama is installed, and where Visual Studio isn't (only the 3.5 .NET framework and some required tools are).
What's the problem ?
Well, first, my WPF application isn't really one, Panorama doesn't seem to support WPF, only Windows Forms, and only as DLLs. Which means I created a WPF UserControl, that I embed in a Windows Form DLL.
I basically have 2 DLLs, one which is the WPF control, and one that uses this control in a winform. This is the last one that I have to integrate in Panorama. On my computer, the one I'm coding with, Panorama recognizes correctly the DLL and there's no problem.
But when I try to give these DLLs to my colleague, with his Panorama without Visual Studio installed, it doesn't work. After some tests, I noticed that it only works if the project (the DLLs) have been compiled on the same computer.
The same problem goes for the other DLL, the one that creates files. As I said, it uses HDF5DotNet.dll, but it seems it doesn't create it correctly. I guess it's the same problem, the DLL is not recognized.
What I tried.
I thought that maybe the DLLs weren't exported correctly. Maybe the referenced DLLs or assemblies aren't given, which are when you compile on the same computer. They're COM DLLs, because they're used in Panorama, and I can't manage to export them correctly.
I tried creating setup projects, so that they would be installed with their dependencies, but I couldn't find a way. Only the DLLs are installed. I tried looking at my DLLs with DependancyWalker, and there are some where dependancies are missing. Even if I try adding them manually, nothing changes.
I also know that regsvr32 doesn't work with .NET DLLs, because there is no entry point. That's why i thought about GAC, but I can't manage to register them (with strong name and everything), because I can't generate them directly.
So yeah, sorry for the long post, I tried to explain my train of thoughts and what I actually tried to do, but I can't find a way to give my projects to my colleague so that he can use them on his computer.
"Self Registration" ( be it RegSvr32, RegAsm or other ) is not a Windows Installer Best Practice. This injects out of process dependencies into the installation critical path that the installer is not aware of, that can fail and can't be rolled back or uninstalled.
The better approach is to use RegAsm /regfile to harvest the COM metadata for the ComVisible assembly and then author those registry values into your MSI's Registry table. This way Windows Installer merely has to copy the DLL and apply the registry values to register your component. It's far less likely to break and can be uninstalled and repaired cleanly.
How you do this exactly depends on the tool you are using to author your MSI. In WiX you'd use Heat to harvest this information. In InstallShield you'd set the .NET ComVisible attribute to True.
The end result is the same.
Hi try the following in command prompt instead of regsvr32 try the following :
"RegAsm.exe acxMaterialClassificationMerge.dll /codebase " where acxMaterialClassificationMerge.dll is your dll. You should do this on every pc thats going to use the dll. RegAsm is located in C:\Windows\Microsoft.NET\Framework\v2.0.50727
1: install first dotnet framework version 2 or newer on the computer
2: in command prompt :"RegAsm.exe acxMaterialClassificationMerge.dll /codebase " where acxMaterialClassificationMerge.dll is your dll. You should do this on every pc thats going to use the dll. RegAsm is located in C:\Windows\Microsoft.NET\Framework\v2.0.50727.

COM troubles between two versions of a C# Application

I haven't worked much with COM, so please forgive my ignorance.
Background: I am working on a project in VS 2010. There is a C# COM DLL integrated into the C# solution, and a Setup/Deployment project as well - the Setup project is set to register the COM .tlb file upon installation.
The problem: A previous version of the C# application, along with it's COM DLL, was present on a PC when someone decided to install the newest version of the C# application, and therefore the newest COM DLL. When this happened, it broke the COM functionality for both versions of the C# application..or that is what I am assuming has happened.
Is this typical COM/DLL-Hell behavior? When both C# applications are uninstalled, and then only ONE is re-installed, everything is back to normal - both apparently can't be installed at the same time.
I have tried changed the GUID for the COM DLL project, changing the AssemblyVersion and AssemblyFileVersion for the COM DLL project - all with mixed results. When I change those items, the new install of the application works (great), but now the old C# application doesn't have working functionality.
Note: there are no errors or exceptions thrown when the COM functionality is failing - the COM calls just seem to do nothing. So it is "silently" failing.
I have been researching this and trying various modifications to no real success...maybe I'm thinking about this the wrong way. Is there anyone else with more experience on this that could give me some insight?
You could use a merge module to install the com object and its successive versions. This would allow you to have multiple versions on the same machine. From Microsoft:
A merge module is like a snapshot of a particular version of a component. A new merge module should be created for each successive version of a component in order to avoid version conflicts.
Check out this link: Installer vs. Merge Module Recommendations

Working with .tlb files

I've created a c# com interop dll project that generates both .dll and .tlb files.
When I use them on the computer that I built everythig, all works fine.
But when I pass it to another computer (with the same windows installed), it doesn't work.
I allready made the:
Regasm.exe SoundLogDLL.dll /tlb:SoundLogDLL.tlb
command, but still doesn't work.
I also done the work in all computers in vs2008 before releasing it!
Is there anything else that I have to do?
After two weeks and lot of time spent, I've discovered what was missing:
Regasm.exe SoundLogDLL.dll /codebase
and all worked :)

Categories

Resources