ArcGIS AddIN开发之COM对象写入注册表

做一个交互式绘制文字的工具,希望这次设置的Symbol,下次打开ArcMap时自动调用这个Symbol,并支持对其进行修改。

解决方法是将这个Symbol写入注册表中,每次自动读取上一次设置的Symbol,如果修改了Symbol,则自动写入注册表中。

相关文章:

注册表读写

http://blog.csdn.net/p424671075/article/details/6176219

ESRI COM对象序列化

http://blog.csdn.net/xgyb12458/article/details/4125911

Object与二进制的转换

http://www.cnblogs.com/jesszhu/archive/2013/08/22/3276556.html

阅读上述帖子后,开始着手写。首先想的是将ISymbol装箱为Object,再序列号为二进制,就可以写入注册表了。调试时显示这个Object不支持序列化

后来查阅到COM对象的序列化,需要用到IXMLSerializer,将COM对象序列化为字符,使用方式如下:

public string esriSerializer(object obj)
        {
            IXMLSerializer xmlSerializer = new XMLSerializerClass();
            string xmlstring = xmlSerializer.SaveToString(obj, null, null);
            return xmlstring;
        }

        public object esriDeserializer(string str)
        {
            IXMLSerializer xmlSerializer = new XMLSerializerClass();
            return xmlSerializer.LoadFromString(str, null, null);
        }
    public string esriSerializer(object obj)
        {
            IXMLSerializer xmlSerializer = new XMLSerializerClass();
            string xmlstring = xmlSerializer.SaveToString(obj, null, null);
            return xmlstring;
        }

        public object esriDeserializer(string str)
        {
            IXMLSerializer xmlSerializer = new XMLSerializerClass();
            return xmlSerializer.LoadFromString(str, null, null);
        }

之后,在将字符串对象序列化为二进制,写入注册表即可。

序列化为与反序列化二进制的代码如下:

public byte[] BinarySerializer(object obj)
        {
            try
            {
                using (var ms = new MemoryStream())
                {
                    var formatter = new BinaryFormatter();
                    formatter.Serialize(ms, obj);
                    var data = ms.ToArray();
                    return data;
                }
            }
            catch (InvalidOperationException)
            {
                throw;
            }
        }

        public object BinaryDeserializer(byte[] bt)
        {
            object obj=null;
            try
            {
                using (var ms = new MemoryStream(bt))
                {
                    var formatter = new BinaryFormatter();
                    obj=formatter.Deserialize(ms);
                }
            }
            catch (InvalidOperationException)
            {
                
            }
            return obj;
        }

读取与写入注册表代码如下:

/// <summary>
        /// 从注册表获取值
        /// </summary>
        /// <param name="toolname">工具名称</param>
        /// <param name="key">值名称</param>
        /// <returns></returns>
        public object getValueFromReg(string toolname,string key)
        {
            object obj=null;
            try
            {
                RegistryKey rkey = Registry.LocalMachine;
                RegistryKey rootkey = Registry.LocalMachine;
                RegistryKey sftkey = rootkey.OpenSubKey("software", true);
                RegistryKey llcsft = sftkey.OpenSubKey("llcSft");
                RegistryKey AddinCfg = llcsft.OpenSubKey("AddInConfig");
                RegistryKey AddInName = AddinCfg.OpenSubKey(toolname);
                byte[] tmp = (byte[])AddInName.GetValue(key);
                obj = esriDeserializer(BinaryDeserializer(tmp).ToString());
            }
            catch (System.Exception ex)
            {
                return null;
            }
            return obj;
        }

        /// <summary>
        /// 写入注册表
        /// </summary>
        /// <param name="toolName">工具名称</param>
        /// <param name="pm">键值</param>
        /// <returns></returns>
        public bool setValueToReg(string toolName,KeyValuePair<string,object> pm)
        {
            try
            {
                RegistryKey rootkey = Registry.LocalMachine;
                RegistryKey sftkey = rootkey.OpenSubKey("software",true);
                RegistryKey llcsft = sftkey.CreateSubKey("llcSft");
                RegistryKey AddinCfg = llcsft.CreateSubKey("AddInConfig");
                RegistryKey AddInName = AddinCfg.CreateSubKey(toolName);
                AddInName.SetValue(pm.Key, BinarySerializer(esriSerializer(pm.Value)), RegistryValueKind.Binary);
            }
            catch (System.Exception ex)
            {
                
            }
            return true;
        }

使用中,直接调用setValueToReg,getValueFromReg两个函数即可。

原文地址:https://www.cnblogs.com/DayDreamEveryWhere/p/4581275.html