Determine Revit Demo Mode

Here is yet another interesting example of an apparent gap in the Revit API that can be easily filled using a little workaround.

We have seen numerous examples of performing a certain operation within a temporary transaction that is then rolled back to cancel it, such as to determine gross

material quantities
for
an element with openings, a

host reference
and,
more generally, all

object relationships
.

Here is an example of using a related but different approach: the trick consists in attempting to perform a certain operation and gracefully handling a specific expected failure condition, in ths case a specific exception being thrown, to determine whether Revit is running in demo mode:

Question: Is it possible to determine whether Revit runs in demo mode?
I need this for two different reasons:

  • It is a licensing issue, since read-only viewing should not occupy a license.
  • Some add-in commands should be greyed out or hidden in the ribbon bar in demo mode.

Answer: You could try to save the model (after making a modification!) and then see if you get an InvalidLicenseException.

I implemented a little sample application TestDemoMode to test a simplified version of this idea.

Here is the test method I created:


  static bool IsDemoMode( Document doc )
  {
    Application app = doc.Application;
 
    try
    {
      Transaction tx = new Transaction( doc );
 
      tx.Start( "Modify Document" );
 
      SketchPlane sp
        = new FilteredElementCollector( doc )
          .OfClass( typeof( SketchPlane ) )
          .FirstElement() as SketchPlane;
 
      Line line = app.Create.NewLineBound(
        XYZ.Zero, XYZ.BasisX );
 
      ModelCurve mc = doc.Create.NewModelCurve(
        line, sp );
 
      tx.Commit();
 
      string filename = Path.GetTempFileName();
      File.Delete( filename );
 
      doc.SaveAs( filename );
      File.Delete( filename );
 
      tx.Start( "Unmodify Document" );
      doc.Delete( mc );
      tx.Commit();
 
      return false;
    }
    catch( InvalidLicenseException ex )
    {
      return true;
    }
  }

This is the external command Execute mainline code:


  public Result Execute(
    ExternalCommandData commandData,
    ref string message,
    ElementSet elements )
  {
    UIApplication uiapp = commandData.Application;
    UIDocument uidoc = uiapp.ActiveUIDocument;
    Document doc = uidoc.Document;
 
    bool rc = IsDemoMode( doc );
 
    string s = string.Format(
      "This is {0}a Revit demo version.",
      rc ? "" : "not " );
 
    TaskDialog.Show( "Test Demo Mode", s );
 
    return Result.Succeeded;
  }

I have not tested it for both cases, though, since I do not have a demo version handy.

I did run it in a non-demo version, which was correctly reported:

Not a demo version

I have also not added any checks to determine whether the write and save attempt may be failing due to the document being read-only, disk full, or anything like that.

A much better approach would be to create a new document from scratch and attempt to save that.

Anyway, here is
TestDemoMode.zip including
the source code, add-in manifest and full Visual Studio solution of the simplified test command.

A full-blown implementation requires a number of additional considerations and lots of testing, of course.
As said, the ‘1 new document’ – ‘2 edit document’ – ‘3 save as’ strategy might be best.
Hopefully all exceptions thrown during the first two steps will have to do with the licensing.
Step three is less certain, since for instance the hard drive may be full.

Saving the current document is a really bad idea and might take a long time, without even thinking about detaching from central and keeping work-shares.


Comments

13 responses to “Determine Revit Demo Mode”

  1. Hi Jeremy,
    as I recently pointed out, there are many Utils classes in the API.
    I haven’t tested whether you can export DWFs or DWGs in trial mode, but if this would be the case, you could use
    OptionalFunctionalityUtils.IsDWFExportAvailable() or
    OptionalFunctionalityUtils.IsDWGExportAvailable()
    to determine if you are in demo mode.
    Cheers,
    Rudolf

  2. If this is not the case, API Dev team may add something like
    OptionalFunctionalityUtils.IsInDemoMode()
    or
    OptionalFunctionalityUtils.IsTrialVersion()
    in the next release ;-)
    Bye,
    Rudolf

  3. Hi Jeremy,
    as far as I can see,
    you can export DWFs but not DWGs if you are in demo mode.
    Thus, the following line(s) could be used to determine if you are in viewer/demo/trial mode:
    bool isDemoMode = (!OptionalFunctionalityUtils.IsDWGExportAvailable());
    Cheers,
    Rudolf

  4. Dear Rudolf,
    This is an absolutely brilliant observation, sounds perfect.
    We just need someone to test it on a demo version.
    I can actually well imagine this method returning true in spite of a demo version being installed, because it might in fact have the required components available to create the DWG file, so the check returns true, and still have disabled the save functionality by other means that this method does not bother checking for.
    As soon as this is confirmed I think we should promote this information to a main blog post.
    Thank you!
    Cheers, Jeremy.

  5. Hi Jeremy,
    you are right, sadly.
    If I start Revit in Viewer Mode (starting Revit.exe -viewer), the result is as you foretold.
    ;-(
    But there is another way to avoid the try-to-save-workarounding.
    ;-)
    Remembering the status bar blog post, I suggest to get the title of the main window handle and check if it contains the words “VIEWER” and “MODE” (respectively “MODUS” in my German Revit).
    This would also work in a zero-document scenario.
    How to get the text:
    http://www.pinvoke.net/default.aspx/user32.getwindowtext
    This test may fail if the current document is named “VIEWER-MODE”, of course…
    Cheers,
    Rudolf

  6. Dear Rudolf,
    Why am I not surprised?
    And yes, the new suggestions sounds good to me.
    I can even tell you how to make it absolutely fool-proof, so that it can handle any kind of project name in the title:
    simply parse the title for the project name. I guess there may be situations where there is no project name, maybe a zero document state or something, so you may need to handle that case as well. Once you have found the document name, whatever it is, then remove it. After that, you can search for the strings you mention above.
    Thank you for the nice suggestion!
    Cheers, Jeremy.

  7. Hi Jeremy,
    ah, of course.
    Thanks for the hint.
    I like it if there is a lively discussion in the comments section ;-)
    Bye
    Rudolf

  8. Thanks for the solution, but I get a Revit encountered a System.IO.IOException: The process cannot access the file because it is being used by another process.
    so I tried this:
    try
    {
    doc.Save();
    return false;
    }
    catch (Autodesk.Revit.Exceptions.InvalidOperationException ex)
    {
    return true;
    }
    It works, excepts it saves the file which I would like to avoid.
    I thought also of trying export but it can take a long time for large files.
    Do you have any other suggestions? Thanks

  9. Dear Madmed,
    Yes, sure; Rudolf made several useful and even more effective suggestions in his comments above.
    Cheers, Jeremy.

  10. thanks, yes but I didnt succed to make it work.
    Can you post some example code (not necessarily working code) Just something to get me started. Thank you.

  11. Dear Madmed,
    Yes, sure, I would love to! I’ll do that right away, as soon as I have some time…
    Don’t hold your breath!
    Cheers, Jeremy.

  12. done:
    [DllImport(“user32.dll”, CharSet = CharSet.Auto, SetLastError = true)]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    [DllImport(“user32.dll”, SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetWindowTextLength(IntPtr hWnd);
    public static StringBuilder GetStatusText(IntPtr mainWindow)
    {
    StringBuilder s = new StringBuilder();
    if (mainWindow != IntPtr.Zero)
    {
    int length = GetWindowTextLength(mainWindow);
    StringBuilder sb = new StringBuilder(length + 1);
    GetWindowText(mainWindow, sb, sb.Capacity);
    sb.Replace(“Autodesk Revit Architecture 2013 – “, “”);
    return sb;
    }
    return s;
    }
    To check if we have a demo version:
    IntPtr revitHandle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
    StringBuilder sb = GetStatusText(revitHandle);
    bool isDemo = sb.ToString()[0] != ‘[‘

  13. Dear Madmed,
    Thank you for your implementation. I took this opportunity to add the code as a new command to The Building Coder samples, and also update the source code comments for 2013:
    http://thebuildingcoder.typepad.com/blog/2013/01/determine-revit-demo-mode-revisited.html
    Please also note Rudolf’s new comment on that post.
    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