ActiveX控件这种古老东西在某些场合依然有重要用途。使用C#编写一个ActiveX控件的难点在于如何把DLL及相关文件打包成CAB。参阅了很多资料,有两点感悟:
1.ActiveX控件可以制作测试签名,然而并没什么卵用,除非弄付费的数字签名。现实的解决办法是目标IE添加信任网站,再设置ActiveX权限。相关文章网上很多,不再细述。
2.CAB中包含一个INF文件,指出了安装内容和步骤。我想按照网上INF示例格式,把DLL和相关文件同INF打包在一起,然后在INF中指示目标系统把它们安装到相应位置上。可惜我参考了几十篇文章,不管如何修改INF文件内容,DLL根本完全装不到目标机器上。可能原因人家都是用C++编写的吧....反正最终我发现.net下必需先把相关文件打包成微软安装程序msi,然后再把msi文件和inf文件打包成cab,而inf中只有一条指令,就是运行这个msi。
这是我的示例工程,C#编写ActiveX控件需要三个工程,NetActiveXSample是用来生成ActiveX控件DLL,Setup1是windows安装项目,用来打包生成msi。注意:.NET DLL添加到客户系统上后,需要添加到全局程序集缓冲再注册,这样才能使用。因此Setup1打包的不仅是NetActiveXSample工程生成的DLL,还要包含.net 工具gacutil.exe和RegAsm.exe。这两个工具VS中有,需要注意的是:它们的版本要和你项目的.net版本一致,而且你要保证目标机器上已安装了相应版本的.net framework。
为了执行这两个程序,需要在Setup1中添加自定义安装。方法是先建一个类库比如我解决方案中的DLLSetup,其中代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.IO;
namespace DllSetup
{
[RunInstaller(true)]
public partial class Installer1 : System.Configuration.Install.Installer
{
/// 函数入口——主函数
/// </summary>
public static void Main()
{
}
public Installer1()
{
InitializeComponent();
}
/// <summary>
/// 重写安装完成后函数
/// 实现安装完成后自动启动已安装的程序
/// </summary>
/// <param name="savedState"></param>
protected override void OnAfterInstall(IDictionary savedState)
{
base.OnAfterInstall(savedState);
RunBat(Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\NetActiveXSample.bat");
}
private void RunBat(string batPath)
{
Process pro = new Process();
FileInfo file = new FileInfo(batPath);
pro.StartInfo.WorkingDirectory = file.Directory.FullName;
pro.StartInfo.FileName = batPath;
pro.StartInfo.CreateNoWindow = false;
//静默方式执行bat脚本(不出现黑框框)
//pro.StartInfo.CreateNoWindow = true;
//pro.StartInfo.UseShellExecute = false;
pro.Start();
pro.WaitForExit();
}
}
}
NetActiveXSample.bat:
gacutil /i NetActiveXSample.dll
regasm NetActiveXSample.dll
pause
注意:
1. 项目文件夹/cab下有index.html供测试用。
2.项目代码中没有ActiveX控件调用JS的代码,因为需要引用mshtml。相关参考文章:
3.防止System文件夹下原有内容被覆盖,需要的话做个备份。
4.修改了ActiveX控件代码后,要么修改Guid,要么从目标机器控制面板-添加删除程序中先卸载掉旧控件。
有问题或建议加我扣扣探讨:一八四二六三二零三