Replacing Built-In Revit Commands and Their Ids

One main focus of the Revit 2013 API features is better support for add-in integration. This includes the possibility for an add-in to replace an existing Revit command with its own implementation. Note that you cannot call an existing command, just replace it entirely.

Such a command replacement is demonstrated in a very simple form by the DisableCommand SDK sample, which disables a command by replacing its implementation with a simple popup message.

A slightly more complex example is given by the UIAPI SDK sample, which implements and installs an alternative command binding for the Design Model command to start up a new family freshly created from the conceptual mass template and display its 3D view.

These are the steps to replace a built-in Revit command:

List of all Revit Command Ids

To simplify the first step, Victor Chekalin aka Виктор Чекалин now presents a list of all Revit command ids,

In Victor's own words:

I'm learning the ability to replace a Revit command with my own add-in implementation. To replace a command, I must know CommandId of the command which I want to replace. The help tells me I can find a CommandId in the journal file. So the Revit SDK help doesn't contains full list of CommandIds. I have decided to correct this mistake and create that list.

I thought this information will be useful for you and other developers and send you the list of all command ids in both text and Excel format.

Question: Wow! How did you create this list?

Answer: It is my little secret how I've got it. Joke :-)

At first I thought the commands must be described somewhere. I searched for the text 'ID_EXPORT_IFC' (the command name from the Dev Days Online – Revit 2013 API) in all files at the Revit Program folder. So I found the UIFramework.dll file. I opened this file in the text editor and saw XML data containing command descriptions.

Next steps were very easy. I saved this part of the UIFramework.dll file to the XML file and read the XML data:

private IEnumerable<InternalCommandDef> 
  ReadCommandsFromFile()
{
  using( var streamReader 
    = File.OpenText( @"C:\Users\ChekalinVV"
      + "\Documents\Revit\Revit2013SDK"
      + "\RevitUICommands.xml" ) )
  {
    using( var reader = XmlReader.Create( 
      streamReader ) )
    {
      while( reader.Read() )
      {
        if( reader.Name.Equals( "Command" ) )
        {
          InternalCommandDef commandDef 
            = new InternalCommandDef();
 
          if( reader.MoveToAttribute( "Path" ) )
            commandDef.Path = reader.Value;
 
          if( reader.MoveToAttribute( "CommandId" ) )
            commandDef.CommandId = reader.Value;
 
          yield return commandDef;
        }
      }
    }
  }
}

Retrieve get CommandId info for each command and write it to the text file:

  using( var textFile = File.CreateText( 
    @"C:\Users\ChekalinVV\Documents\Revit"
    + "\Revit2013SDK\RevitUICommands.txt" ) )
  {
    foreach( var command in commands )
    {
      RevitCommandId commandId = RevitCommandId
        .LookupCommandId( command.CommandId );
 
      if( commandId == null ) continue;
 
      command.CanHaveBinding 
        = commandId.CanHaveBinding;
 
      command.Id = commandId.Id;
 
      textFile.WriteLine( "{0}\t{1}\t{2}\t{3}",
          command.CommandId,
          command.Path,
          command.Id,
          command.CanHaveBinding );
 
      /* It is just a joke
 
      if( !commandId.HasBinding 
        && commandId.CanHaveBinding )
      {
        var commandBinding =
          App.ControlledApplication
            .CreateAddInCommandBinding(commandId);
 
        commandBinding.Executed += OnCommandExecute;
      }
      */
    }
  }
}

It is not necessary to get full CommandId properties, but I wanted to retrieve the CanHaveBinding property for all commands. As I can see only two commands cannot have binding: Undo and Redo commands. Although I try to bind ID_APP_EXIT command (just for test because it was the first command I found in the journal files). It binds without any errors but doesn't work.

Very many thanks to Victor for this interesting research and the useful comprehensive list!