tags:

views:

163

answers:

2

I'm trying to add a generated COM interop assembly project to my solution, and the only solution I could come up with feels really nasty.

I created a .net dll project, removed all .cs files from it and then created the following post-build event:

call "$(DevEnvDir)..\tools\vsvars32.bat"
midl.exe $(ProjectDir)relative-path-to-my-idl\MyComName.idl /tlb MyComName.tlb
tlbimp.exe /keyfile:path-to-my-key\k.snk MyComName.tlb

Essentially, I first create an empty DLL, then overwrite it with a real interop DLL. And there's no dependency management here - it's created every time.

Is there a better way to do this?

+1  A: 

You can overcome the dependency problem by using MSBuild tasks directly instead of a PostBuild batch file, which line up nicely with the MSBuild dependency system.

However, why are you generating the file manually from an idl? When I need COM interop, I just import it and put the generated assembly (*.Interop.dll) into version control. This way, you always have the version you need and it's already ready to use, and Visual Studio can find the interop DLL before the first build, i.e. Intellisense is there right from the beginning.

Now some people won't like to check in a binary file, which I typically agree with, but well, if it works... :)

Of course, my method won't work if building the COM server is part of building the solution. In this case, just try to put the generation into the MSBuild script to get rid of the dependency thing, unless Visual Studio accepts a reference to a solution-internal non-.NET-COM project.

OregonGhost
+1, keep it simple: check it in.
csharptest.net
But I'm not building it manually, I'm building it automatically. I check in .idls and not interop dlls for the same reason I check in .cs files and not .exe/.dlls - that's what the build system is supposed to do for me. It manages dependencies and builds (and re-builds) those modules whose dependencies have changed.If I check in the generated interop DLL, now **I'm** responsible for re-building when changes occur.Sadly, it's hard to do things the right way with Visual Studio, so I may have to do this.
Mark W
If the build system should do that for you, then the right way is to do this in a MSBuild file (you can even use the csproj for that). This is a life saver if VS does not provide what you need. This still means you have to make a build of the DLL before Intellisense recognizes it. IMO there's a difference between checking in a compiled DLL where the source is part of the project (basically making no sense, as you said), and checking in a DLL which serves as a header file. If you check-in the IDL, you are responsible for updating the IDL. What about creating the DLL in a post-checkout script?
OregonGhost
Now that I think about it, what about creating a custom build tool (don't know the right term) like the ResXFileCodeGenerator? Such a tool can generate other files when a certain source file (your idl, in this case) is changed (or the generated result is not there). This is done as needed, so you'll get the DLL without building, and it's nicely integrated into VS (and hopefully the build server). I don't know though if the definition of the build tool (i.e. the code) can be in the same solution where it's used, or if you have to install it.
OregonGhost
This sounds pretty good - I'll have to look into MSBuild and see what I can do. Thanks for the advice.
Mark W
A: 

The MIDL compilation can be handled by making the COM interop project a managed C++ project (instead of a C# project) then adding the idl and h to the project as regular source files.

Eusebio