RevitAddInUtility

In a
comment on
the recent discussion of the

Revit 2011 product GUIDs
,
David Bartliff raised an interesting question on the new Revit add-in utility DLL which triggered some internal discussion as well.

Before addressing David’s question, however, let’s look at some background info on what this utility is about at all.

Revit Add-In Utility DLL

The Revit add-in utility DLL is a stand-alone .NET assembly which offers a dedicated API capable of reading, writing and modifying add-in manifest files.
It is intended for use from product installers and scripts.

The developer guide discusses it briefly in section 3.4.2 and provides two sample code snippets demonstrating ‘Creating and editing a manifest file’ and ‘Reading an existing manifest file’.

The classes defined by the add-in utility DLL with all their member methods and properties are documented in the help file RevitAddInUtility.chm in the SDK installation folder.
The SDK also provides two sample applications which demonstrate its use.

Before we can discuss them fully, there is yet another piece of new valuable Revit 2011 add-in management functionality which we need to mention:

The External Command Availability Interface IExternalCommandAvailability

This interface allows you control over whether or not an external command button may be pressed in a given Revit project or family context.
The IsCommandAvailable interface method passes the application and a set of categories matching the currently selected items in Revit to the implementation class.
The typical use would be to check the selected categories to see if they meet the criteria for your command to be run.
Other criteria could obviously also be added, so you can easily define an application that can only be used between ten thirty and eleven o’clock in the morning, or when the moon is full.
Here is an accessibility checking example from the developer guide section 3.2.2.5 which allows a command to be launched when there is no active selection, or when at least one wall is selected:


public class SampleAccessibilityCheck
  : IExternalCommandAvailability
{
  public bool IsCommandAvailable(
    UIApplication applicationData,
    CategorySet selectedCategories )
  {
    // Allow button click if there is 
    // no active selection
 
    if( selectedCategories.IsEmpty )
      return true;
 
    // Allow button click if there is 
    // at least one wall selected
 
    foreach( Category c in selectedCategories )
    {
      if( c.Id.IntegerValue
        == ( int ) BuiltInCategory.OST_Walls )
        return true;
    }
    return false;
  }
}

I just noticed that the same sample code is also included in the help file, by the way.

ExternalCommand2011 SDK Samples

As mentioned in the

product GUID post
,
the Revit 2011 SDK includes a new subfolder named ExternalCommand2011 containing the two applications ExternalComandRegistration and RevitAddInUtilitySample.
They demonstrate how to make efficient use of some of the new Revit add-in utility and external command registration functionality:

  • RevitAddInUtility: use the RevitAddInUtility DLL to create and edit an add-in manifest file, read existing data from it, and retrieve the installed Revit product information.
  • ExternalComandRegistration: new external command registration features:
    1. Visibility Mode: control the visibility of each external command based on the different product and document type.
    2. IAvailabilityClass: enable and disable each external command based on user selection or application information.
    3. Icon and tooltip: define icon and tooltip.
    4. Localisation: localise strings in the add-in manifest file.

RevitAddInUtility

Demonstrates how to write a new add-in manifest file, retrieve information from a given manifest file or an entire folder containing manifest files, and how to retrieve information on installed Revit products on the local system.
It displays the following dialogue with three buttons and a tree view to demonstrate various RevitAddInUtility functions:

RevitAddInUtility

It provides the following functionality:

  1. Create a new add-in manifest file with an external application and an external command in it.
  2. Retrieve external command and application information from the newly created add-in manifest and display them in the tree view.
  3. Retrieve information about installed Revit products and corresponding add-in manifest folders and display it in the tree view.

I assume that this sample is the application David is alluding to in his question below.

ExternalComandRegistration

Demonstrate user how to register external commands making use of the new features provided in Revit 2011, including:

  1. Provides a console application in which we create an add-in manifest which contains two external commands by RevitAddInUtility.
  2. Set ‘VisibilityMode’ node of these two external commands with different values to demonstrate how to visualize external command base on the document type or project type change. Set visibility mode of first command with ‘NotVisibleInStructure | NotVisibleWhenNoActiveDocument’, Set visibility mode of second command with ‘NotVisibleInMEP | NotVisibleInFamily’.
  3. Provides user an assembly with two classes which inherited from IAvailabilityClass interface:
  4. First class: return false from IsCommandAvailabilable(UIApplication^ app, CategorySet^ categories) when user selected a wall. Use CategorySet property to judge user’s selection.
  5. Second class: return false from IsCommandAvailabilable(UIApplication^ app, CategorySet^ categories) when current document is in 3D view.
  6. Set ‘AvailabilityClass’ node of these two external commands with class name provided in step 3.
  7. Provides resource files for both English and Chinese language. Including both picture and text string to demonstrate the localization, icon and tooltip.
  8. Set icon and tooltip image of these two external commands with images above, and set node as ‘English_USA’. And tell user how to change language to ‘Chinese_Simplified’ to display external command by Chinese.
  9. Provides an easy add-on application to bind with each external command.

Locating the RevitAddInUtility Assembly

In order to make use of the functionality provided by the RevitAddInUtility assembly, for instance in an installer, the application needs to first locate and load it.
Here is David’s
question on this:

Question: Will the actual release version of RevitAddInUtility.dll be added to the GAC – it is not for Beta 2.
We built the sample exe and put it on the desktop of a user’s PC and it failed to work properly because it could not find the utility DLL.
So we either have to locate the Revit program folder ourselves or use a local copy of the utility DLL – which seems to defeat the purpose somewhat.

Answer:

RevitAddinUtility.dll is a stand-alone tool and does not depend on any other Revit modules.
Revit application developers can freely include it in their installers.

Currently, this DLL is located in the product install folder.
The long-term plan is for it to be moved into the SDK.
The intention is to allow redistribution of the DLL with program installers, although there is no legal language about that in the Revit install or SDK at this point.

For ADN members, this information is also provided in the technical solution

TS87598
.

Maybe putting it in the GAC is a good alternate solution which might be feasible if it is indeed entirely managed and has no dependencies whatsoever on Revit DLLs.
Thank you for that suggestion!


Comments

13 responses to “RevitAddInUtility”

  1. After some further thought, one of our developers says that it sounds feasible to deploy the addin utility in GAC. It may still be better to copy it to the install package, since that can avoid problems in case Revit has not been installed at all on the target machine or the add-in utility is not found in the GAC. So you might want to check first whether it is in GAC and then run the local installer version otherwise.

  2. I am trying to create a single installer for both 32 bit and 64 bit but it seems that RevitAddInUtility.dll is compiled for x64 in the 64 bit install and x86 in the 32 bit install.
    Is there an Any CPU compilation?
    Or am I just missing something?

  3. Dear Joel,
    In general, since you are an ADN member, submitting an ADN DevHelp Online request is the safer way to go to obtain an answer, because my colleagues will see it as well as me. In addition, that automatically hooks up to our knowledgebase.
    I have asked the development team about this, and their response is that a request will need to be filed.
    So for the moment, I think you will have to live with the two separate versions for 32 and 64 bits.
    Cheers, Jeremy.

  4. Thanks Jeremy. I put in an ADN request.

  5. Dear Joel,
    Thank you very much for that. I handled your case and also pubished your and Rod’s workaround suggestions:
    http://thebuildingcoder.typepad.com/blog/2010/05/revitaddinutility-for-32-and-64-bit-systems.html
    Cheers, Jeremy.

  6. I just wanted to say that the new way to register an Add-In (via RevitAddinUtility) is simply awesome. So you understand why I say that having to cope with two versions (32 & 64 bit), having to copy the right dll or having to include it in my msi or having to resort to any other trick simply negates the above mentioned awesomeness.

  7. Dear Dan,
    Shall we agree on “mitigates”?
    There are already known effective work-arounds, and we are looking into a purer long-term solution:
    http://thebuildingcoder.typepad.com/blog/2010/05/revitaddinutility-for-32-and-64-bit-systems.html
    Cheers, Jeremy.

  8. Hi Jeremy,
    I agree with you, there are several effective workarounds – this is not the issue. I was so amazed when RevitAddInUtility got out that in my eyes the trouble of using workarounds looked very big (although it’s not); it’s like having a very very nice cake without the cherry on top. It’s so very easy to use (when developing) only that it’s not (when installing the product).
    I don’t want to offend anyone, on the contrary. I can’t wait for the long-term solution.
    By the way, I didn’t expected your answer. I want to use this opportunity to thank you for your posts, you got me out of my trouble several time.

  9. Dear Dan,
    Thank you for the clarification, and no offense taken, don’t worry.
    Yes, I am looking forward to the perfect long-term solution as well. I like the cherry on the top!
    Thank you for your appreciation!
    Cheers, Jeremy.

  10. Hector Diaz Avatar
    Hector Diaz

    Hi Jeremy, I put the following code in Visual Studio:
    Imports System
    Imports Autodesk.Revit.ApplicationServices
    Imports Autodesk.Revit.Attributes
    Imports Autodesk.Revit.DB
    Imports Autodesk.Revit.UI
    _
    _
    Public Class SampleAccessibilityCheck
    Implements IExternalCommandAvailability
    Public Function IsCommandAvailable(ByVal applicationData As UIApplication, ByVal selectedCategories As CategorySet) As Boolean Implements IExternalCommandAvailability.IsCommandAvailable
    ‘ Allow button click if there is no active selection
    If selectedCategories.IsEmpty Then
    Return True
    End If
    ‘ Allow button click if there is at least one wall selected
    For Each c As Category In selectedCategories
    If c.Id.IntegerValue = DirectCast(BuiltInCategory.OST_Walls, Integer) Then
    Return True
    End If
    Next
    Return False
    End Function
    End Class
    When I started-up Revit and ran the application it failed. This error appeared: ClassLibrary1.SampleAccessibilityCheck does not inherit IExternalCommand. Then I tried to write the code for the IExternalCommand with the Execute Method but the application didn’t work ¿Do you know what could I do to solve this problem?…Thks a lot Jeremy….Regards, Hector

  11. Dear Hector,
    It sounds to me as if you specified your SampleAccessibilityCheck class as an external command implementation class, in which case it would have to be derived from IExternalCommand and implement an Execute method, which it does not.
    Use of the IExternalCommandAvailability interface only makes sense in a call to one of the Revit API element selection methods such as the Selection.PickObject method. That method would normally be called from within an external command. Where is this command? That is what Revit is looking for and what is specified for loading in the add-in manifest.
    Cheers, Jeremy.

  12. Hi Jeremy,
    can I use RevitAddInUtility to find a Revit Server installation or it works only for Revit installations?
    Regards,
    Michele

  13. Dear Michele,
    1. no and 2. yes.
    Cheers, Jeremy.

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading