Deploy C# ActiveX in a CAB for Internet Explorer use

wpfwannabe picture wpfwannabe · Mar 30, 2011 · Viewed 20.6k times · Source

I am desperately trying to deploy an ActiveX for IE developed in C# as a CAB archive. I have read many resources (some of them from StackOverflow) and it appears a lot of people are having the same problems. I have tried 3 solutions: a) creating a CAB VS project, b) manually creating a CAB using CABARC with a COM registration in INF and c) manually creating a CAB with launching msiexec. None of them worked. I even tried d) creating a bootstrapper which launches msiexec to no avail (because some people suggested simply launching msiexec on Vista can't work).

I am running Windows Vista but my project fails to run even on IE6 on XP.

When I install ActiveX using MSI, all is fine on ALL Windows. Apparently CAB thing is not working and I could not find a proper way to debug this whole process yet.

Any help is appreciated.

Answer

RB. picture RB. · Mar 30, 2011

Update: Note that this old but excellent answer is still a very good outline for how to approach solving this problem, at least as along the evolutionary scale as Win7 and IE11. I just succeeded making it all work using the Answerer's Firebreath.org toolset as a jumping off point. It's not simple but it can be done. I've added a reference to that project to the reference list below since it may make a more logical jumping off point for current developers than this overview is.


Hooray - I have just finished an identical project, so you'll be pleased to know that it's actually possible. I have only tested this on XP - I understand there may be issues where Vista/7 don't allow msiexec to be called.

Given that you have an assembly correctly exposing a COM interface, I did the following:

  • Strong-named the assembly.
  • Created an INF file
  • Created an MSI using the Visual Studio 2008 "Setup Project" template.
  • Created a CAB file using "iexpress.exe" bundled with Windows XP.

Create INF file

The *.inf file I used looks like:

[version]
signature="$CHICAGO$"
AdvancedINF=2.0

[Setup Hooks]
install=install

[install]
run=msiexec.exe /package """%EXTRACT_DIR%\SampInst.msi""" /qn

The only bit you should need to change is the SampInst.msi. Note I would use an 8.3 filename, as long filenames can cause issues. While testing, I would not use the qn switch either, as that is a silent install.

Create the Installer

The installer has to do only one thing, and that is register the assembly by calling RegAsm on it. Most installers will provide some method to easily do this. For example, an installer created through VS 2008 will simply need to have the “Register” property of the assembly set to “vsdrpCOM”. Note that vsdrpCOM should be chosen as it generates the appropriate registry entries at build-time. The vsdrpCOMSelfRegistration setting is likely to fail as it calls RegAsm at run-time, and will thus not work for non-administrators.

Package the installer into a CAB file

This can be done by any cab archiver. Windows XP contains iexpress.exe, a wizard driven archiver, while Microsoft’s CAB SDK contains cabarc.exe. Other 3rd-party tools are also available. Note that you will need to reserve space in the CAB file for code-signing if you are going to sign the CAB.

You will need to CAB the INF file, and the MSI file. You will not need to CAB the Setup.Exe file.

Handy hint: The VS2008 Setup Project project type allows you to set a post-build step in the properties, so you can build and CAB in a single step. My post-build step looks like:

cd "$(ProjectDir)"
"%WINDIR%\System32\Makecab.exe" /f "VboCslib.ddf"

The DDF file format is documented.

Sample HTML page

The object tag is used to point to the cab file containing the installer. A very simple HTML page which would deploy an ActiveXControl would be:

<html>
<head></head>
<body>

    <!--
        ID :    The id of the ActiveX control to be used in JavaScript.
        CLASSID : The GUID associated with the ActiveX control.
        CODEBASE: The location containing the CAB installer for the ActiveX 
       control. This could be a URL, or a relative path.
        -->
    <OBJECT ID="MyActiveXControl"
            CLASSID="CLSID:FC36FAE1-48E0-4f6b-B469-E1B5A8C6D1AC"
            CODEBASE="cabfiles\SampleCabFile.CAB#version=1,0,0,0">
        </OBJECT>

        <script>
            MyActiveXControl.SomeMethod();
        </script>
    </body>
    </html>

Handy hints

  • Ensure your installer installs on a "per-user" basis, not a "per-machine" basis. This will make it more likely to install if the user does not have admin privileges.

Trouble-shooting

Internet Explorer 6 actually provides a really useful diagnostic aid. Clear your Temporary Internet Files, then navigate to the web-page. If the installation does not work, go to your temporary internet files and you will see a couple of files in there. One of these will be an error log starting ?CodeDownloadErrorLog. Drag it to your desktop and open it in notepad, and it will give details on what it was trying to do when it failed.

References

  1. Microsoft KB247257 – Steps for signing a .cab file
  2. MSDN – About INF File Architecture
  3. SN.EXE - Code Strong Programs with Strong Names
  4. Nikolkos Craft – How To: Deploy .NET ActiveX Control
  5. CodeProject – Create ActiveX .NET Step by Step
  6. CodeProject – Downloading C# ActiveX Components through CAB file
  7. MSDN - ALLUSERS Property (Windows)
  8. MSDN – Non-Admin ActiveX Controls
  9. MSDN – Microsoft Cabinet Format

Update: Firebreath.org has a toolset for generating browser plugins for many platforms. The IE/ActiveX code to solve the problem posed here is just a subset. But as of 6 Nov 2014, I found it easier to start with Firebreath and its instructions than to try to build up my dev environment and roll all my own solutions from scratch.