static void ProcessProperties(SolidEdgeFramework.Properties properties)
        {
            //SolidEdgeFramework.Property property = null;
            dynamic property = null;  // Using dynamic so that property.Value works.

            for (int i = 1; i <= properties.Count; i++)
            {
                System.Runtime.InteropServices.VarEnum nativePropertyType = System.Runtime.InteropServices.VarEnum.VT_EMPTY;
                Type runtimePropertyType = null;

                object value = null;

                try
                {
                    property           = properties.Item(i);
                    nativePropertyType = (System.Runtime.InteropServices.VarEnum)property.Type;

                    // May throw an exception...
                    value = property.Value;

                    if (value != null)
                    {
                        runtimePropertyType = value.GetType();
                    }
                }
                catch (System.Exception ex)
                {
                    value = ex.Message;
                }

                Console.WriteLine("\t{0} = '{1}' ({2} | {3}).", property.Name, value, nativePropertyType, runtimePropertyType);
            }
        }
        static void AddCustomProperties(SolidEdgeFramework.PropertySets propertySets)
        {
            SolidEdgeFramework.Properties properties = null;

            properties = propertySets.Item("Custom");

            Console.WriteLine("Adding custom properties.");

            properties.Add("My String", "Hello world!");
            properties.Add("My Integer", 338);
            properties.Add("My Boolean", true);
            properties.Add("My DateTime", DateTime.Now);
        }
        static void ProcessPropertySets(SolidEdgeFramework.PropertySets propertySets)
        {
            SolidEdgeFramework.Properties properties = null;

            for (int i = 1; i <= propertySets.Count; i++)
            {
                properties = propertySets.Item(i);

                Console.WriteLine("PropertSet '{0}'.", properties.Name);

                ProcessProperties(properties);
            }
        }
        private void OkButton_Click(object sender, EventArgs e)
        {
            Log.Debug("assemblyDocument: " + this.Document.Name + " path: " + this.Document.Path);
            if (string.IsNullOrEmpty(this.Document.Path))
            {
                MessageBox.Show("You must save the current assembly before adding parts");
            }
            else
            {
                SolidEdgePart.PartDocument partDocument = (SolidEdgePart.PartDocument) this.Document.Application.Documents.Open(this._filePath, 0x00000008);//, "8");
                this.Document.Application.DoIdle();
                Log.Debug("partDocument: " + partDocument.Name);
                // Get file properties of the partDocument
                SolidEdgeFramework.Properties objProperties = ((SolidEdgeFramework.PropertySets)partDocument.Properties).Item("Custom");
                // Handles naming convention when it is not followed
                int length = partDocument.Name.IndexOf(".par");
                if (length <= 0)
                {
                    Log.Warn("selected file is not a Part Document");
                    length = partDocument.Name.Length;
                }
                string   fileName            = partDocument.Name.Substring(0, length);
                string[] variableValuesArray = new string[this._settings.getNumberOfVariables()];
                foreach (PartProperty partProperty in this.partPropertyBindingSource)
                {
                    if (this._settings.isVariableDefined(partProperty.Name))
                    {
                        // Get a reference to the Variables collection.
                        SolidEdgeFramework.Variables variables = (SolidEdgeFramework.Variables)partDocument.Variables;
                        // Get a reference to the variableList.
                        SolidEdgeFramework.VariableList variableList = (SolidEdgeFramework.VariableList)variables.Query(partProperty.Name, SolidEdgeConstants.VariableNameBy.seVariableNameByBoth, SolidEdgeConstants.VariableVarType.SeVariableVarTypeBoth, false);
                        foreach (var property in variableList)
                        {
                            try {
                                Type type = property.GetType();
                                SolidEdgeFramework.ObjectType objectType = (SolidEdgeFramework.ObjectType)type.InvokeMember("Type", System.Reflection.BindingFlags.GetProperty, null, property, null);
                                switch (objectType)
                                {
                                case SolidEdgeFramework.ObjectType.igDimension:
                                    SolidEdgeFrameworkSupport.Dimension dimension = (SolidEdgeFrameworkSupport.Dimension)property;
                                    dimension.Value = partProperty.GetSolidEdgeStoredValue(partDocument.UnitsOfMeasure);
                                    Marshal.FinalReleaseComObject(dimension);
                                    break;

                                case SolidEdgeFramework.ObjectType.igVariable:
                                    SolidEdgeFramework.variable variable = (SolidEdgeFramework.variable)property;
                                    variable.Value = partProperty.GetSolidEdgeStoredValue(partDocument.UnitsOfMeasure);
                                    Marshal.FinalReleaseComObject(variable);
                                    break;
                                }
                                Log.Debug(this._settings.getVariableIndex(partProperty.Name) + " >= " + variableValuesArray.Length);
                                if (this._settings.getVariableIndex(partProperty.Name) >= variableValuesArray.Length)
                                {
                                    Array.Resize <string>(ref variableValuesArray, this._settings.getVariableIndex(partProperty.Name) + 1);
                                }
                                variableValuesArray[this._settings.getVariableIndex(partProperty.Name)] = partProperty.Value + " " + partProperty.Units;
                                // Update file property
                                try {
                                    // TODO: Fix exception when partProperty.Name is not defined in objProperties.Item
                                    SolidEdgeFramework.Property objProperty = objProperties.Item(partProperty.Name);
                                    objProperty.set_Value(partProperty.Value.ToString());
                                    Marshal.FinalReleaseComObject(objProperty);
                                } catch (Exception ex) {
                                    Log.Warn("no file property exists for " + partProperty.Name + " | " + ex.Message);
                                }
                            } catch (Exception ex) {
                                Log.Error(ex.Message);
                            }
                        }
                        Marshal.FinalReleaseComObject(variables);
                        Marshal.FinalReleaseComObject(variableList);
                    }
                }
                objProperties.Save();
                Marshal.FinalReleaseComObject(objProperties);
                // Remove invalid fileName characters
                fileName            = string.Join("", fileName.Split(Path.GetInvalidFileNameChars()));
                variableValuesArray = variableValuesArray.Where(c => c != null).ToArray();
                fileName           += "-" + string.Join(this._settings.getFileNameSeparator(), variableValuesArray);
                Log.Debug("fileName: " + fileName);
                string fullPathName           = this.Document.Path;
                string assemblyPartFolderName = _settings.getAssemblyPartFolderName();
                if (assemblyPartFolderName != null & assemblyPartFolderName != "")
                {
                    assemblyPartFolderName = string.Join("", assemblyPartFolderName.Split(Path.GetInvalidFileNameChars()));
                    fullPathName          += "\\" + assemblyPartFolderName;
                    Directory.CreateDirectory(fullPathName);
                }
                fullPathName += "\\" + fileName + ".par";
                Log.Debug("fullPathName: " + fullPathName);

                if (!File.Exists(fullPathName))
                {
                    partDocument.SaveCopyAs(fullPathName);
                }

                this.Document.Application.DoIdle();
                partDocument.Close(false);
                this.Document.Application.DoIdle();
                Marshal.FinalReleaseComObject(partDocument);
                this.HideConfigurationContainer();
                int count = ((SolidEdgeAssembly.AssemblyDocument) this.Document).Occurrences.Count;
                if (count > 0)
                {
                    SolidEdgeAssembly.Occurrence occurrence = ((SolidEdgeAssembly.AssemblyDocument) this.Document).Occurrences.Item(count);
                    occurrence.GetTransform(out double OriginX, out double OriginY, out double OriginZ, out double AngleX, out double AngleY, out double AngleZ);
                    Marshal.ReleaseComObject(occurrence);
                    double offset = 0.05;
                    occurrence = ((SolidEdgeAssembly.AssemblyDocument) this.Document).Occurrences.AddWithTransform(fullPathName, OriginX + offset, OriginY + offset, OriginZ + offset, AngleX, AngleY, AngleZ);
                    // delete grounded relationship from occurrence.Relations3d
                    SolidEdgeAssembly.Relations3d relation3d = (SolidEdgeAssembly.Relations3d)occurrence.Relations3d;
                    foreach (var relation in relation3d)
                    {
                        Type type = relation.GetType();
                        // Get the value of the Type proprety via Reflection
                        SolidEdgeFramework.ObjectType objectType = (SolidEdgeFramework.ObjectType)type.InvokeMember("Type", BindingFlags.GetProperty, null, relation, null);
                        // Determine the relation type
                        switch (objectType)
                        {
                        case SolidEdgeFramework.ObjectType.igGroundRelation3d:
                            SolidEdgeAssembly.GroundRelation3d groundRelation3d = (SolidEdgeAssembly.GroundRelation3d)relation;
                            groundRelation3d.Delete();
                            break;
                        }
                    }
                    Marshal.FinalReleaseComObject(relation3d);
                    Marshal.FinalReleaseComObject(occurrence);
                }
                else
                {
                    ((SolidEdgeAssembly.AssemblyDocument) this.Document).Occurrences.AddWithTransform(fullPathName, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
                }
            }
        }