/// <summary> /// Runs an action and catches any exceptions thrown /// wrapping and rethrowing them as a <see cref="SolidDnaException"/> /// </summary> /// <param name="action">The action to run</param> /// <param name="errorTypeCode">The <see cref="SolidDnaErrorTypeCode"/> to wrap the exception in</param> /// <param name="errorCode">The <see cref="SolidDnaErrorCode"/> to wrap the exception in</param> /// <param name="errorDescription">The description of the error if thrown</param> public static void Wrap(Action action, SolidDnaErrorTypeCode errorTypeCode, SolidDnaErrorCode errorCode, string errorDescription) { try { action(); } catch (Exception ex) { // Create the SolidDNA exception var error = new SolidDnaException(SolidDnaErrors.CreateError( errorTypeCode, errorCode, errorDescription), ex); // If it should just be logged and ignored, log it if (SolidDnaEnvironment.LogAndIgnoreUncaughtExceptions) { // Log the error Logger.Log($"SolidDNA Exception created. {error.SolidDnaError?.ToString()}"); if (error.InnerException != null) { Logger.Log($"Inner Exception: { error.InnerException.GetErrorMessage()}"); } } // Otherwise, throw else { throw error; } } }
/// <summary> /// Runs a function and catches any exceptions thrown, /// wrapping and rethrowing them as a <see cref="SolidDnaException"/> /// </summary> /// <param name="func">The function to run</param> /// <param name="errorTypeCode">The <see cref="SolidDnaErrorTypeCode"/> to wrap the exception in</param> /// <param name="errorCode">The <see cref="SolidDnaErrorCode"/> to wrap the exception in</param> /// <param name="errorDescription">The description of the error if thrown</param> public static T Wrap <T>(Func <T> func, SolidDnaErrorTypeCode errorTypeCode, SolidDnaErrorCode errorCode, string errorDescription) { try { return(func()); } catch (Exception ex) { // Create the SolidDNA exception var error = new SolidDnaException(SolidDnaErrors.CreateError( errorTypeCode, errorCode, errorDescription), ex); // If it should just be logged and ignored, log it if (SolidDnaEnvironment.LogAndIgnoreUncaughtExceptions) { // Log the error Logger.LogCriticalSource($"SolidDNA Exception created. {error.SolidDnaError?.ToString()}"); if (error.InnerException != null) { Logger.LogCriticalSource($"Inner Exception: { error.InnerException.GetErrorMessage()}"); } return(default(T)); } // Otherwise, throw else { throw error; } } }
/// <summary> /// Runs a task and catches any exceptions thrown /// wrapping and rethrowing them as a <see cref="SolidDnaException"/> /// /// Returns the result of the task /// </summary> /// <param name="task">The task to run</param> /// <param name="errorTypeCode">The <see cref="SolidDnaErrorTypeCode"/> to wrap the exception in</param> /// <param name="errorCode">The <see cref="SolidDnaErrorCode"/> to wrap the exception in</param> /// <param name="errorDescription">The description of the error if thrown</param> public static async Task <T> WrapAwait <T>(Func <Task <T> > task, SolidDnaErrorTypeCode errorTypeCode, SolidDnaErrorCode errorCode, string errorDescription) { try { return(await task()); } catch (Exception ex) { // Create the SolidDNA exception var error = new SolidDnaException(SolidDnaErrors.CreateError( errorTypeCode, errorCode, errorDescription), ex); // If it should just be logged and ignored, log it if (SolidDnaEnvironment.LogAndIgnoreUncaughtExceptions) { // Log the error Logger.Log($"SolidDNA Exception created. {error.SolidDnaError?.ToString()}"); if (error.InnerException != null) { Logger.Log($"Inner Exception: { error.InnerException.GetErrorMessage()}"); } // Return a default object return(default(T)); } // Otherwise, throw it up else { throw error; } } }
/// <summary> /// Set's all icon lists based on a string format of the absolute path to the icon list images, replacing {0} with the size. /// For example C:\Folder\myiconlist{0}.png would look for all sizes such as /// C:\Folder\myiconlist20.png /// C:\Folder\myiconlist32.png /// C:\Folder\myiconlist40.png /// ... and so on /// </summary> /// <param name="pathFormat">The absolute path, with {0} used to replace with the icon size</param> public void SetIconLists(string pathFormat) { // Make sure we have something if (string.IsNullOrWhiteSpace(pathFormat)) { return; } // Make sure the path format contains "{0}" if (!pathFormat.Contains("{0}")) { throw new SolidDnaException(SolidDnaErrors.CreateError( SolidDnaErrorTypeCode.SolidWorksCommandManager, SolidDnaErrorCode.SolidWorksCommandGroupIvalidPathFormatError, Localization.GetString("ErrorSolidWorksCommandGroupIconListInvalidPathError"))); } // Find 20 image var result = string.Format(pathFormat, 20); if (File.Exists(result)) { IconList20Path = result; } // Find 32 image result = string.Format(pathFormat, 32); if (File.Exists(result)) { IconList32Path = result; } // Find 40 image result = string.Format(pathFormat, 40); if (File.Exists(result)) { IconList40Path = result; } // Find 64 image result = string.Format(pathFormat, 64); if (File.Exists(result)) { IconList64Path = result; } // Find 96 image result = string.Format(pathFormat, 96); if (File.Exists(result)) { IconList96Path = result; } // Find 128 image result = string.Format(pathFormat, 128); if (File.Exists(result)) { IconList128Path = result; } }
/// <summary> /// Create a command group flyout containing a list of <see cref="CommandManagerItem"/> items /// </summary> /// <param name="title">Name of the flyout to create</param> /// <param name="items">The command items to add</param> /// <param name="pathFormat">The icon list absolute path based on a string format of the absolute path to the icon list images, replacing {0} with the size. /// For example C:\Folder\myiconlist{0}.png</param> /// <param name="tooltip">Tool tip for the new flyout</param> /// <param name="hint">Text displayed in SOLIDWORKS status bar when a user's mouse pointer is over the flyout</param> /// <returns></returns> public CommandManagerFlyout CreateFlyoutGroup(string title, List <CommandManagerItem> items, string pathFormat, string tooltip = "", string hint = "") { #region Icons // Make sure the path format contains "{0}" if (pathFormat == null || !pathFormat.Contains("{0}")) { throw new SolidDnaException(SolidDnaErrors.CreateError( SolidDnaErrorTypeCode.SolidWorksCommandManager, SolidDnaErrorCode.SolidWorksCommandGroupInvalidPathFormatError, Localization.GetString("ErrorSolidWorksCommandGroupIconListInvalidPathError"))); } var iconListPaths = new Dictionary <int, string>(); // Fill the dictionary with all paths that exist foreach (var iconSize in mIconSizes) { var path = string.Format(pathFormat, iconSize); if (File.Exists(path)) { iconListPaths.Add(iconSize, path); } } // Get icon paths var icons = iconListPaths.Values.ToArray(); #endregion // Create unique callback Id var callbackId = Guid.NewGuid().ToString("N"); // Attempt to create the command flyout var unsafeCommandFlyout = BaseObject.CreateFlyoutGroup2( mFlyoutIdCount, title, tooltip, hint, icons, icons, $"Callback({callbackId})", null); // Create managed object var flyout = new CommandManagerFlyout( unsafeCommandFlyout, mFlyoutIdCount++, callbackId, items, title, hint, tooltip); // Return it return(flyout); }
/// <summary> /// Get's the command tab for this /// </summary> /// <param name="type">The type of document to get the tab for. Use only Part, Assembly or Drawing one at a time, otherwise the first found tab gets returned</param> /// <param name="title">The title of the command tab to get</param> /// <param name="createIfNotExist">True to create the tab if it does not exist</param> /// <param name="clearExistingItems">Removes any existing items on the tab if true</param> /// <returns></returns> public CommandManagerTab GetCommandTab(ModelType type, string title, bool createIfNotExist = true, bool clearExistingItems = true) { // Try and get the tab var unsafeTab = mBaseObject.GetCommandTab((int)type, title); // If we did not get it, just ignore if (unsafeTab == null && !createIfNotExist) { return(null); } // If we want to remove any previous tabs... while (clearExistingItems && unsafeTab != null) { // Remove it mBaseObject.RemoveCommandTab(unsafeTab); // Clean COM object Marshal.ReleaseComObject(unsafeTab); // Try and get another unsafeTab = mBaseObject.GetCommandTab((int)type, title); } // Create it if it doesn't exist if (unsafeTab == null) { unsafeTab = mBaseObject.AddCommandTab((int)type, title); } // If it's still null, we failed if (unsafeTab == null) { // Throw error throw new SolidDnaException(SolidDnaErrors.CreateError( SolidDnaErrorTypeCode.SolidWorksCommandManager, SolidDnaErrorCode.SolidWorksCommandGroupCreateTabError, Localization.GetString("ErrorSolidWorksCommandCreateTabError"))); } // Return tab return(new CommandManagerTab(unsafeTab)); }
/// <summary> /// Creates a command group /// </summary> /// <param name="title">The title</param> /// <param name="items">The command items to add</param> /// <param name="tooltip">The tool tip</param> /// <param name="hint">The hint</param> /// <param name="position">Position of the CommandGroup in the CommandManager for all document templates. /// NOTE: Specify 0 to add the CommandGroup to the beginning of the CommandMananger, or specify -1 to add it to the end of the CommandManager. /// NOTE: You can also use ICommandGroup::MenuPosition to control the position of the CommandGroup in specific document templates.</param> /// <param name="ignorePreviousVersion">True to remove all previously saved customization and toolbar information before creating a new CommandGroup, false to not. /// Call CommandManager.GetGroupDataFromRegistry before calling this method to determine how to set IgnorePreviousVersion. /// Set IgnorePreviousVersion to true to prevent SOLIDWORKS from saving the current toolbar setting to the registry, even if there is no previous version.</param> /// <param name="hasMenu">Whether the CommandGroup should appear in the Tools dropdown menu.</param> /// <param name="hasToolbar">Whether the CommandGroup should appear in the Command Manager and as a separate toolbar.</param> /// <returns></returns> private CommandManagerGroup CreateCommandGroup(string title, List <CommandManagerItem> items, string tooltip = "", string hint = "", int position = -1, bool ignorePreviousVersion = true, bool hasMenu = true, bool hasToolbar = true) { // NOTE: We may need to look carefully at this Id if things get removed and re-added based on this SolidWorks note: // // If you change the definition of an existing CommandGroup (i.e., add or remove toolbar buttons), you must assign a // new unique user-defined UserID to that CommandGroup. You must perform this action to avoid conflicts with any // previously existing CommandGroups and to allow for backward and forward compatibility of the CommandGroups in your application. // // Get the next Id var id = mCommandGroups.Count == 0 ? 1 : mCommandGroups.Max(f => f.UserId) + 1; // Store error code var errors = -1; // Attempt to create the command group var unsafeCommandGroup = mBaseObject.CreateCommandGroup2(id, title, tooltip, hint, position, ignorePreviousVersion, ref errors); // Check for errors if (errors != (int)swCreateCommandGroupErrors.swCreateCommandGroup_Success) { // Get enum name var errorEnumString = ((swCreateCommandGroupErrors)errors).ToString(); // Throw error throw new SolidDnaException(SolidDnaErrors.CreateError( SolidDnaErrorTypeCode.SolidWorksCommandManager, SolidDnaErrorCode.SolidWorksCommandGroupCreateError, Localization.GetString("ErrorSolidWorksCommandGroupAddError") + $". {errorEnumString}")); } // Otherwise we got the command group var group = new CommandManagerGroup(unsafeCommandGroup, items, id, title, tooltip, hint, hasMenu, hasToolbar); // Return it return(group); }
/// <summary> /// Reads the material database and adds the materials to the given list /// </summary> /// <param name="database">The database to read</param> /// <param name="list">The list to add materials to</param> private void ReadMaterials(string database, ref List <Material> list) { // First make sure the file exists if (!File.Exists(database)) { throw new SolidDnaException( SolidDnaErrors.CreateError( SolidDnaErrorTypeCode.SolidWorksApplication, SolidDnaErrorCode.SolidWorksApplicationGetMaterialsFileNotFoundError, Localization.GetString("SolidWorksApplicationGetMaterialsFileNotFoundError"))); } try { // File should be an XML document, so attempt to read that using (var stream = File.Open(database, FileMode.Open, FileAccess.Read, FileShare.Read)) { // Try and parse the Xml var xmlDoc = XDocument.Load(stream); // Make sure we got something if (xmlDoc == null) { throw new ArgumentNullException(Localization.GetString("SolidWorksApplicationGetMaterialsXmlNotLoadedError")); } var materials = new List <Material>(); // Iterate all classification nodes and inside are the materials xmlDoc.Root.Elements("classification")?.ToList()?.ForEach(f => { // Get classification name var classification = f.Attribute("name")?.Value; // Iterate all materials f.Elements("material").ToList().ForEach(material => { // Add them to the list materials.Add(new Material { Database = database, DatabaseFileFound = true, Classification = classification, Name = material.Attribute("name")?.Value, Description = material.Attribute("description")?.Value, }); }); }); // If we found any materials, add them if (materials.Count > 0) { list.AddRange(materials); } } } catch (Exception ex) { // If we crashed for any reason during parsing, wrap in SolidDna exception if (!File.Exists(database)) { throw new SolidDnaException( SolidDnaErrors.CreateError( SolidDnaErrorTypeCode.SolidWorksApplication, SolidDnaErrorCode.SolidWorksApplicationGetMaterialsFileFormatError, Localization.GetString("SolidWorksApplicationGetMaterialsFileFormatError"), ex)); } } }
/// <summary> /// Creates the command group based on it's current children /// NOTE: Once created, parent command manager must remove and re-create the group /// This group cannot be re-used after creating, any edits will not take place /// </summary> /// <param name="manager">The command manager that is our owner</param> public void Create(CommandManager manager) { if (mCreated) { throw new SolidDnaException(SolidDnaErrors.CreateError( SolidDnaErrorTypeCode.SolidWorksCommandManager, SolidDnaErrorCode.SolidWorksCommandGroupReActivateError, Localization.GetString("ErrorSolidWorksCommandGroupReCreateError"))); } #region Set Icons // // Set the icons // // NOTE: The order in which you specify the icons must be the same for this property and MainIconList. // // For example, if you specify an array of paths to // 20 x 20 pixels, 32 x 32 pixels, and 40 x 40 pixels icons for this property // then you must specify an array of paths to // 20 x 20 pixels, 32 x 32 pixels, and 40 x 40 pixels icons for MainIconList.</remarks> // // Set all icon lists var icons = GetIconListPaths(); // 2016+ support mBaseObject.IconList = icons.ToArray(); // <2016 support if (icons.Count > 0) { // Largest icon for this one mBaseObject.LargeIconList = icons.Last(); // The list of icons mBaseObject.MainIconList = icons.ToArray(); // Use the largest available image for small icons too mBaseObject.SmallIconList = icons.Last(); } #endregion #region Add Items // Add items this.Items?.ForEach(item => AddCommandItem(item)); #endregion // Activate the command group mCreated = mBaseObject.Activate(); // Get command Ids this.Items?.ForEach(item => item.CommandId = mBaseObject.CommandID[item.UniqueId]); #region Command Tab // Add to parts tab var list = this.Items.Where(f => f.TabView != CommandManagerItemTabView.None && f.VisibleForParts).ToList(); if (list?.Count > 0) { AddItemsToTab(ModelType.Part, manager, list); } // Add to assembly tab list = this.Items.Where(f => f.TabView != CommandManagerItemTabView.None && f.VisibleForAssemblies).ToList(); if (list?.Count > 0) { AddItemsToTab(ModelType.Assembly, manager, list); } // Add to drawing tab list = this.Items.Where(f => f.TabView != CommandManagerItemTabView.None && f.VisibleForDrawings).ToList(); if (list?.Count > 0) { AddItemsToTab(ModelType.Drawing, manager, list); } #endregion // If we failed to create, throw if (!mCreated) { throw new SolidDnaException(SolidDnaErrors.CreateError( SolidDnaErrorTypeCode.SolidWorksCommandManager, SolidDnaErrorCode.SolidWorksCommandGroupActivateError, Localization.GetString("ErrorSolidWorksCommandGroupActivateError"))); } }