PDM Framework in general and Add Hooks

I am not a programmer, but are busy writing an API on SolidWorks PDM, that generates a new serial number with a button click on data card based on variable values on the data card. The general API works well , but when I created a new file within SoldiWorks today and completed the data card and pressed ok, it gave me an error
image
I suspects a potential uncaught unhandled exceptions/references issue as mentioned in your post
PDM addin error code 0x080131513.

I had a quick look at your PDMFramework. What is the benefit of using this rather than the standard VisualBasic EPDM libraries? Using this extension give you new command that can be used, but I found it very difficult to use, not having resources to tell me how to use it?

I however have tried to use the PDM Framework by just pasting my code in the AddInBase section, but it does not recognize my button click to execute the code. I then realized that I did not add the addHook command to notify the addin that there is a card button.

I tried to add it as normal with the following code:

public void GetAddInInfo(ref EdmAddInInfo poInfo, IEdmVault5 poVault, IEdmCmdMgr5 poCmdMgr)
{
poCmdMgr.AddHook(EdmCmdType.EdmCmd_CardButton);
poCmdMgr.AddHook(EdmCmdType.EdmCmd_SerialNo);
}

But VB gave me an error that it is already in an inherited member in AddInBase. So I recon that it was part of your PDMFramework, the question was just how to add it. I then played around a bit with the command under enum and realized there is a “Flag” and “TaskFlag” command. I then managed to add the first TaskFlag as follows:

[TaskFlags((int)EdmCmdType.EdmCmd_CardButton)]

But VB complains if I want to add a second TaskFlag item, it also complains if I add it as a second argument to the TaskFlag. I though I will compile and see if this works, but it still does not recognize card button when clicked.

Do you have any recommendations?

Typically that error is due to an uncaught/unhandled exception happening within your code. For every hooked action, the add-in has OnCmd called. See if you can debug your add-in and step through your code to see where this may be happening.

Debugging SOLIDWORKS PDM Add-In - Best Practices.

Regarding the PDMFramework: You’re right that there isn’t a lot of documentation yet. @AmenJlili and his group have done a great job creating this framework and I assume are working on building more examples and documentation.

From what I have gleaned, he’s set up the hooks and everything to be an attribute that you can assign to the AddInBase class. See below for the outline of an add-in that I started using this framework. Maybe it will help.

using BlueByte.SOLIDWORKS.PDMProfessional.PDMAddInFramework;
using BlueByte.SOLIDWORKS.PDMProfessional.PDMAddInFramework.Attributes;
using BlueByte.SOLIDWORKS.PDMProfessional.PDMAddInFramework.Enums;
using BlueByte.SOLIDWORKS.PDMProfessional.PDMAddInFramework.Diagnostics;
using EPDM.Interop.epdm;
using SimpleInjector;
using System;
using System.IO;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace PDM_AddIn
{
    public enum Commands
    {
        AssignSerialNumber = 1001,
        RenameToPN = 1002,
        AddInVersion =1003
    }

    [Menu((int)Commands.AssignSerialNumber, "Assign Serial. Number")]
    [Menu((int)Commands.RenameToPN, "Rename to  PN")]
    [Menu((int)Commands.AddInVersion, "Add-In Version")]
    [ListenFor(EdmCmdType.EdmCmd_PreState)]
    [ListenFor(EdmCmdType.EdmCmd_PostState)]
    [ListenFor(EdmCmdType.EdmCmd_PreUnlock)]
    [ListenFor(EdmCmdType.EdmCmd_PostLock)]
    [ListenFor(EdmCmdType.EdmCmd_PostAdd)]
    [ListenFor(EdmCmdType.EdmCmd_PostCopy)]
    [ListenFor(EdmCmdType.EdmCmd_PreUndoLock)]
    [Name("Acme EPDM Add-In - PDMFramework")]
    [Description("Handles Custom Routines")]
    [CompanyName("ACME Inc.")]
    [AddInVersion(false, 1)]
    [IsTask(false)]
    [RequiredVersion(Year_e.PDM2021, ServicePack_e.SP5)]
    [ComVisible(true)]
    [Guid("YOUR GUID HERE")]
    public partial class PDM_AddIn_PDMFramework : AddInBase
    {
        public override void OnCmd(ref EdmCmd poCmd, ref EdmCmdData[] ppoData)
        {
            try
            {
                base.OnCmd(ref poCmd, ref ppoData);
                Logger.LogToOutput("", $"Event Trigger: {poCmd.meCmdType}");

                switch (poCmd.meCmdType)
                {
                    #region PostAdd & PostCopy
                    case EdmCmdType.EdmCmd_PostAdd:
                    case EdmCmdType.EdmCmd_PostCopy: //a file was just added to the vault
                        {
                        }
                        break;
                    #endregion

                    #region PostLock
                    case EdmCmdType.EdmCmd_PostLock: //user just checked out a file.
                        {
                        }
                        break;
                    #endregion

                    #region PreState
                    case EdmCmdType.EdmCmd_PreState: //user is trying to change state
                        {
                        }
                        break;
                    #endregion

                    #region PostState
                    case EdmCmdType.EdmCmd_PostState: //user has changed the state
                        {
                        }
                        break;
                    #endregion

                    #region PreUnlock
                    case EdmCmdType.EdmCmd_PreUnlock:   //just getting ready to check in files
                        {
                        }
                        break;
                    #endregion

                    #region Default
                    default: //no prehooks must be a hook from a menu
                        {
                            switch (poCmd.mlCmdID)
                            {
                                case (int)Commands.AssignSerialNumber:
                                    {

                                    }
                                    break;
                                case (int)Commands.RenameToPN:
                                    {

                                    }
                                    break;
                                case (int)Commands.AddInVersion:
                                    {

                                    }
                                    break;
                            }
                            break;
                            #endregion
                        }

                }
            }
            catch(Exception)
            {
                MessageBox.Show(MyInfo.GetWin32WindowHandle(poCmd.mlParentWnd), "Error in function OnCmd", "ACME PDM Add-In", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }


        protected override void OnLoggerTypeChosen(LoggerType_e defaultType)
        {
            base.OnLoggerTypeChosen(LoggerType_e.Console);
        }

        protected override void OnRegisterAdditionalTypes(Container container)
        {
            // register types with the container 
        }

        protected override void OnLoggerOutputSat(string defaultDirectory)
        {
            // set the logger default directory - ONLY USE IF YOU ARE NOT LOGGING TO PDM
        }
        protected override void OnLoadAdditionalAssemblies(DirectoryInfo addinDirectory)
        {
            base.OnLoadAdditionalAssemblies(addinDirectory);
        }

        protected override void OnUnhandledExceptions(bool catchAllExceptions, Action<Exception> logAction = null)
        {
            this.CatchAllUnhandledException = false;

            logAction = (Exception e) =>
            {
                throw new NotImplementedException();
            };


            base.OnUnhandledExceptions(catchAllExceptions, logAction);
        }
    }
}

That error is unrelated to the framework. It’s prolly has to do with your references.

Wrap your OnCmd implementation in a try catch block.

Take a look at this video series to get started:

[TaskFlags((int)EdmCmdType.EdmCmd_CardButton)]
Only use TaskFlags with EdmTaskFlag Enumeration - 2015 - SOLIDWORKS API Help not EmdCmdType.

Thanks for the replies, I understand that the error is unrelated to the framework, but I just wanted to see how the framework works and if this might solve my issue and what benefit it will add by using it.

So basically what you are saying is to use the EdmCmdType you need to include this under the AddInBase with a switch and case statement?

switch (poCmd.meCmdType)
                {
                    #region PostAdd & PostCopy
                    case EdmCmdType.EdmCmd_Cardbutton:
                    case EdmCmdType.EdmCmd_SerialNo: 
                        {
                        }
                        break;
                    #endregion

I already have the OnCmd wrap in a try catch block but only after the
base.OnCmd(ref poCmd, ref ppoData);
is called. But this does not catch any errors.

Thanks I have already went through your YouTube series, which helped me to get started, but not entirely to resolve my issue on how to go forward with the framework.

@BigCrazyAl I tried to debug to see where the code fails, but it seems like it does not even start with the OnCmd function, so it is very difficult to tell you what could be the issue. I normally debug by attaching to process and since it is failing in SolidWorks I attached the SolidWorks process, with a break point at the first code line within OnCmd. SolidWorks crashed before reaching the break point.

@wjvisagie, You can separate your EdmCmdType with a switch/case block or any other alternative that performs the same task. It could also be done with a series of if/else-if statements if you really want to. The switch statement looks cleaner here in my opinion.

Debugging an add-in requires that you go through a bit of a different route in order to get Visual Studio to allow you to step through code to see what’s happening. The codestack link in my previous post shows the process to go through and get the debugging to work properly. If you get it set up correctly, you can launch a browser window from visual studio that attaches to the PDM Add-In that you’ve written.

@wjvisagie : Debugging PDM add-ins is hard. I have a unit testing framework that does it. More than happy to demo it to you.

1 Like

@wjvisagie : Were you able to solve your issue?