How to link to an ActiveX Control from a Strongly Named Assembly

Windows Forms has a feature that allows you to use an ActiveX control on your managed form.  All you have to do is add the control to your toolbox, and VS takes care of the rest behind the scenes.  But this feature has a bit of a problem when it comes to strongly named assemblies.

The root of the problem is that strongly named assemblies can only statically reference other strongly named assemblies.  (They can use reflection to use simply named assemblies, but that's beside the point here.)  Part of the process of adding that ActiveX control to your project involves generating a managed wrapper assembly around it, and unfortunately Visual Studio does not sign that assembly.  So, when you try to sign your assembly you'll get compiler errors along the lines of:

error CS1577: Assembly generation failed -- Referenced assembly 'Interop.SHDocVw' does not have a strong name

The solution to the problem is to generate the wrapper assemblies with a strong name.  You can use the SDK tool AxImp to accomplish this.  For instance, if you wanted to wrap the IE engine, you would use:

sn -k shdocvw.snk
AxImp %WINDIR%\System32\shdocvw.dll /keyfile:shdocvw.snk

Which would create a pair of assemblies AxSHDocVw.dll and SHDocVw.dll you can use in place of the versions that Visual Studio generates on its own.

Of course, in Whidbey, Windows Forms has a web browser control, which finally gets rid of the need to have wrapper assemblies around shdocvw.dll :-)

Updated 1/14/05:   Daniel Schlößer points out that you don't have to drop out to the SDK tools, Visual Studio 2003 lets you set a project setting in order to have the IDE generate strongly named wrapper assemblies.