Autoloader fails with IExtensionApplication

Autoloader fails with IExtensionApplication

christian.hestnes
Contributor Contributor
2,052 Views
4 Replies
Message 1 of 5

Autoloader fails with IExtensionApplication

christian.hestnes
Contributor
Contributor

I am experiencing problems when i use Autoloader together with IExtensionApplication.

If i load the dll with netload everything works fine, but if i load it with the Autoloader in a bundle it fails, and i cant fix it by using netload afterwords. If i remove the  IExtensionApplication spesific code, the Autoloader works fine again.

Does anyone know why this happens?

public class AV_Ribbon : IExtensionApplication
    {
        private const string BIKUBE_TAB_ID = "AV_BIKUBE_TAB_ID";
        public void Initialize()
        {
            BikubeRibbon();
        }
        public void Terminate()
        {

        }
        [CommandMethod("BikubeRibbon")]
        public void BikubeRibbon()
        {
            Autodesk.Windows.RibbonControl ribCntrl =
                Autodesk.AutoCAD.Ribbon.RibbonServices.RibbonPaletteSet.RibbonControl;
            //can also be Autodesk.Windows.ComponentManager.Ribbon;     
            RibbonTab ribTab = new RibbonTab();
            ribTab.Title = "Bikube";
            ribTab.Id = BIKUBE_TAB_ID;
            ribCntrl.Tabs.Add(ribTab);

            LeggTilPublPanel(ribTab);
            //ribTab.IsActive = true; //Bytter til denne Tab-en ved innlasting
        }
        private void LeggTilPublPanel(RibbonTab ribTab)
        {
            RibbonPanelSource ribPanelSource = new RibbonPanelSource();
            ribPanelSource.Title = "Publisering";

            RibbonPanel ribPanel = new RibbonPanel();
            ribPanel.Source = ribPanelSource;
            ribTab.Panels.Add(ribPanel);

            RibbonButton ribButton = new RibbonButton();
            ribButton.Size = RibbonItemSize.Large;
            ribButton.Text = "Publiser";
            ribButton.Orientation = System.Windows.Controls.Orientation.Vertical;
            ribButton.LargeImage = GetBitmap(new Bitmap(Properties.Resources.BikubePublisering_ikon_40x40));
            ribButton.ShowText = true;
            ribButton.CommandParameter = "PubliserTilBikube "; //HUSK: mellomrom etter kommando
            ribButton.CommandHandler = new AdskCommandHandler();
            ribPanelSource.Items.Add(ribButton);
        }
        private BitmapImage GetBitmap(Bitmap image)
        {
            MemoryStream stream = new MemoryStream();
            image.Save(stream, ImageFormat.Png);
            BitmapImage bmp = new BitmapImage();
            bmp.BeginInit();
            bmp.StreamSource = stream;
            bmp.EndInit();
            return bmp;
        }
    }
    class AdskCommandHandler : System.Windows.Input.ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
            //is from Ribbon Button
            RibbonButton ribBtn = parameter as RibbonButton;
            if (ribBtn != null)
            {
                //execute the command 
                acApp.DocumentManager.MdiActiveDocument
                .SendStringToExecute(
                   (string)ribBtn.CommandParameter, true, false, true);
            }
        }
    }
0 Likes
Accepted solutions (2)
2,053 Views
4 Replies
Replies (4)
Message 2 of 5

_gile
Consultant
Consultant
Accepted solution

hi,

you can try this way:

public void Initialize()
{
    Autodesk.AutoCAD.ApplicationServices.Core.Application.Idle += OnIdle;
}

private void OnIdle(object sender, EventArgs e)
{
    try
    {
        Autodesk.AutoCAD.ApplicationServices.Core.Application.Idle -= OnIdle;
        BikubeRibbon();
    }
    catch (System.Exception ex)
    {
        var ed = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument.Editor;
        ed.WriteMessage($"\nError: {ex.Message}");
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 5

Norman_Yuan
Mentor
Mentor
Accepted solution

The direct reason that after autoloading your DLL seems not working at all (even you manually run the command "BikubeRibbon", you obviously got "unknown command" error) is that you DID NOT use try...catch... to handle possible exception in the Initialize() method, where you run a fairly complicated code (to build you custom ribbon tab/items), which could cause runtime error, if not coded well, and in your case, the code does indeed cause error.

 

If exception in Initialize() is not caught, the DLL loading would fail, thus code written in the dll would not work. So, ALWAYS place code in Initialize() in a try...catch... block.

 

Now about why your code fails:

 

When your DLL is loaded on AutoCAD startup, you cannot guarantee that AutoCAD has already finishes its Ribbon menu creation when your DLL is loaded. So, the first line of your code in BikubeRibbon() would raise exception if AutoCAD's RibbonControl has not been available at the time.

 

You should start your custom ribbon building process in  the event handler of either RibbonServices.RibbonPaletteSetCreated event or Application.Idle event. 

 

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 4 of 5

christian.hestnes
Contributor
Contributor

Thank you for the tip.

0 Likes
Message 5 of 5

christian.hestnes
Contributor
Contributor

Thank you for the thorough explanation.

0 Likes