I frequently have to update and distribute our company Dynamo Custom Packages, but I also like to check the packages before I roll them out to make sure they are loading in correctly and none of our standard graphs blow out due to deprecated/modified nodes.

For doing this, I have my own local package folders which mirrors the ones on the server where I install and test then roll out (this is just the way I do it anyway). But I hate having to change the package paths over and over, we have a couple, one for third party packages and one for homegrown packages. So I made a little Admin utility to switch these for me in Dynamo Sandbox. I originally did this in Visual Studio for a mess-around project but can easily be done in Dynamo.

(I am very lazy btw. If I were a cartoon character I would probably be Garfield the Cat as we both like lasagna, making life as easy as possible and in dire need of exercise).

1vmcn9.jpg

Anyway, I thought I would post this as it also shows how to modify an .xml file in python as this script requires that I read the DynamoSettings.xml file, makes some changes and write it back. The reason this is in Dynamo Sandbox is that you can’t update this while Dynamo for Revit is open as it locks the DynamoSettings.xml file for editing, so bear that in mind if you run it. Here is a demo followed by the code…

 import clr
 import sys
 pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
 sys.path.append(pyt_path)
 import System
 import os
 import xml.etree.ElementTree as ET
 
 ############### Definitions ###############
 #Ensure a list object...
 def tolist(obj1):
     if hasattr(obj1,"__iter__"): return obj1
     else: return [obj1]
 
 ################# Inputs ##################
 # The Directories where the packages reside... 
 dirs = tolist(IN[0])
 # The Dynamo Version (we are checking if the input is given)...
 ver = "XX"
 if IN[1]:
     ver = tolist(IN[1])[0]

 ############### Main Script ###############
 # Get AppData/Roaming folder create path to Dynamo Revit folder where the DynamoSettings.xml lives...
 appData = os.getenv('APPDATA')
 dir = os.path.join(appData,"Dynamo\Dynamo Revit",ver)
 fp = None
 if os.path.exists(dir):
     fp = os.path.join(dir,"DynamoSettings.xml")
     if os.path.exists(fp):        
         try:
             # Parse .xml file...
             tree = ET.parse(fp)
             # Get root of tree...
             r = tree.getroot()
             # Get Child Element where tag is equal to CustomPackageFolders...
             for c in r:
                 if c.tag == "CustomPackageFolders":
                     # Clear all the SubElements in this Child Element...
                     c.clear()
                     # Write the new directories to the Child Element...
                     for dir in dirs:
                         # Check if path really is valid...
                         if os.path.exists(dir):
                             # Create a new Tree Element which is a string and a Sub Element of the Child Element...
                             subElem = ET.Element("string")
                             # Set the Sub Elements text value as the directory path...
                             subElem.text = dir
                             # and append this Sub Element to the Child Element...
                             c.append(subElem)
                     # Write all changes back to the DynamoSettings.xml file...
                     tree.write(fp)
             OUT = "Custom Package Folders updated"
         # If something went wrong...
         except Excpetion, e:
             OUT = "Could not set Custom Package Folders:- \n" + e.message
     # If no DynamoSettings.xml file exists...
     else:
         OUT = "Could not locate DynamoSettings.xml"
 # If the version of Dynamo Given was not valid...
 else:
     OUT = "Could not find the directory with that version of Dynamo"

 

This is a little hacky the way we have to modify the .xml directly, maybe there is another way, but I have no idea how this is done via directly through the Dynamo API yet (if at all), but this does the trick.

Note: It is always good practice when messing with any file like this that you make a backup just for peace of mind or you test in another location so you don’t do something by mistake.

FYI – You can also use this method to parse the Dynamo Nodes themselves. Here is a similar video if you are interested that I did a while back. You can even get the python code out of custom nodes just through the .dyf file if that floats your boat…

 

Anyway, I hope this might be of use to you or at least a food for thought article. 🙂

Advertisement