Distribution of Interop files - c#

There are some bug fixes that have been done in a COM component. Each time I compile, a new interop file is generated along with the dll of the actual component (component.dll) where the fix has gone in. Is it necessary to release the interop file (interop.component.dll) along with the actual dll when releasing the fix to the customer.
Also, I would like to know what exactly does interop files have?

If the COM components interface remain unchanged then you will not need to replace the interop library.
Interop files are containing automatically generated wrapper classes for you COM interfaces, so you can call your COM components without worrying about the correct order and type of your method parameters.

Related

c# outlook addin vsto access OL2016 Interop while working with OL2010 PIA

We have managed to build an outlook addin for 2010,2013 and 2016. We have created an OL2010 vsto project and fiddled with the .csproj file(1*). The problem is that few types were added in 2013/2016 and we can't access them. We only want to access them if the respective OL version is used of course.
As far as i understand the whole thing:
The Interop assemblies are delivered with the addin. So its theoretically possible to inject some IL code or provide additional assemblies with the same namespace that provide those missing types. Since those Interop assemblies are only COM Wrapper and the functionallity relies on unmanaged code which is provided by the installed Outlook version they should get loaded seamlessly when imported correctly.
Is that somehow feasible?
What could go wrong if i try this/deploy the addin to the client?
How could i proceed to determine if i need to use a higher version Interop Type?
How can i load the higher Interop Type?
How can i use it without conflicting existing types?
As i want Intellisense and static typing. I have to predefine those types and decorate them with Guid, CoClass, and TypeLibType. Will that be enough?
(1*)(we changed the DebugInfoExeName and the OfficeVersion in the ProjectName.csproj file and built the respective installer with different virtual machines where the corresponding outlook versions are installed. Maybe there is an easier way? -> let me know!...sadly we can't use addin-express because of some reasons.
I would preferably not use the complete OL 2016 Interop Assemblies since it is throwing exceptions when used from other Threads than the main threads. And we have some synchronization code which has to be run in the background.
Thank you for any answers!
"Creating interops manually: In Visual Studio, just add a COM reference to an application of the Office 2000 suite to the project. This automatically creates the interop you need. But it is the point where your problem begins: a great number of classes and events are inaccessible, because a number of identical bugs in Office type libraries make Studio create the interop that will not work for you. You can disassemble the interop, make unavailable classes and events public, and recompile it (ildasm.exe and ilasm.exe). This is exactly the way Add-in Express version-neutral interops were created."
source: https://social.msdn.microsoft.com/Forums/en-US/a95cd4e3-e619-4846-be2a-ce4c235ff457/is-it-possible-to-use-the-microsoftofficeinteropoutlook-that-comes-from-office-2010-with-all?forum=outlookdev
EDIT
Checkout this project
https://github.com/netoffice/NetOffice-NuGet
It contains version neutral interop assemblies though the structure and namespaces dont match... But still could be useful.

Different Results from TLBIMP and AXIMP

I have a ActiveX COM control and its source code. I wanted to change one of the method's input parameter, so I changed the IDL etc and generated the COM DLL and TLB.
But when I imported the COM DLL in a .NET project the method had retained its old signature. So I tried to generate the ActiveX DLL using AXIMP (though it is all the same, I wanted to give a try).
Still the method's signature did not change to what I changed to.
But when I generated the interop DLL using TLBIMP from the TLB file generated, the method signature changed correctly.
Where can I be wrong?
Thanks.
There are a lot of manual steps involved so it easy to miss one. It rather depends on how you imported the type library, there's more than one way to do it. If you picked the reference from the Add Reference + COM tab then the likely mistake is that you forgot to re-register the new COM server. Or you accidentally picked the old one instead of the new one, which can happen when you change the guids, like you should, and forgot to cleanup the old one. Cleaning up is pretty important and easily missed since it needs to be done before you rebuild the COM server. You can end up with a lot of garbage in the registry.
And yes, using Tlbimp.exe directly is the most reliable way to avoid accidents. Since you run it directly on the type library and don't use the registry at all.
A recipe for having the least possible amount of trouble could look like this:
Unregister the old COM server first by running regsvr.exe -u
Delete the old DLL and TLB files
Change the IDL to add your new method
Assign a new IID for the interface you changed
Assign a new CLSID for the coclass that uses the interface
Increment the library version
Change the name of the output DLL, favor including the major+minor version in the name
Build the new COM server
Register the server with regsvr32.exe
Run Tlbimp.exe to generate the interop library
Remove the reference to the old interop library in your .NET project
Use Add Reference + Browse to add the new interop library
Skipping any of these steps can invoke build trouble, registry pollution, DLL Hell and having an all-around lousy wrecked day without getting anything done.

Using tlbimp without needing a second assembly?

I am trying to implement a COM interface in my C# dll for others to consume. I have defined an interface in foo.idl.
I've run foo.idl through tlbimp to produce foo.dll, a .Net assembly. Now to implement my interface, I can reference foo.dll in my dll to implement the interface.
This works perfectly as it stands with one exception: I now have to distribute two dlls instead of one. This actually goes against the requirements of the project I'm working on: deliver one DLL.
Is there a way to merge the tlbimp dll into mine, or any other way to do this (implement a COM interface in C# without the second dll)?
A good disassembler gets the job done, like Reflector. You can simply disassemble the interop assembly and copy the generated C# interface declarations into your source code. Of course you should only do this if the interface declarations and IIDs are stable.
And definitely consider upgrading to VS2010. Its "embed interop types" feature allows you to ship your assembly without the interop assembly.
You could probably cheat by using a .tlb instead of the 'glue' dll.
I'd suggest you create a mixed-mode assembly using MSVC++/CLR
http://msdn.microsoft.com/en-us/library/k8d11d4s(v=vs.100).aspx
Interop (How Do I in Visual C++)
This might have the drawback that you can't use C# in the same assembly. Should you want to add C# code to the mix, you might be able to squeeze out of your tough situation using
IlMerge
For other, possibly interesting, thoughts see my earlier answer:
Is it possible to compile a console application into a single .dll file?

Calling a c# COM server dll from a C# client app

I got an desktop application which uses a small DLL written in C# registered as an COM object to collect some infos from Active Directory. The app is written in C++, it works fine. I would like to write a small app in C# which would call the same registered DLL's methods (kind of testing tool), but can't figure out how to do this without referencing the COM DLL at compile time (I really need to use the COM registered dll)
I followed this article, managed to instantiate the object, but i cannot cast the instance to my interface created from IDL. Also the debugger knows the exact type of the instance with all members shown. I suspect this is due the DLL is loaded in the CLR as well.
Is this even possible?
thanks
You can't. The IDE will refuse to let you add a reference to the type library. You can fool it by using late binding. But that still doesn't fool the CLR, it won't create both a CCW and an RCW. You'll need a native client, like C++ or a scripting language to truly exercise the COM specific path.
There's just no point, just use the assembly reference directly and use normal C# code to test it.
You can consume a COM component from a C# project. The general steps are as follows:
Locate a COM component to use and register it. Use regsvr32.exe to register or un–register a COM DLL.
Add to the project a reference to the COM component or type library.
When you add the reference, Visual Studio uses the Tlbimp.exe (Type Library Importer), which takes a type library as input, to output a .NET Framework interop assembly. The assembly, also named a runtime callable wrapper (RCW), contains managed classes and interfaces that wrap the COM classes and interfaces that are in the type library. Visual Studio adds to the project a reference to the generated assembly.
Create an instance of a class that is defined in the RCW. This, in turn, creates an instance of the COM object.
Use the object just as you use other managed objects. When the object is reclaimed by garbage collection, the instance of the COM object is also released from memory.
For more information, see Exposing COM Components to the .NET Framework.
Detailed Article
I would suggest you use the .NET 4.0 dynamic type instead of all the mess of dealing with reflection in that article you mentioned

Running forms and VBA code from C# on an Access 2003 database

Pretty much what it says on the tin. I've tried googling around but can't find anything helpful.
I'm trying to automate a process and part of that involves running forms/VBA code from an access 2003 database. What's the best way to call these from C#?
The Primary Interop Assemblies let you to automate Access 2003 from your C# application. In particular, you should be able to use commands like DoCmd.OpenForm and DoCmd.RunCode, allowing you to run your Access 2003 forms and VBA code.
Create the VBA code in a separate COM dll, and then you can use COM interop to call from C#
For instance, see SO question: Using a COM dll from C# without a type library.
Exposing COM Components to C#
You can consume a COM component from a
C# project. The general steps are as
follows:
Locate a COM component to use and register it. Use regsvr32.exe to
register or un–register a COM DLL.
Add to the project a reference to the COM component or type library.
When you add the reference, Visual
Studio uses the Type Library Importer
(Tlbimp.exe), which takes a type
library as input, to output a .NET
Framework interop assembly. The
assembly, also named a runtime
callable wrapper (RCW), contains
managed classes and interfaces that
wrap the COM classes and interfaces
that are in the type library. Visual
Studio adds to the project a reference
to the generated assembly.
Create an instance of a class that is defined in the RCW. This, in turn,
creates an instance of the COM object.
Use the object just as you use other managed objects. When the object
is reclaimed by garbage collection,
the instance of the COM object is also
released from memory.

Categories