VS 2010 开发 ActiveX 自动升级外篇
利用 ComRegisterFunction 特性在 Registry 中自动写入新的 InstalledVersion
1. 创建一个 Installer 类型的类
[RunInstaller(true)] public partial class ComInstaller : System.Configuration.Install.Installer { public ComInstaller() { InitializeComponent(); } public override void Install(IDictionary stateSaver) { base.Install(stateSaver); RegistrationServices regsrv = new RegistrationServices(); if (!regsrv.RegisterAssembly(this.GetType().Assembly, AssemblyRegistrationFlags.SetCodeBase)) { throw new InstallException("Failed To Register for COM"); } } public override void Uninstall(IDictionary savedState) { base.Uninstall(savedState); RegistrationServices regsrv = new RegistrationServices(); if (!regsrv.UnregisterAssembly(this.GetType().Assembly)) { throw new InstallException("Failed To Unregister for COM"); } } }
2. 为 Version 类写扩展方法 ToSpecialString()
public static string ToSpecialString(this Version ver) { return string.Format("{0},{1},{2},{3}", ver.Major, ver.Minor, ver.Build, ver.Revision); }
3. InfoViewer 类中添加具有 ComRegisterFunction 特性的方法
[ComRegisterFunction()] public static void RegisterClass(string key) { // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it StringBuilder sb = new StringBuilder(key); sb.Replace(@"HKEY_CLASSES_ROOT\", ""); // Open the CLSID\{guid} key for write access RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true); // And create the 'Control' key - this allows it to show up in // the ActiveX control container RegistryKey ctrl = k.CreateSubKey("Control"); ctrl.Close(); // Next create the CodeBase entry - needed if not string named and GACced. RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true); inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase); inprocServer32.Close(); //Com Version RegistryKey instver = k.CreateSubKey("InstalledVersion"); instver.SetValue("", Assembly.GetExecutingAssembly().GetName().Version.ToSpecialString()); instver.Close(); // Finally close the main key k.Close(); } [ComUnregisterFunction()] public static void UnregisterClass(string key) { StringBuilder sb = new StringBuilder(key); sb.Replace(@"HKEY_CLASSES_ROOT\", ""); // Open HKCR\CLSID\{guid} for write access RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true); // Delete the 'Control' key, but don't throw an exception if it does not exist k.DeleteSubKey("Control", false); // Next open up InprocServer32 //RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true); // And delete the CodeBase key, again not throwing if missing k.DeleteSubKey("CodeBase", false); //Com Version k.DeleteSubKey("InstalledVersion"); // Finally close the main key k.Close(); }
4. 右键 ActiveXDemo.Setup 项目 --> View --> Custom Actions
5. 右键 Custom Actions --> Add Custom Action...
6. 点击 OK 之后
7. 重新编译,并制作 cab
通过这种设置,以后只需修改 ActiveX 的项目版本号,即可在安装时,系统自动写入 Registry 中的 InstalledVersion,其值为 ActiveX 的项目版本的值;但要注意,在修改 ActiveX 的项目版本号的同时,也要修改 HTML 中 codebase 中的版本号,使两者保持一致。