Exemple #1
0
        public static void LoadComAddIn(ExcelComAddIn addIn)
        {
            // If we are called without the addIn's DnaLibrary being set, default to the current library
            if (addIn.DnaLibrary == null)
            {
                addIn.DnaLibrary = DnaLibrary.CurrentLibrary;
            }

            CLSID  clsId;
            string progId;

            // If we have both an explicit Guid and an explicit ProgId, then use those, else create synthetic ProgId.
            object[] progIdAttrs = addIn.GetType().GetCustomAttributes(typeof(ProgIdAttribute), false);
            object[] guidAttrs   = addIn.GetType().GetCustomAttributes(typeof(GuidAttribute), false);
            if (progIdAttrs.Length >= 1 && guidAttrs.Length >= 1)
            {
                // Use the attributes
                ProgIdAttribute progIdAtt = (ProgIdAttribute)progIdAttrs[0];
                progId = progIdAtt.Value;

                GuidAttribute guidAtt = (GuidAttribute)guidAttrs[0];
                clsId = new Guid(guidAtt.Value);
            }
            else
            {
                // We pick a new Guid as ClassId for this add-in.
                clsId = Guid.NewGuid();
                // and make the ProgId from this Guid - max 39 chars....
                progId = "AddIn." + clsId.ToString("N");
            }
            addIn.SetProgId(progId);

            // Put together some nicer descriptions for the Add-ins dialog.
            string friendlyName;

            if (addIn is ExcelRibbon)
            {
                friendlyName = addIn.DnaLibrary.Name; // + " (Ribbon Helper)"; (No more - it is displayed in the Ribbon tooltip!)
            }
            else if (addIn is ExcelCustomTaskPaneAddIn)
            {
                friendlyName = addIn.DnaLibrary.Name + " (Custom Task Pane Helper)";
            }
            else
            {
                friendlyName = addIn.DnaLibrary.Name + " (COM Add-in Helper)";
            }
            string description = string.Format("Dynamically created COM Add-in to load custom UI for the Excel Add-in {0}, located at {1}.", addIn.DnaLibrary.Name, DnaLibrary.XllPath);

            try
            {
                Debug.Print("Getting Application object");
                object app     = ExcelDnaUtil.Application;
                Type   appType = app.GetType();
                Debug.Print("Got Application object: " + app.GetType().ToString());

                CultureInfo ci = new CultureInfo(1033);

                object excelComAddIns;
                object comAddIn;
                using (new SingletonClassFactoryRegistration(addIn, clsId))
                    using (new ProgIdRegistration(progId, clsId))
                        using (new ComAddInRegistration(progId, friendlyName, description))
                        {
                            excelComAddIns = appType.InvokeMember("COMAddIns", BindingFlags.GetProperty, null, app, null, ci);
//                            Debug.Print("Got COMAddins object: " + excelComAddIns.GetType().ToString());
                            appType.InvokeMember("Update", BindingFlags.InvokeMethod, null, excelComAddIns, null, ci);
//                            Debug.Print("Updated COMAddins object with AddIn registered");
                            comAddIn = excelComAddIns.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, excelComAddIns, new object[] { progId }, ci);
//                            Debug.Print("Got the COMAddin object: " + comAddIn.GetType().ToString());

                            // At this point Excel knows how to load our add-in by CLSID, so we could clean up the
                            // registry aggressively, before the actual (dangerous?) loading starts.
                            // But this seems to lead to some distress - Excel has some assertion checked when
                            // it updates the LoadBehavior after a successful load....
                            comAddIn.GetType().InvokeMember("Connect", BindingFlags.SetProperty, null, comAddIn, new object[] { true }, ci);
//                            Debug.Print("COMAddin is loaded.");
                            loadedComAddIns.Add(comAddIn);
                        }
            }
            catch (Exception e)
            {
                Debug.Print("LoadComAddIn exception: " + e.ToString());
                // CONSIDER: How to deal with errors here...? For now I just re-raise the exception.
                throw;
            }
        }
        public static void LoadComAddIn(ExcelComAddIn addIn)
        {
            // If we are called without the addIn's DnaLibrary being set, default to the current library
            if (addIn.DnaLibrary == null)
                addIn.DnaLibrary = DnaLibrary.CurrentLibrary;

            CLSID clsId;
            string progId;

            // If we have both an explicit Guid and an explicit ProgId, then use those, else create synthetic ProgId.
            object[] progIdAttrs = addIn.GetType().GetCustomAttributes(typeof(ProgIdAttribute), false);
            object[] guidAttrs   = addIn.GetType().GetCustomAttributes(typeof(GuidAttribute),   false);
            if (progIdAttrs.Length >= 1 && guidAttrs.Length >= 1)
            {
                // Use the attributes
                ProgIdAttribute progIdAtt = (ProgIdAttribute)progIdAttrs[0];
                progId = progIdAtt.Value;

                GuidAttribute guidAtt = (GuidAttribute)guidAttrs[0];
                clsId = new Guid(guidAtt.Value);
            }
            else
            {
                // We pick a new Guid as ClassId for this add-in.
                clsId = Guid.NewGuid();
                // and make the ProgId from this Guid - max 39 chars....
                progId = "AddIn." + clsId.ToString("N");
            }
            addIn.SetProgId(progId);

            // Put together some nicer descriptions for the Add-ins dialog.
            string friendlyName;
            if (addIn is ExcelRibbon)
                friendlyName = addIn.DnaLibrary.Name; // + " (Ribbon Helper)"; (No more - it is displayed in the Ribbon tooltip!)
            else if (addIn is ExcelCustomTaskPaneAddIn)
                friendlyName = addIn.DnaLibrary.Name + " (Custom Task Pane Helper)";
            else
                friendlyName = addIn.DnaLibrary.Name + " (COM Add-in Helper)";
            string description = string.Format("Dynamically created COM Add-in to load custom UI for the Excel Add-in {0}, located at {1}.", addIn.DnaLibrary.Name, DnaLibrary.XllPath);

            try
            {
                Debug.Print("Getting Application object");
                object app = ExcelDnaUtil.Application;
                Type appType = app.GetType();
                Debug.Print("Got Application object: " + app.GetType().ToString());

                CultureInfo ci = new CultureInfo(1033);

                object excelComAddIns;
                object comAddIn;
                using (new SingletonClassFactoryRegistration(addIn, clsId))
                using (new ProgIdRegistration(progId, clsId))
                using (new ComAddInRegistration(progId, friendlyName, description))
                {
                    excelComAddIns = appType.InvokeMember("COMAddIns", BindingFlags.GetProperty, null, app, null, ci);
                    //                            Debug.Print("Got COMAddins object: " + excelComAddIns.GetType().ToString());
                    appType.InvokeMember("Update", BindingFlags.InvokeMethod, null, excelComAddIns, null, ci);
                    //                            Debug.Print("Updated COMAddins object with AddIn registered");
                    comAddIn = excelComAddIns.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, excelComAddIns, new object[] { progId }, ci);
                    //                            Debug.Print("Got the COMAddin object: " + comAddIn.GetType().ToString());

                    // At this point Excel knows how to load our add-in by CLSID, so we could clean up the
                    // registry aggressively, before the actual (dangerous?) loading starts.
                    // But this seems to lead to some distress - Excel has some assertion checked when
                    // it updates the LoadBehavior after a successful load....
                    comAddIn.GetType().InvokeMember("Connect", BindingFlags.SetProperty, null, comAddIn, new object[] { true }, ci);
                    //                            Debug.Print("COMAddin is loaded.");
                    loadedComAddIns.Add(comAddIn);
                }
            }
            catch (UnauthorizedAccessException secex)
            {
                Logging.LogDisplay.WriteLine("The Ribbon helper required by add-in {0} could not be registered.\r\nThis may be due to restricted permissions on the user's HKCU\\Software\\Classes key.\r\nError message: {1}", DnaLibrary.CurrentLibrary.Name, secex.Message);
                return;
            }
            catch (Exception e)
            {
                Debug.Print("LoadComAddIn exception: " + e.ToString());
                // CONSIDER: How to deal with errors here...? For now I just re-raise the exception.
                throw;
            }
        }
Exemple #3
0
        public static void LoadComAddIn(ExcelComAddIn addIn)
        {
            // We pick a new Guid as ClassId for this add-in.
            CLSID clsId = Guid.NewGuid();
            // and make the ProgId from this Guid - max 39 chars....
            string progId = "AddIn." + clsId.ToString("N");
            addIn.SetProgId(progId);
            // Put together some nicer descriptions for the Add-ins dialog.
            string friendlyName;
            if (addIn is ExcelRibbon)
                friendlyName = addIn.DnaLibrary.Name + " (Ribbon Helper)";
            else if (addIn is ExcelCustomTaskPaneAddIn)
                friendlyName = addIn.DnaLibrary.Name + " (Custom Task Pane Helper)";
            else 
                friendlyName = addIn.DnaLibrary.Name + " (COM Add-in Helper)";
            string description = string.Format("Dynamically created COM Add-in to load custom UI for the Excel Add-in {0}, located at {1}.", addIn.DnaLibrary.Name, DnaLibrary.XllPath);

            try
            {
                Debug.Print("Getting Application object");
                object app = ExcelDnaUtil.Application;
                Type appType = app.GetType();
                Debug.Print("Got Application object: " + app.GetType().ToString());

                CultureInfo ci = new CultureInfo(1033);

                object excelComAddIns;
                object comAddIn;
                using (SingletonClassFactoryRegistration regClassFactory = new SingletonClassFactoryRegistration(addIn, clsId))
                using (ProgIdRegistration regProgId = new ProgIdRegistration(progId, clsId))
                using (ComAddInRegistration regComAddIn = new ComAddInRegistration(progId, friendlyName, description))
                {
                    excelComAddIns = appType.InvokeMember("COMAddIns", BindingFlags.GetProperty, null, app, null, ci);
//                            Debug.Print("Got COMAddins object: " + excelComAddIns.GetType().ToString());
                    appType.InvokeMember("Update", BindingFlags.InvokeMethod, null, excelComAddIns, null, ci);
//                            Debug.Print("Updated COMAddins object with AddIn registered");
                    comAddIn = excelComAddIns.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, excelComAddIns, new object[] { progId }, ci);
//                            Debug.Print("Got the COMAddin object: " + comAddIn.GetType().ToString());

                    // At this point Excel knows how to load our add-in by CLSID, so we could clean up the 
                    // registry aggressively, before the actual (dangerous?) loading starts.
                    // But this seems to lead to some distress - Excel has some assertion checked when 
                    // it updates the LoadBehavior after a successful load....
                    comAddIn.GetType().InvokeMember("Connect", BindingFlags.SetProperty, null, comAddIn, new object[] { true }, ci);
//                            Debug.Print("COMAddin is loaded.");
                    loadedComAddIns.Add(comAddIn);
                }
            }
            catch (Exception e)
            {
                Debug.Print("LoadComAddIn exception: " + e.ToString());
                // CONSIDER: How to deal with errors here...? For now I just re-raise the exception.
                throw;
            }
        }