為完成網頁自動下載並安裝控件的功能,需要通過C#創建一個ActiveX控件,然後將該控件置於安裝程序中,在打開網頁的時候下載、安裝並注冊該ActiveX控件。本文是采用VS2005創建的,VS2003創建過程與之相似。
首先,創建一個類庫,為其命名為CreateActiveXEmail:

刪除掉默認生成的類Class1.cs,創建一個接口ActiveXEmailInterface:

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;


namespace CreateActiveXEmail


...{

[Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

public interface ActiveXEmailInterface


...{

void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions);

void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions);

}

}
其中GUID可以通過【工具】-【創建GUID】來產生。
實現該接口的目的就是提高程序的安全性,以便客戶端IE在不更改設置的情況下可以預行該ActiveX控件。
然後,用你需要實現某些功能的類來繼承上面的接口。

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Drawing;

using System.Data;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;


namespace CreateActiveXEmail



[Guid("060d1308-f34e-4c9f-8962-0abafe385d33"), ComVisible(true)]

public class ActiveXEmail : ActiveXEmailInterface


...{

public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)


...{

pdwSupportedOptions = 1;

pdwEnabledOptions = 2;

}


public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)


...{

}


public ActiveXEmail()


...{

}

}
注意,上面代碼中的類屬性“ComVisible(true)”,是必須添加的。
在上面的類中,僅僅是現實了接口的兩個方法,至於其他需要的方法,自行添加即可。另外,需要對項目屬性進行一點修改:

注意,類屬性中的“ComVisible(true)”和上圖中的【為 COM Interop 注冊】缺一不可!只有這樣才能生成tlb文件。
這樣,一個可用的ActiveX控件就已經生成。在本機你可以隨意調用其中的任何方法,但問題是,當客戶端機器需要遠程調用時,必須在能在客戶端機器上注冊該ActiveX控件才行。所以,還必須進行下面的步驟:將該ActiveX打包,在安裝後在目標機器進行注冊。
創建一個安裝包:

然後右鍵單擊項目,點擊【添加】-【項目輸出】,在【主輸出】中選擇上面創建的工程“CreateActiveXEmail”。然後,打開安裝工程的【屬性】頁面,對項目的【安裝URL】項進行設置:

注意,上圖的【安裝URL】項中,必須使用絕對路徑。另外,上圖中的“DllFolder”是一個已發布網站“http://172.16.11.136/TestingAX”下的一個目錄,這意味著,當在客戶端訪問頁面時,如果客戶端未安裝當前ActiveX控件,則從路徑http://172.16.11.136/TestingAX/DllFolder”來下載。
最後,在頁面中按如下方法調用即可:

<object classid="clsid:060d1308-f34e-4c9f-8962-0abafe385d33"

codebase="DllFolder/setup.exe#version=1,0,0,0"></object>
另外,還可以采用其他方法,即上面的類庫屬性不選擇【為 COM Interop 注冊】,安裝工程屬性不為【安裝URL】指定路徑,類中也不添加“ComVisible(true)”屬性,而是創建一個安裝類:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Configuration.Install;

using System.Reflection;

using System.IO;

using Microsoft.Win32;

using System.Diagnostics;


namespace CreateActiveXEmail


...{

[RunInstaller(true)]

public partial class CustomInstaller : Installer


...{

private string regCommandFile = string.Empty;

private string unRegCommandFile = string.Empty;


public CustomI


...{

InitializeComponent();

}


protected override void OnAfterInstall(System.Collections.IDictionary savedState)


...{

base.OnAfterInstall(savedState);


try


...{

//get the path of the Regasm.exe

string regasmPath = string.Empty;


//get the path of the current executing assembly

string currentAsmDLLFilePath = Assembly.GetExecutingAssembly().Location;

string currentAsmPath = currentAsmDLLFilePath.Substring(0, currentAsmDLLFilePath.LastIndexOf(''\'') + 1);


string currentRegasmPath = string.Format("{0}{1}", currentAsmPath, "RegAsm.exe");

if (!File.Exists(currentRegasmPath))

...{

try


...{

RegistryKey frmReg = Registry.LocalMachine.OpenSubKey(@"SOFTWAREMicrosoft.NetFramework");

if (frmReg == null)


...{

//the .Net framework do not exist in the local Machine

return;

}


string frameworkVersion = Environment.Version.ToString();

frameworkVersion = frameworkVersion.Substring(0, frameworkVersion.LastIndexOf(''.''));


regasmPath = string.Format(@"{0}v{1}{2}", frmReg.GetValue("InstallRoot").ToString(), frameworkVersion, "RegAsm.exe");


if (!File.Exists(regasmPath))


...{

//the Regasm.exe do not exist in the local Machine

return;

}

}

catch (System.ArgumentException ex)


...{

throw new System.ArgumentException(ex.Message);

}

}

else


...{

regasmPath = currentRegasmPath;

}


//create the registration command line

string regCommand = string.Format("{0} "{1}" /{2} /{3}", regasmPath, currentAsmDLLFilePath, "tlb", "codebase");

try


...{

regCommandFile = string.Format("{0}{1}", currentAsmPath, "Regasm.bat");

if (File.Exists(regCommandFile))


...{

File.Delete(regCommandFile);

}


using (StreamWriter swReg = File.CreateText(regCommandFile))


...{

swReg.Write(regCommand);

swReg.Flush();

}

}

catch (UnauthorizedAccessException uaex)


...{

throw new UnauthorizedAccessException(uaex.Message);

}

catch (DirectoryNotFoundException dnex)


...{

throw new DirectoryNotFoundException(dnex.Message);

}

catch (IOException ioex)


...{

throw new IOException(ioex.Message);

}


//create the unregistration command file

string unRegCommand = string.Format("{0} "{1}" /{2 regasmPath, currentAsmDLLFilePath, "u");


try


...{

unRegCommandFile = string.Format("{0}{1}", currentAsmPath, "UnRegasm.bat");

if (File.Exists(unRegCommandFile))


...{

File.Delete(unRegCommandFile);

}


using (StreamWriter swReg = File.CreateText(unRegCommandFile))


...{

swReg.Write(unRegCommand);

swReg.Flush();

}

}

catch (UnauthorizedAccessException uaex)


...{

throw new UnauthorizedAccessException(uaex.Message);

}

catch (DirectoryNotFoundException dnex)


...{

throw new DirectoryNotFoundException(dnex.Message);

}

catch (IOException ioex)


...{

throw new IOException(ioex.Message);

}


//register for the COM Interop

Process.Start(regCommandFile);

}

catch (Exception ex)

...{

throw new Exception(ex.Message);

}

}


public override void Uninstall(System.Collections.IDictionary savedState)


...{

try


...{

Process.Start(unRegCommandFile);

}

catch (Exception ex)


...{

throw new Exception(ex.Message);

}


base.Uninstall(savedState);

}

}

}
因為沒有了“ComVisible(true)”和【為 COM Interop 注冊】,工程也就無法生成tlb文件,沒有tlb文件也就意味著注冊失敗,dll文件或ActiveX控件在客戶端無法使用。上面的類就是通過代碼的方式將dll文件在客戶端注冊,生成tlb文件。
當然,這種方法寫的東西比較多點,只是提供一種思路,為其他可能的項目准備。