Mihailik had a good suggestion for how to do COM interop in C# the the comments to a previous post that I'd like to share.
In many cases, TLBIMP produces a wrapper that can be used directly, and that's certainly the easiest way to do things.
But sometimes it doesn't make the right choice in how to express an interface. I ran into two situations yesterday:
In the first one, tlbimp produced an interface where an output string got the type of "ref ushort". In the second one, the designers of the interface decided that they would type a parameter as a byte* to point to lots of different kinds of data, and tlbimp typed that as "ref byte".
So, it meant I needed to tweak the parameters on the interface definitions. The hard way to do this is to write the interface definitions by hand. It's not much fun. Or, you can run ildasm, make the tweak, and then use ilasm. Also not a lot of fun.
The easy way - that Mihailik recommended - was to use Lutz Roeder's excellent .NET reflector, point it at the assembly that TLBIMP generated, and then use the disassembly feature of Reflector to get C# code. Paste the code into a source file, make the necessary tweaks, and Bob's your uncle.
With a few caveats...
First, the full richness of COM cannot be expressed in C#, so it's possible that you'll come across an interface where the C# version doesn't work correctly.
Second, you may come across some little thing's that don't quite mesh with C# syntax. I came across a case where an attribute wasn't legal in C#, and several where a derived interface restated the base interface's members (taken care of by adding a "new" to the derived interface definition).