How do I consume a COM+ local server from C#? - c#

I have a web application from a company that has gone out of business. We're looking to extend the web app a bit with some asp.net functionality. The web app was written as an ISAPI application in Delphi, and uses COM+ to talk to the SQL Server and handles things like session management and authentication.
So, in order to get the current user and other details, I have to use the undocument COM+ components. I was able to dig out the type library and auto generated IDL, but at this point i'm lost in creating a .NET proxy class for this.
Is there a way to autogenerate the .net COM+ proxy either from the .dll itself (extracting the typelib info) or from the IDL?
Note: These seem to be simple COM style objects hosted in COM+ servers, no subscriptions or transaction monitoring..

You could use tlbimp.exe to generate C# proxy classes from your COM library.
tlbimp.exe myTest.tlb /out:myTest.dll
If you don't have the tlb it works also with COM dlls. Once the COM wrapper assembly generated you can reference it in your project and use the types inside as you would any other .NET class.
Possible location of tlbimp.exe : C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\TlbImp.exe or use the Visual Studio Command Prompt.

Run Tlbimp.exe on the type library to generate the .NET interop assembly for it.

Have you tried going to the references in your project, right clicking, add reference, then browsing to the dll. I think visual studio will generate the Runtime Callable Wrapper for you.

Related

.NET Core error on build: error MSB4062 Microsoft.Build.Tasks.ResolveComReference

I'm working on a .net core web app (targeting net461).
The app needs to reference a COM dll.
I added the COM reference and the app still builds on my dev machine.
However, on the build server it fails to build with this error:
C:\Program Files (x86)\dotnet\sdk\2.0.0\Microsoft.Common.CurrentVersion.targets(2604,5): error MSB4062: The "Microsoft.Build.Tasks.ResolveComReference" task could not be loaded from the assembly Microsoft.Build.Tasks.Core
After searching a bit, it seems like it's a pretty uncommon error.
Anyone know what the error is and/or how to fix it?
UPDATE: Seems like the dotnet CLI does not support COM references. Visual Studio uses msbuild directly behind the scenes, but on the build server, I was using the dotnet CLI commands.
WORKAROUND:
Reference the COM dll and rebuild. Visual Studio will generate an interop
dll. It will be named something like Interop.MyComDLL.dll. It is found in the build output directory.
Copy the generated Interop dll to somewhere in the application (I just
used a /dlls folder at the root application level).
Remove the COM dll reference.
Add a direct reference (Dependencies > Add Reference... > Browse in Visual Studio) to the Interop dll
It should also fail on developer machine if you try to build it using the same command as on build server, e.g.
dotnet.exe build Solution.sln --configuration Release --no-incremental
VS building solution using msbuild, it's a different way.
My suggestion would be to do any COM interop using dynamics, if you want to make it easier to change in the future, create an interface that that has all the COM properties and methods you need to access.
Create a class, implementing the interface, that creates the COM Object dynamically as part of the constructor. Then implement each of the methods and properties to access the the dynamic object you created.
This should remove any build time dependency, give an interface the rest of your code can depend on, and give an easy way out of the COM at a later date if required.
You might also find Rick Strahl's article for COM in .Net Core useful?
https://weblog.west-wind.com/posts/2019/Jan/22/COM-Object-Access-and-dynamic-in-NET-Core-2x
Hope this helps :)

How to make my C# DLL a self registering dll

I've created a COM object in C# that later get's used by a VBScript. In order for the VBScript to be able to instantiate the object it must be registered. Previously I was registering the object manually using RegAsm tool supplied with any .NET Framework.
However, I am now creating an installer so I can install this object on different machines and when I am using InstallShield 2012 Spring Express it is warning me that the dll is not self registering.
How can I make my DLL self register? I've found guides and examples of folks using the Process object in C# to call RegAsm, but my object is not an executable.
Custom actions and Self Registration is NOT a best practice.
If your version of InstallShield doesn't support COM Interop, run the command:
regasm foo.dll /regfile:foo.reg
Now import that reg file into InstallShield and tweak things file foo.dll to [INSTALLDIR]foo.dll.
If your version of InstallShield doesn't support importing reg files, edit in notepad and enter the values into InstallShield by hand.
This is the cleanest approach as you won't have any custom actions to fail and since MSI is handling the registration it knows how to uninstall and rollback the data.
If you are using InstallShield, you can ask InstallShield to register your typelibs. In Components -> YOUR DLL -> .NET Settings -> Set .NET COM Interop to Yes.
In case you are using a version of InstallShield that does not support this, write a custom action which calls RegAsm.exe to register your dll.

Creation of .Ocx File from a .Net Dll

I have a .Net Com Dll is it possible to use this dll and create .OCX file in c++ or MFC. If yes what are all the steps which needs to be followed. If any sample code is availabe that would be a great help
You could expose the .NET assembly as COM object using the regasm.exe tool. You could use the [ComVisible(true)] to indicate that all classes should be visible by COM clients when registered. This assembly level attribute could also be set in the properties of the project in Visual Studio. You could also apply it only to some classes that need to be exported. Once the assembly registered as COM object you could instantiate any class from unmanaged clients as with any standard COM object.
There is nothing particularly special about an .ocx file, it is just a DLL. Microsoft came up with that filename extension back in the Visual Basic version 4 days to make it obvious to VB programmers that they had a DLL that contains controls. ActiveX controls as opposed to VBX controls from the 16-bit days.
If you made the .NET assembly [ComVisible] then you already have a COM server that's usable in other projects. Provided you registered it properly, .NET assemblies must be registered with Regasm.exe instead of Regsvr32.exe. Done automatically in a .NET project with the Project + Properties, Build tab, "Register for COM interop" option. And at installation time with a Setup and Deployment project. If you need a type library then use Regasm.exe with the /tlb and /codebase options. Or Tlbexp.exe
If this really needs to be a traditional .ocx, in other words have controls, then you can use a Winforms UserControl or your own class derived from a Winforms control. Winforms automatically implements the plumbing to make classes derived from the Control class function properly in an ActiveX host.
If you're wanting to use a .NET library in normal C++, there are ways, mostly involving COM Interop. Microsoft has a whole section of MDSN dedicated to COM Interop: http://msdn.microsoft.com/en-us/library/6bw51z5z%28v=VS.71%29.aspx.
If the .NET DLL supports COM Interop, use that.
Try using VC++'s #import directive to read the .NET DLL in as a COM object. When compiled, VC++ should output a .tlh file and a .thi file (header and implementation respectively) which will be automatically compiled into your project. But this may or may not work depending on the DLL's construction, dependencies, etc.
Look at creating your own COM Interop .NET wrapper library that marshals calls to the base .NET DLL.

Statically link COM DLL in C# (avoid regfree)

I have perhaps a silly question:
We have a VC++ COM DLL (developed internally) and we have ported our main app to C# and used COM Interop, reg-free to access the COM dll. Everything works just fine with internal embedded manifest.
However, the friendly product-dev/marketing/sales want to minimize the package and include the COM dll directly. Somehow, someone became convinced that the app distro should include the exe only (since it's unmanaged we can't just ILMerge it in).
Since we have the tlb/lib of the COM, could we somehow statically link it, without porting the whole COM to C# managed re-work?
Thank you
P.S. Pardon my wording: the company was downsized and I am the Python guy who had to learn everything .NET in the last week or so since now I am doing my job and the job of 2 ex-senior .net developers
It looks like Costura can more or less do this.
https://github.com/Fody/Costura
It specifically has support for merging unmanaged assemblies (ie a C++ DLL) into a .NET assembly.
Note - this is not true static linking but would achieve the aim of packaging everything in the single EXE to be distributed.
It is possible to include the source for the COM DLL into the project for the exe, or you could change the COM DLL project into a static lib project. Once you've accomplished that, you must modify the code to create the COM objects directly. All said, neither options are particularly easy.
Alternatively you could look into products like Spoon Studio that would allow you to wrap your exe and COM DLL into one exe without any code.

.net component installer for COM interop

I have a .net component that will be called by unmanaged code. I want to create an installer for the .net component that will in one step..
-install it to the desired directory
-generate the tlb file
-run the regasm command
The deployers of this component dont have knowledge of the .net framework.
Any ideas?
Thanks.
The type library only needs to be deployed if you want your client to use the component themselves when they write their own code using your COM server. That's unlikely given your description of their skills. If required anyway, you are better off simply deploying the .tlb yourself instead of auto-generating it during install.
Your client won't have Regasm.exe on their machine, it is only available in the Windows SDK. Nevertheless, registering ComVisible components is a standard capability of MSI. You can create your own installer that registers the component with a Visual Studio Setup project. Set the Register property to "vsdrpCOM".
It's been a while but I think something like this would work:
Add an Install.Installer class to your component, override it's Install and Uninstall methods and use RegisterAssembly to register the Assembly.
Then create a Visual Studio setup project and add a custom action to run your Installer methods during the setup.
Actually, here's a thread discussing just this and there's a comprehensive answer in there: http://www.dotnet247.com/247reference/msgs/18/90440.aspx

Categories