示例#1
0
        internal static void UnregisterMethods()
        {
            object xlCallResult;

            // Remove menus
            IntegrationHelpers.RemoveCommandMenus();

            // Now take out the methods
            foreach (XlMethodInfo mi in registeredMethods)
            {
                if (mi.IsCommand)
                {
                    XlCallImpl.TryExcelImpl(XlCallImpl.xlfSetName, out xlCallResult, mi.Name, "");
                }
                else
                {
                    // I follow the advice from X-Cell website
                    // to get function out of Wizard
                    XlCallImpl.TryExcelImpl(XlCallImpl.xlfRegister, out xlCallResult, pathXll, "xlAutoRemove", "J", mi.Name, IntegrationMarshalHelpers.GetExcelMissingValue(), 0);
                }
                XlCallImpl.TryExcelImpl(XlCallImpl.xlfUnregister, out xlCallResult, mi.RegisterId);
            }
            registeredMethods.Clear();
        }
示例#2
0
 internal static HRESULT DllCanUnloadNow()
 {
     InitializeIntegration();
     return(IntegrationHelpers.DllCanUnloadNow());
 }
示例#3
0
 internal static HRESULT DllUnregisterServer()
 {
     InitializeIntegration();
     return(IntegrationHelpers.DllUnregisterServer());
 }
示例#4
0
        private static void LoadIntegration()
        {
            // Get the assembly and ExcelIntegration type - will be loaded from file or from packed resources via AssemblyManager.AssemblyResolve.
            Assembly integrationAssembly = Assembly.Load("ExcelDna.Integration");

            // Check if ExcelDna.Integration was loaded from the Global Assembly Cache
            if (integrationAssembly.GlobalAssemblyCache)
            {
                // Prevent using the version in the GAC to avoid add-ins using the wrong version and breaking
                // https://github.com/Excel-DNA/ExcelDna/pull/250#issuecomment-508642133
                throw new InvalidOperationException("ExcelDna.Integration was loaded from Global Assembly Cache, and that's not allowed.");
            }

            Type integrationType = integrationAssembly.GetType("ExcelDna.Integration.ExcelIntegration");

            // Check the version declared in the ExcelIntegration class
            int integrationVersion = (int)integrationType.InvokeMember("GetExcelIntegrationVersion", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, null);

            if (integrationVersion != ExcelIntegrationVersion)
            {
                // This is not the version we are expecting!
                throw new InvalidOperationException("Invalid ExcelIntegration version detected.");
            }

            // Get the methods that need to be called from the integration assembly
            MethodInfo tryExcelImplMethod       = typeof(XlCallImpl).GetMethod("TryExcelImpl", BindingFlags.Static | BindingFlags.Public);
            Type       tryExcelImplDelegateType = integrationAssembly.GetType("ExcelDna.Integration.TryExcelImplDelegate");
            Delegate   tryExcelImplDelegate     = Delegate.CreateDelegate(tryExcelImplDelegateType, tryExcelImplMethod);

            integrationType.InvokeMember("SetTryExcelImpl", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { tryExcelImplDelegate });

            MethodInfo registerMethodsMethod       = typeof(XlRegistration).GetMethod("RegisterMethods", BindingFlags.Static | BindingFlags.Public);
            Type       registerMethodsDelegateType = integrationAssembly.GetType("ExcelDna.Integration.RegisterMethodsDelegate");
            Delegate   registerMethodsDelegate     = Delegate.CreateDelegate(registerMethodsDelegateType, registerMethodsMethod);

            integrationType.InvokeMember("SetRegisterMethods", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { registerMethodsDelegate });

            MethodInfo registerWithAttMethod       = typeof(XlRegistration).GetMethod("RegisterMethodsWithAttributes", BindingFlags.Static | BindingFlags.Public);
            Type       registerWithAttDelegateType = integrationAssembly.GetType("ExcelDna.Integration.RegisterMethodsWithAttributesDelegate");
            Delegate   registerWithAttDelegate     = Delegate.CreateDelegate(registerWithAttDelegateType, registerWithAttMethod);

            integrationType.InvokeMember("SetRegisterMethodsWithAttributes", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { registerWithAttDelegate });

            MethodInfo registerDelAttMethod       = typeof(XlRegistration).GetMethod("RegisterDelegatesWithAttributes", BindingFlags.Static | BindingFlags.Public);
            Type       registerDelAttDelegateType = integrationAssembly.GetType("ExcelDna.Integration.RegisterDelegatesWithAttributesDelegate");
            Delegate   registerDelAttDelegate     = Delegate.CreateDelegate(registerDelAttDelegateType, registerDelAttMethod);

            integrationType.InvokeMember("SetRegisterDelegatesWithAttributes", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { registerDelAttDelegate });

            MethodInfo registerRtdWrapperMethod       = typeof(XlRegistration).GetMethod("RegisterRtdWrapper", BindingFlags.Static | BindingFlags.Public);
            Type       registerRtdWrapperDelegateType = integrationAssembly.GetType("ExcelDna.Integration.RegisterRtdWrapperDelegate");
            Delegate   registerRtdWrapperDelegate     = Delegate.CreateDelegate(registerRtdWrapperDelegateType, registerRtdWrapperMethod);

            integrationType.InvokeMember("SetRegisterRtdWrapper", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { registerRtdWrapperDelegate });

            MethodInfo getResourceBytesMethod       = typeof(AssemblyManager).GetMethod("GetResourceBytes", BindingFlags.Static | BindingFlags.NonPublic);
            Type       getResourceBytesDelegateType = integrationAssembly.GetType("ExcelDna.Integration.GetResourceBytesDelegate");
            Delegate   getResourceBytesDelegate     = Delegate.CreateDelegate(getResourceBytesDelegateType, getResourceBytesMethod);

            integrationType.InvokeMember("SetGetResourceBytesDelegate", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { getResourceBytesDelegate });

            // set up helpers for future calls
            IntegrationHelpers.Bind(integrationAssembly, integrationType);
            IntegrationMarshalHelpers.Bind(integrationAssembly);
        }
示例#5
0
        public XlParameterInfo ReturnType; // Macro will have ReturnType null (as will native async functions)

        // THROWS: Throws a DnaMarshalException if the method cannot be turned into an XlMethodInfo
        // TODO: Manage errors if things go wrong
        XlMethodInfo(ModuleBuilder modBuilder, MethodInfo targetMethod, object target, object methodAttribute, List <object> argumentAttributes)
        {
            // Default Name, Description and Category
            Name                 = targetMethod.Name;
            Description          = "";
            Category             = IntegrationHelpers.DnaLibraryGetName();
            HelpTopic            = "";
            IsVolatile           = false;
            IsExceptionSafe      = false;
            IsHidden             = false;
            IsMacroType          = false;
            IsThreadSafe         = false;
            IsClusterSafe        = false;
            ExplicitRegistration = false;

            ShortCut = "";
            // DOCUMENT: Default MenuName is the library name
            // but menu is only added if at least the MenuText is set.
            MenuName = IntegrationHelpers.DnaLibraryGetName();
            MenuText = null; // Menu is only

            // Set default IsCommand - overridden by having an [ExcelCommand] attribute,
            // or by being a native async function.
            // (Must be done before SetAttributeInfo)
            IsCommand = (targetMethod.ReturnType == typeof(void));

            SetAttributeInfo(methodAttribute);
            // We shortcut the rest of the registration
            if (ExplicitRegistration)
            {
                return;
            }

            FixHelpTopic();

            // Return type conversion
            // Careful here - native async functions also return void
            if (targetMethod.ReturnType == typeof(void))
            {
                ReturnType = null;
            }
            else
            {
                ReturnType = new XlParameterInfo(targetMethod.ReturnType, true, IsExceptionSafe);
            }

            ParameterInfo[] parameters = targetMethod.GetParameters();

            // Parameters - meta-data and type conversion
            Parameters = new XlParameterInfo[parameters.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                object argAttrib = null;
                if (argumentAttributes != null && i < argumentAttributes.Count)
                {
                    argAttrib = argumentAttributes[i];
                }
                Parameters[i] = new XlParameterInfo(parameters[i], argAttrib);
            }

            // A native async function might still be marked as a command - check and fix.
            // (these have the ExcelAsyncHandle as last parameter)
            // (This check needs the Parameters array to be set up already.)
            if (IsExcelAsyncFunction)
            {
                // It really is a function, though it might return null
                IsCommand = false;
            }

            // Create the delegate type, wrap the targetMethod and create the delegate

            // CONSIDER: Currently we need a special delegate type here so that we can hook on the marshaling attributes.
            //           Future version might do straight-forward marshaling, so we can get rid of these types (just use generic methods)

            // FirstArgument (if received) is not used in the delegate type created ...
            Type delegateType = CreateDelegateType(modBuilder);
            // ... but is baked into the delegate itself.
            Delegate xlDelegate = CreateMethodDelegate(delegateType, targetMethod, target);

            // Need to add a reference to prevent garbage collection of our delegate
            // Don't need to pin, according to
            // "How to: Marshal Callbacks and Delegates Using C++ Interop"
            // Currently this delegate is never released
            // TODO: Clean up properly
            DelegateHandle  = GCHandle.Alloc(xlDelegate);
            FunctionPointer = Marshal.GetFunctionPointerForDelegate(xlDelegate);
        }
示例#6
0
        // THROWS: Throws a DnaMarshalException if the method cannot be turned into an XlMethodInfo
        // TODO: Manage errors if things go wrong
        XlMethodInfo(MethodInfo targetMethod, object target, object methodAttribute, List <object> argumentAttributes)
        {
            // Default Name, Description and Category
            Name                 = targetMethod.Name;
            Description          = "";
            Category             = IntegrationHelpers.DnaLibraryGetName();
            HelpTopic            = "";
            IsVolatile           = false;
            IsExceptionSafe      = false;
            IsHidden             = false;
            IsMacroType          = false;
            IsThreadSafe         = false;
            IsClusterSafe        = false;
            ExplicitRegistration = false;

            ShortCut = "";
            // DOCUMENT: Default MenuName is the library name
            // but menu is only added if at least the MenuText is set.
            MenuName = IntegrationHelpers.DnaLibraryGetName();
            MenuText = null; // Menu is only

            // Set default IsCommand - overridden by having an [ExcelCommand] attribute,
            // or by being a native async function.
            // (Must be done before SetAttributeInfo)
            IsCommand = (targetMethod.ReturnType == typeof(void));

            SetAttributeInfo(methodAttribute);
            // We shortcut the rest of the registration
            if (ExplicitRegistration)
            {
                return;
            }

            FixHelpTopic();

            // Return type conversion
            // Careful here - native async functions also return void
            if (targetMethod.ReturnType == typeof(void))
            {
                ReturnType = null;
            }
            else
            {
                ReturnType = new XlParameterInfo(targetMethod.ReturnType, true, IsExceptionSafe);
            }

            ParameterInfo[] parameters = targetMethod.GetParameters();

            // Parameters - meta-data and type conversion
            Parameters = new XlParameterInfo[parameters.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                object argAttrib = null;
                if (argumentAttributes != null && i < argumentAttributes.Count)
                {
                    argAttrib = argumentAttributes[i];
                }
                Parameters[i] = new XlParameterInfo(parameters[i], argAttrib);
            }

            // A native async function might still be marked as a command - check and fix.
            // (these have the ExcelAsyncHandle as last parameter)
            // (This check needs the Parameters array to be set up already.)
            if (IsExcelAsyncFunction)
            {
                // It really is a function, though it might return null
                IsCommand = false;
            }
        }