Posted on 27. March 2009

Load() that command please?–User settings Part 4

As I explained in part 3 if a command fails to run other than in the Revit executable directory, there is a good chance it’s because of the command assembly was loaded into the wrong binding context (LoadFrom() ) by Revit. In this part of the series I’m going to explain how we can fix this so you can place a command in any directory..

When an Appdomain tries to load an assembly it first looks in the GAC and the directory defined by it’s ApplicationBase property. Normally this is the directory of the executable and this is the case for Revit. You can also add subdirectories of the ApplicationBase directory, by setting the privateBinPath via the AppDomainSetup and the Domain manager will look there as well. Unfortunately this can’t be set once Revit has started so how do we make the Revit AppDomain load our command assemblies into the correct binding context?

I should also add, you may additionally require FullTrust if the command is loaded from a network path

Every AppDomain has by definition one configuration file. In our case this will be Revit.exe.config which resides in the Revit executable directory .In Revit 2009 you need to create this yourself, in the executable directory. In Revit 2010 it is already created because Autodesk are configuring a CAS setting for the CLR. You’ll see from the documentation on the configuration schema and in particular the runtime schema that there are 2 solutions that allow us to ensure our commands are loaded correctly by the Revit AppDomain.

Probing Solution

Probing will add subdirectories to the PrivateBinPath, ensuring any command assembly in these subdirectories will be probed correctly and load in the Load() context . Paths can only be subdirectories of the Revit program path not full paths outside of the ApplicationBase directory.

  The advantage of this solution is it very easy to configure. It’s great for development, as long as you place the command assembly in a configured subdirectory the command will load into the correct binding context. The disadvantage is it won’t work if you want to place your command assembly on the network.

The following is an example Revit.exe.config file. In this example we’re defining 2 subdirectories to be added for probing. For a default XP installation the full paths to these directories would be :

  • C:\Program Files\Revit Architecture 2009\Program\Extensions
  • C:\Program Files\Revit Architecture 2009\Program\Extensions\Dev
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="Extensions\;Extensions\Dev;"/>
        </assemblyBinding>
    </runtime>
</configuration> 

Note all subdirectories need to be defined by separating paths with semi-colons (;)

CodeBase solution

This solution is the most exact but also requires the most configuration. You must provide the complete codebase for the assembly in question. This is most useful when you want to store command assemblies anywhere on the network. The assemblies full Identity must be included or this solution will not work. It is not enough to just provide the codebase. The full path and version of the assembly is provided and at a minimum the assembly's name. The following is an example Revit.exe.config:

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="MyCommand" />
                <codeBase version="1.0.0.0" href="FILE://C:/2009Commands/MyCommand.dll"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

Note the following:

  • The format of the href with the FILE prefix as per standard URI’s.
  • You must add an assembly binding entry for each command assembly you want to load.
  • If you version your assemblies then the version property of the binding must be updated accordingly.

For both solutions you must add these AppDomain configuration settings to the Revit.exe.config file not your commands app.config file.

So that’s how we can use any .NET assembly in our commands. Now we know how to do this I can complete the series by explaining how to implement a fully featured configuration solution in your commands.

Comments are closed