Wednesday, October 20, 2004
How to deploy a .Net assmebly for COM use through CAB on webpage
By Wang Ting
普通的ActiveX控件或COM DLL打包成Cab后能很容易通过Internet Component Download装到客户端。我们只需在网页里加入 object codebase... /object>。
今天遇到一个人想对.Net写的“COM组件”做相同的事情。可是.Net assembly是要RegAsm之后才能被COM client调用的……
一个解决办法是把.Net assembly和它的TLB（Register属性都为vsdrfCOM)打在Setup project中生成一个MSI，然后再把MSI打在CAB中。我们可以通过CAB INF中的Hook功能，在客户端下载完CAB之后自动安装CAB中的MSI。
To create a .Net assembly which will be used by COM clients:
1. Create a VB.Net Class Library named “ClassLibraryVBActiveX”. Use the following code for the project:
Public Class Class1
Public Function Hello() As String
Return "Hello World!"
Please keep a note of the GUID. We will use it later.
2. Right click the class library project in the Solution Explorer and select “Properties”. This will open the Property Pages of the class library project. Under the category “Configuration Properties” | “Build”, check the check box “Register for COM Interop”.
3. Build the class library project.
To create a Setup project for the class library:
4. Right-click the solution in the Solution Explorer and select “Add” | “New Project”. Select “Setup Project” and name it as “ActiveXInstaller”.
5. Add the “Primary output” of the class library to the Setup project.
6. Build the Setup project. We should see that “ClassLibraryVBActiveX.dll” and “ClassLibraryVBActiveX.tlb” have been built into the Setup project.
To build the CAB file for the Setup project:
7. Extract the ZIP attached and save the files to a temporary folder.
We have the following 5 files:
makecab.exe – The utility for building CABs. The utility can typically be found in “System32”.
Installer.inf – The Inf file for the CAB file. It has the following contents:
run= msiexec /i %EXTRACT_DIR%\ActiveXInstaller.msi /qn
; This section is required for compatibility on both Windows 95 and Windows NT.
Here “run” specifies the command we would like to run after IE extracts the CAB. The command line will install the MSI “ActiveXInstaller.msi” under silent mode. You may refer to the following links for more details about the format of INF:
About INF File Architecture
Cab.DDF – a text file with the following contents:
This file is a directive file for the “MakeCAB.exe” utility. “ActiveX.CAB” is the output name of the CAB. The last two lines indicate the two files we would like to include into the CAB.
Make.bat – a batch file that will run the following command to build the CAB:
MAKECAB.EXE /f "Cab.DDF"
TestPage.htm – a template HTML that will install the CAB:
Note that the GUID should match the GUID in our VB.Net code.
8. To use these files, please copy output MSI of the Setup project (e.g. “ActiveXInstaller.msi”) to the same folder as the files above. Then double-click “Make.bat” to build the CAB.
9. Copy the CAB as well as “TestPage.htm” to a web folder and test it.
Note that this approach also provides a way for the end user to uninstall the assembly. We can remove it by “Add/Remove Programs” applet.
re: 9/11/2004 12:13 PM Wang Ting
这个网站是用一个MSI来修改.Net CLR Security Policy，以便可以以full trust来运行它的.Net程序（一样要下载到本地，我个人觉得还不如直接让用户下一个EXE或script运行）我这里做的是通过CAB包把.Net assembly安装注册成COM组件，以便COM client可以调用……
You can deploy assembly using cab files.
There are two ways to load assemblies from cab files.
You can give the URL of the cab file to Assembly.LoadFrom. For example,
2. Use app.config, and specify codebase hint, then use Assembly.Load.
When we locate the cab file, we extract them to a temporary directory. The temporary directory becomes the application base now and we will probe the desired assembly in the temporary directory. We then copy the assembly to download cache, and remove the temporary directory we created. The final assembly location you see from Assembly.Location will be in download cache directory.
There are subtle difference in using Assembly.LoadFrom and codebase hint.
In Assembly.LoadFrom case, after we extract the cab file, we will only look for assembly with the same name as the cab file, excluding the extension. In our example above, we will only look for myasm.dll/myasm.exe.
In codebase hint case, we will look for the assembly specified in Assembly.Load, instead of the name of the cab file. This means, the cab file does not have to have the same name as the assembly.
A side effect of codebase hint behavior is that you can put multiple assemblies in one cab file. You will need to specify multiple assemblyBinding statements in app.config file to use the same cab file as codebase hint for different assemblies.
If you use this technique, due to how we extract the cab file and find the assembly (see above), we will download, and extract the same cab file multiple times. So bundling multiple assemblies in one cab file may actually hurt performance, instead of improving performance.
Of course, in reality, we use IE to download the cab file. You may benefit from IE’s caching of the downloaded cab file. You really want to measure your scenario, to decide if you want to use this technique or not.