C# Excel禁用项重新启用

在做Excel插件的时候,常常碰到一个问题就是插件异常(可能是自己插件的Bug或者是用户的一些强制操作),然后被Excel禁用。你可以查看Excel ->选项 -> 加载项 -> 管理 -> 禁用项目->转到 看看对话框中是否有自己的插件。解决这个问题也简单,删除掉注册表项就可以了
以office2013为例,禁用项的注册表路径是
HKEY_CURRENT_USER\Software\Microsoft\15.0\Excel\Resiliency\DisabledItems,要注意的是禁用项中的数据都是16进制的,所以处理的时候要转换为我们能看懂的String类型。我当时就思考禁用项在注册表中,但是搜索了半天都没搜到想要的结果,原因就是禁用项里的数据类型变成byte[]了。这是瞎耽误功夫。最后还是翻Office注册表项的时候找到了(网上没搜到,就一个一个翻着看)。

解释一下原理:这段代码包含两个功能,一个是去除禁用项(因为Office有很多版本,为了使软件兼容更多Office版本,所以这里查询所有版本的禁用项并检查是否存在自己的插件),一个是检查插件的连接状态并重新修改其为启动连接时加载。


     public void ExcelRepair()
        {
            //TODO:检查禁用项
            CheckDisalbledItem();
            //TODO:检查Addin注册表
            CheckRegister();
        }

        private void CheckDisalbledItem()
        {
            string keypath = @"Software\Microsoft\Office"; //\15.0\Excel\Resiliency\DisabledItems
            RegistryKey key = Registry.CurrentUser.OpenSubKey(keypath,true);
            FindSubItem(key, "DisabledItems", "这里写自己插件名称");
        }

        public void CheckRegister()
        {
            RegistryKey key = Registry.CurrentUser;
            RegistryKey software = key.CreateSubKey(@"Software\Microsoft\Office\Excel\Addins\自己插件名称");
            software.SetValue("LoadBehavior", "3", RegistryValueKind.DWord);
        }

        /// 
        /// 查找指定项指定内容
        /// 
        /// 
        /// 这里是禁用项的名称
        /// 自己插件的名称
        private void FindSubItem(RegistryKey key, string subkeyname,string deleteStr)
        {
            if (key.Name.Contains(subkeyname))
            {
                for (int i = 0; i < key.ValueCount; i++)
                {
                    try
                    {
                        var result = key.GetValueNames().ToList().Find(v => 
                        System.Text.Encoding.ASCII.GetString((byte[])key.GetValue(v)).Replace("\0", "").ToUpper().Contains(deleteStr.ToUpper()));
                        if (result.Count() > 0)
                        {
                            key.DeleteValue(result);
                        }
                    }
                    catch (Exception ex)
                    {
                        continue;
                    }
                }
                return;
            }
            if (key.SubKeyCount > 0)
            {
                foreach (var item in key.GetSubKeyNames())
                {
                    try
                    {
                        FindSubItem(key.OpenSubKey(item,true), subkeyname,deleteStr);
                    }
                    catch(Exception ex)
                    {
                        continue;
                    }
                }
            }
        }

你可能感兴趣的:(C#)