Search code examples
xamlworkflow-foundation-4workflow-foundation

How can I get a list of variables and assignments / default values?


We have a collection of Microsoft Windows Workflows (.xaml files) that I need to go through and inventory the variables. The workflows are complicated with variables scoped at many levels so I can't simply open up the Workflow xaml and look at the Variables tab at the top level; I need to dig through each level, sequence, etc. to find all possible variable definitions.

Can I automate this process? Can Visual Studio aid in this process?

One solution, I could write some code to read the workflow file, look for variables, grab any default values, and check if the variable is assigned, thus overriding the default. Technically, this is possible from C#. But is this solution really necessary to get the information?


Solution

  • You can use a recursive function like this:

    List<Variable> Variables;
    
    private void GetVariables(DynamicActivity act)
    {
        Variables = new List<Variable>();
        InspectActivity(act);
    }
    
    private void InspectActivity(Activity root)
    {
        IEnumerator<Activity> activities = WorkflowInspectionServices.GetActivities(root).GetEnumerator();
    
        while (activities.MoveNext())
        {
            PropertyInfo propVars = activities.Current.GetType().GetProperties().FirstOrDefault(p => p.Name == "Variables" && p.PropertyType == typeof(Collection<Variable>));
    
            if (propVars != null)
            {
                try
                {
                    Collection<Variable> variables = (Collection<Variable>)propVars.GetValue(activities.Current, null);
    
                    variables.ToList().ForEach(v =>
                    {
                        Variables.Add(v);
                    });
                }
                catch
                {
    
                }
            }
    
            InspectActivity(activities.Current);
        }
    }
    

    And should be called like this:

    using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xamlData)))
    {
        XamlXmlReaderSettings readerSettings = new XamlXmlReaderSettings()
        {
            LocalAssembly = Assembly.GetExecutingAssembly()
        };
    
        var xamlReader = new XamlXmlReader(stream, readerSettings);
    
        Activity activity = ActivityXamlServices.Load(xamlReader);
    
        DynamicActivity root = activity as DynamicActivity;
        GetVariables(root);
    }
    

    Credit to: https://stackoverflow.com/a/11429284/593609