Close Revit from the API

By Augusto Goncalves

This is possible using SendMessage with WM_CLOSE parameter. There are two tricks here: first, DLLImport the method from user32.dll, second get Revit windows handle.

For the first, there is a good source of those methods at PInvike.NET website. For this case, we need the SendMessage header. For the second, there is a good post at The Builder Coder blog.

Finally, the code will look like:

[Transaction(TransactionMode.Manual)]

public class AdskCommand : IExternalCommand

{

  public Result Execute(

      ExternalCommandData commandData,

      ref string message,

      ElementSet elements)

  {

    // send the message to close

    SendMessage(RevitWndHandle,

      WM_CLOSE,

      IntPtr.Zero, IntPtr.Zero);

 

    return Result.Succeeded;

  }

 

  // the value for close

  static uint WM_CLOSE = 0x10;

 

  // Use P/Invoke to DLLImport

  [DllImport("user32.dll",

    CharSet = CharSet.Auto,

    SetLastError = false)]

  static extern IntPtr SendMessage(

    IntPtr hWnd, UInt32 Msg,

    IntPtr wParam, IntPtr lParam);

 

  // singleton to store Revit handle

  static IntPtr _hWndRevit = IntPtr.Zero;

 

  // get Revit handle

  private static IntPtr RevitWndHandle

  {

    get

    {

      if (_hWndRevit == IntPtr.Zero)

      {

        System.Diagnostics.Process[] processes

          = System.Diagnostics.Process.

          GetCurrentProcess();

 

        if (0 < processes.Length)

        {

          _hWndRevit = processes[0].MainWindowHandle;

        }

      }

      return _hWndRevit;

    }

  }

}


Comments

4 responses to “Close Revit from the API”

  1. Dear Augusto,
    since it is possible that there is more than one Revit running, it would be better if you use
    System.Diagnostics.Process.GetCurrentProcess()
    instead of System.Diagnostics.Process.GetProcessesByName(“Revit”)
    (as it has already pointed out in the comments section of the TBC posting you mentioned above)
    Best regards,
    Rudolf

  2. Hi Rufolf,
    That’s a good idea, thanks, will update the code.
    Regards,
    Augusto Goncalves

  3. System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow() from an addin will send WM_CLOSE to Revit’s main window. There may be cases where that fails but SendMessage() succeeds.

  4. Thanks for pointing it, that is also valid.
    For completeness, call Process.Kill may not call Save when the project was modified.

Leave a Reply

Discover more from Autodesk Developer Blog

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

Continue reading