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 中的版本号,使两者保持一致。

posted @ 2013-03-26 14:06  踏歌长行  阅读(234)  评论(0编辑  收藏  举报