コード例 #1
0
ファイル: ComActivator.cs プロジェクト: fossabot/runtime-1
        /// <summary>
        /// Entry point for unmanaged COM activation API from managed code
        /// </summary>
        /// <param name="cxt">Reference to a <see cref="ComActivationContext"/> instance</param>
        public static object GetClassFactoryForType(ComActivationContext cxt)
        {
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
            if (cxt.InterfaceId != typeof(IClassFactory).GUID &&
                cxt.InterfaceId != typeof(IClassFactory2).GUID)
            {
                throw new NotSupportedException();
            }

            if (!Path.IsPathRooted(cxt.AssemblyPath))
            {
                throw new ArgumentException(null, nameof(cxt));
            }

            Type classType = FindClassType(cxt.ClassId, cxt.AssemblyPath, cxt.AssemblyName, cxt.TypeName);

            if (LicenseInteropProxy.HasLicense(classType))
            {
                return(new LicenseClassFactory(cxt.ClassId, classType));
            }

            return(new BasicClassFactory(cxt.ClassId, classType));
#else
            throw new PlatformNotSupportedException();
#endif
        }
コード例 #2
0
ファイル: ComActivator.cs プロジェクト: fossabot/runtime-1
        /// <summary>
        /// Entry point for unmanaged COM register/unregister API from managed code
        /// </summary>
        /// <param name="cxt">Reference to a <see cref="ComActivationContext"/> instance</param>
        /// <param name="register">true if called for register or false to indicate unregister</param>
        public static void ClassRegistrationScenarioForType(ComActivationContext cxt, bool register)
        {
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
            // Retrieve the attribute type to use to determine if a function is the requested user defined
            // registration function.
            string attributeName   = register ? "ComRegisterFunctionAttribute" : "ComUnregisterFunctionAttribute";
            Type?  regFuncAttrType = Type.GetType($"System.Runtime.InteropServices.{attributeName}, System.Runtime.InteropServices", throwOnError: false);
            if (regFuncAttrType == null)
            {
                // If the COM registration attributes can't be found then it is not on the type.
                return;
            }

            if (!Path.IsPathRooted(cxt.AssemblyPath))
            {
                throw new ArgumentException(null, nameof(cxt));
            }

            Type classType = FindClassType(cxt.ClassId, cxt.AssemblyPath, cxt.AssemblyName, cxt.TypeName);

            Type?currentType    = classType;
            bool calledFunction = false;

            // Walk up the inheritance hierarchy. The first register/unregister function found is called; any additional functions on base types are ignored.
            while (currentType != null && !calledFunction)
            {
                // Retrieve all the methods.
                MethodInfo[] methods = currentType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

                // Go through all the methods and check for the custom attribute.
                foreach (MethodInfo method in methods)
                {
                    // Check to see if the method has the custom attribute.
                    if (method.GetCustomAttributes(regFuncAttrType !, inherit: true).Length == 0)
                    {
                        continue;
                    }

                    // Check to see if the method is static before we call it.
                    if (!method.IsStatic)
                    {
                        string msg = register ? SR.InvalidOperation_NonStaticComRegFunction : SR.InvalidOperation_NonStaticComUnRegFunction;
                        throw new InvalidOperationException(SR.Format(msg));
                    }

                    // Finally validate signature
                    ParameterInfo[] methParams = method.GetParameters();
                    if (method.ReturnType != typeof(void) ||
                        methParams == null ||
                        methParams.Length != 1 ||
                        (methParams[0].ParameterType != typeof(string) && methParams[0].ParameterType != typeof(Type)))
                    {
                        string msg = register ? SR.InvalidOperation_InvalidComRegFunctionSig : SR.InvalidOperation_InvalidComUnRegFunctionSig;
                        throw new InvalidOperationException(SR.Format(msg));
                    }

                    if (calledFunction)
                    {
                        string msg = register ? SR.InvalidOperation_MultipleComRegFunctions : SR.InvalidOperation_MultipleComUnRegFunctions;
                        throw new InvalidOperationException(SR.Format(msg));
                    }

                    // The function is valid so set up the arguments to call it.
                    var objs = new object[1];
                    if (methParams[0].ParameterType == typeof(string))
                    {
                        // We are dealing with the string overload of the function - provide the registry key - see comhost.dll implementation
                        objs[0] = $"HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID\\{cxt.ClassId.ToString("B")}";
                    }
                    else
                    {
                        // We are dealing with the type overload of the function.
                        objs[0] = classType;
                    }

                    // Invoke the COM register function.
                    method.Invoke(null, objs);
                    calledFunction = true;
                }

                // Go through all the base types
                currentType = currentType.BaseType;
            }
#else
            throw new PlatformNotSupportedException();
#endif
        }