Имя: Пароль:
1C
 
Объекты Net в IDispatch
0 Serginio1
 
30.05.11
18:17
Столкнулся с тем, что 1С не понимала типы Вэб сервисов. А на Net подключение проходит. Сделал обертку через IReflect c поддержкой энумераторов. Может кому пригодится.

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;
using System.Runtime.InteropServices.ComTypes;

namespace NetObjectToIDispatch
{

   

 //  [ComVisible(true)]
   public class EnumVariantImpl : IEnumVARIANT
   {
       private const int S_OK = 0;
       private const int S_FALSE = 1;

       IEnumerator enumerator = null;

       public EnumVariantImpl(IEnumerator enumerator)
       {
           this.enumerator = enumerator;
       }

       public IEnumVARIANT Clone()
       {
           throw new NotImplementedException();
       }


       public int Reset()
       {
           enumerator.Reset();
           return S_OK;
       }

       public int Skip(int celt)
       {
           for (; celt > 0; celt--)
               if (!enumerator.MoveNext())
                   return S_FALSE;
           return S_OK;
       }

       public int Next(int celt, object[] rgVar, IntPtr pceltFetched)
       {
           if (celt == 1 && enumerator.MoveNext())
           {
               rgVar[0] = new AutoWrap(enumerator.Current);
            //   pceltFetched = new IntPtr(1);
               if (pceltFetched != IntPtr.Zero)
                   Marshal.WriteInt32(pceltFetched, 1);


               return S_OK;
           }
           else
           {
               return S_FALSE;
           }
       }
   }

   [ComVisible(true)]
   [ProgId("NetObjectToIDispatch")]
   [ClassInterface(ClassInterfaceType.AutoDispatch)]
   [Guid("1BD846DC-63F2-4070-AF23-8AECD6C158CC")]
   public class NetObjectToIDispatch
   {
       public object CreateObject(string type)
       { return new AutoWrap(Activator.CreateInstance(Type.GetType(type))); }

       public object CreateObjectWhithParam(string type,Object[] args)
       { return new AutoWrap(Activator.CreateInstance(Type.GetType(type), args)); }

       public object CreateArray(string type, int length)
       {
           return new AutoWrap(Array.CreateInstance(Type.GetType(type), length));
       }
   }
   [ProgId("AutoWrapNetObjectToIDispatch")]
   [ClassInterface(ClassInterfaceType.AutoDispatch)]
   [ComVisible(true)]
   [Guid("72EAFB10-099F-4e96-A17E-B67E34DACA53")]
   public class AutoWrap : IReflect
   {
       protected object O = null;
       protected Type T = null;
       public AutoWrap() { }
       public AutoWrap(object obj)
       {
           O = obj;
           T = O.GetType();
       }
       #region IReflect Members
       public System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
       {
           return T.GetField(name, bindingAttr);
       }    /* SNIP other IReflect methods */

       public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
       {        // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)

           if (name == "[DISPID=-4]")
           {
               return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
           }

           if (args != null && args.Length > 0)
           {
               for (int x = 0; x < args.Length; x++)
               {
                   if (args[x] is AutoWrap)
                   { args[x] = ((AutoWrap)args[x]).O; }
               }
           }
           // Invoke whatever needs be invoked!
           object obj = T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
           // Wrap any return objects (that are not primative types)
           if (obj != null)
           {
               //switch (obj.GetType().ToString())
               //{
               //    case "System.String":
               //    case "System.DateTime":
               //    case "System.Boolean":
               //    case "System.Byte":
               //    case "System.Char":
               //    case "System.Decimal":
               //    case "System.Double":
               //    case "System.Single": // Float                
               //    case "System.Int32":
               //    case "System.Int64": // Long
               //    case "System.SByte":
               //    case "System.Int16":// Short
               //    case "System.UInt32":
               //    case "System.UInt64":
               //    case "System.UInt16":
               //        break; // These Types do not get wrapped
               //    default:
               //        obj = new AutoWrap(obj); // Wrap Type
               //        break;
               // Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single.
               if (!(obj.GetType().IsPrimitive
                   || obj.GetType() == typeof(System.Decimal)
                   || obj.GetType() == typeof(System.DateTime)
                   || obj.GetType() == typeof(System.String)))
                   obj = new AutoWrap(obj);
               //}
           }
           return obj;
       }
       public object UnderlyingObject
       { get { return O; } }
       public Type UnderlyingSystemType { get { return T.UnderlyingSystemType; } }
       #endregion


       public FieldInfo[] GetFields(BindingFlags bindingAttr)
       {
          return T.GetFields(bindingAttr);  
       }

       public MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
       {
          return T.GetMember(name,bindingAttr);
       }

       public MemberInfo[] GetMembers(BindingFlags bindingAttr)
       {
         return  T.GetMembers(bindingAttr);
       }

       public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
       {
          return T.GetMethod(name,bindingAttr);
       }

       public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
       {
         //  throw new NotImplementedException();
          return T.GetMethod(name, bindingAttr, binder, types, modifiers);
       }

       public MethodInfo[] GetMethods(BindingFlags bindingAttr)
       {
           return T.GetMethods(bindingAttr);
       }

       public PropertyInfo[] GetProperties(BindingFlags bindingAttr)
       {
           return T.GetProperties(bindingAttr);
       }

       public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
       {
           return T.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
       }

       public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
       {
           return T.GetProperty(name, bindingAttr);
       }
   }
}
1 Serginio1
 
02.06.11
12:26
Подправил для более полного использования типов

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;
using System.Runtime.InteropServices.ComTypes;

namespace NetObjectToIDispatch
{


   

 //  [ComVisible(true)]
   public class EnumVariantImpl : IEnumVARIANT
   {
       private const int S_OK = 0;
       private const int S_FALSE = 1;

       IEnumerator enumerator = null;

       public EnumVariantImpl(IEnumerator enumerator)
       {
           this.enumerator = enumerator;
       }

       public IEnumVARIANT Clone()
       {
           throw new NotImplementedException();
       }


       public int Reset()
       {
           enumerator.Reset();
           return S_OK;
       }

       public int Skip(int celt)
       {
           for (; celt > 0; celt--)
               if (!enumerator.MoveNext())
                   return S_FALSE;
           return S_OK;
       }

       public int Next(int celt, object[] rgVar, IntPtr pceltFetched)
       {
           if (celt == 1 && enumerator.MoveNext())
           {


               rgVar[0] = AutoWrap.ОбернутьОбъект(enumerator.Current);
            //   pceltFetched = new IntPtr(1);
               if (pceltFetched != IntPtr.Zero)
                   Marshal.WriteInt32(pceltFetched, 1);


               return S_OK;
           }
           else
           {
               return S_FALSE;
           }
       }
   }

   [ComVisible(true)]
   [ProgId("NetObjectToIDispatch")]
   [ClassInterface(ClassInterfaceType.AutoDispatch)]
   [Guid("1BD846DC-63F2-4070-AF23-8AECD6C158CC")]
   public class NetObjectToIDispatch
   {
       public object CreateObject(string type)
       { return new AutoWrap(System.Activator.CreateInstance(Type.GetType(type))); }

       public object CreateObjectWhithParam(string type,Object[] args)
       { return new AutoWrap(System.Activator.CreateInstance(Type.GetType(type), args)); }

       public object CreateArray(string type, int length)
       {
           return new AutoWrap(Array.CreateInstance(Type.GetType(type), length));
       }

       public  object Activator {
           get { return new AutoWrap(typeof(System.Activator)); }
       }
           public object ПолучитьТип(string type, string путь)
           {
           Type result = Type.GetType(type,
                      (aName) => путь.Trim().Length != 0 ?
                          Assembly.LoadFrom(путь) :
                          Assembly.Load(aName),
                      (assem, name, ignore) => assem == null ?
                          Type.GetType(name, false, ignore) :
                              assem.GetType(name, false, ignore), true
                     );

           return new AutoWrap(result);
                                   }
   }
   [ProgId("AutoWrapNetObjectToIDispatch")]
   [ClassInterface(ClassInterfaceType.AutoDispatch)]
   [ComVisible(true)]
   [Guid("72EAFB10-099F-4e96-A17E-B67E34DACA53")]
   public class AutoWrap : IReflect
   {
       protected object O = null;
       protected Type T = null;

       BindingFlags staticBinding = BindingFlags.Public | BindingFlags.Static;
       bool ЭтоТип;

       public static object ОбернутьОбъект(object obj)
       {
       if (obj != null)
           {
               //switch (obj.GetType().ToString())
               //{
               //    case "System.String":
               //    case "System.DateTime":
               //    case "System.Boolean":
               //    case "System.Byte":
               //    case "System.Char":
               //    case "System.Decimal":
               //    case "System.Double":
               //    case "System.Single": // Float                
               //    case "System.Int32":
               //    case "System.Int64": // Long
               //    case "System.SByte":
               //    case "System.Int16":// Short
               //    case "System.UInt32":
               //    case "System.UInt64":
               //    case "System.UInt16":
               //        break; // These Types do not get wrapped
               //    default:
               //        obj = new AutoWrap(obj); // Wrap Type
               //        break;
               // Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single.
               if (!(obj.GetType().IsPrimitive
                   || obj.GetType() == typeof(System.Decimal)
                   || obj.GetType() == typeof(System.DateTime)
                   || obj.GetType() == typeof(System.String)))
                   obj = new AutoWrap(obj);
       }
           return obj;
       }
       public AutoWrap() { }
       public AutoWrap(object obj)
       {
           O = obj;
           if (O is Type)
           {
               T = O as Type;
               ЭтоТип = true;
           }
           else {
               T = O.GetType();
               ЭтоТип = false;
           }
           
       }
       #region IReflect Members
       public System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
       {
           if (ЭтоТип)
               return T.GetField(name, staticBinding);
           else
           return T.GetField(name, bindingAttr);
       }    /* SNIP other IReflect methods */

       public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
       {        // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)

           if (name == "[DISPID=-4]")
           {
               return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
           }

           if (args != null && args.Length > 0)
           {
               for (int x = 0; x < args.Length; x++)
               {
                   if (args[x] is AutoWrap)
                   { args[x] = ((AutoWrap)args[x]).O; }
               }
           }
           // Invoke whatever needs be invoked!
           object obj;
               if (ЭтоТип)
                   obj = T.InvokeMember(name, invokeAttr, binder, null, args, modifiers, culture, namedParameters);
               else
                   obj=T.InvokeMember(name, invokeAttr, binder, O, args, modifiers, culture, namedParameters);
           // Wrap any return objects (that are not primative types)
           
               //}
         
           return ОбернутьОбъект(obj);
       }
       public object UnderlyingObject
       { get { return O; } }
       public Type UnderlyingSystemType { get { return T.UnderlyingSystemType; } }
       #endregion


       public FieldInfo[] GetFields(BindingFlags bindingAttr)
       {
           if (ЭтоТип)
               return T.GetFields(staticBinding);
           else
          return T.GetFields(bindingAttr);  
       }

       public MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
       {
            if (ЭтоТип)
                return T.GetMember(name, staticBinding);
            else
          return T.GetMember(name,bindingAttr);
       }

       public MemberInfo[] GetMembers(BindingFlags bindingAttr)
       {
           if (ЭтоТип)
               return T.GetMembers(staticBinding);
           else
         return  T.GetMembers(bindingAttr);
       }

       public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
       {
           if (ЭтоТип)
               return T.GetMethod(name, staticBinding);
           else
            return T.GetMethod(name,bindingAttr);
       }

       public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
       {
         //  throw new NotImplementedException();

           if (ЭтоТип)
               return T.GetMethod(name, staticBinding, binder, types, modifiers);
           else
          return T.GetMethod(name, bindingAttr, binder, types, modifiers);
       }

       public MethodInfo[] GetMethods(BindingFlags bindingAttr)
       {
           if (ЭтоТип)
               return T.GetMethods(staticBinding);
           else
           return T.GetMethods(bindingAttr);
       }

       public PropertyInfo[] GetProperties(BindingFlags bindingAttr)
       {
           if (ЭтоТип)
               return T.GetProperties(staticBinding);
           else
           return T.GetProperties(bindingAttr);
       }

       public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
       {
           if (ЭтоТип)
               return T.GetProperty(name, staticBinding, binder, returnType, types, modifiers);
           else
           return T.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
       }

       public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
       {
           if (ЭтоТип)
               return T.GetProperty(name, staticBinding);
           else
           return T.GetProperty(name, bindingAttr);
       }
   }
}
2 Serginio1
 
02.06.11
12:27
Пример использования
объект=Новый COMОбъект("NetObjectToIDispatch");
   Типмд5= объект.ПолучитьТип("System.Security.Cryptography.MD5CryptoServiceProvider","");
   Активатор=объект.Activator;
   мд5=Активатор.CreateInstance(Типмд5);
   типЭнкодинг=объект.ПолучитьТип("System.Text.Encoding","");
   рез=мд5.ComputeHash(типЭнкодинг.Default.GetBytes("Строка"));
   для каждого стр из рез Цикл
       Сообщить(стр);
       КонецЦикла;
Основная теорема систематики: Новые системы плодят новые проблемы.