Dismiss DialogBox with Python

Hi,

I am working on a pyRevit script for bulk upgrade of all files in a specified folder. As the script closes all worksets upon openings a central file, no pop up messages would appear in this case.

However, if the file encountered is not central, many Dialogs appear, blocking the script until the user specifies a value for the specific update. As I noticed all of the dialogs upon opening are usually of type ‘Dialog_Revit_DocWarnDialog’, I tried to specify a default value for all of them, which was 1001. However, sometimes the first button in the dialog is not the one we need to press, so I had to go deeper and specify a different value, depending on the dialog message.

I tried adding an object of type TaskDialogShowingEventArgs, so that I can get the event.Message(), like shown in this example: Auto dismiss task dialog - YouTube

As I am more of a C# guy, I am currently failing to translate this line in Python:

Here’s what I tried, but it doesn’t work:

I think figuring this out would solve my issue and it should be quite simple…

Here’s my code:

# !/usr/bin/env python
#  -*- coding: utf-8 -*- 

import os

from pyrevit import forms
from Autodesk.Revit.DB import * 
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Events import *


# define dialog actions
def on_dialog_open(sender, event):
    #taskDialEvent = TaskDialogShowingEventArgs(event)
    try:
        if event.DialogId == 'Dialog_Revit_DocWarnDialog':
            #event.OverrideResult(1001)
            #print(taskDialEvent.Message)
            print('DocWarn')
        else:
            print(event.DialogId)
            #print(taskDialEvent.Message)
    except Exception as e:
        print(e)


# select folder of files to be updated
directoryContents = []
filesFolder = forms.pick_folder(title = 'File Folder')

for element in os.listdir(filesFolder):
    if ".rvt" in (os.path.join(filesFolder, element)):
        directoryContents.append(os.path.join(filesFolder, element))


# define worksharing save as options
workSaveAsOptions = WorksharingSaveAsOptions()
workSaveAsOptions.SaveAsCentral = True
    
# define save as options for worksharing models
saveAsOptionsWorksharing = SaveAsOptions()
saveAsOptionsWorksharing.MaximumBackups = 10
saveAsOptionsWorksharing.OverwriteExistingFile = True
saveAsOptionsWorksharing.SetWorksharingOptions(workSaveAsOptions)
    
# define save as options for non - workshared models
saveAsOptions = SaveAsOptions()
saveAsOptions.MaximumBackups = 10
saveAsOptions.OverwriteExistingFile = True

# define relinquish options
relinquishOptions = RelinquishOptions(False)
relinquishOptions.StandardWorksets = True
relinquishOptions.ViewWorksets = True
relinquishOptions.FamilyWorksets = True
relinquishOptions.UserWorksets = True
relinquishOptions.CheckedOutElements = True

# define synchronize options
syncOptions = SynchronizeWithCentralOptions()
syncOptions.SetRelinquishOptions(relinquishOptions)
syncOptions.Compact = True
syncOptions.SaveLocalBefore = True
syncOptions.SaveLocalAfter = True

tOptions = TransactWithCentralOptions()


for revitModel in directoryContents:

    revitModelPath = ModelPathUtils.ConvertUserVisiblePathToModelPath(revitModel)
    
    # define open options so that Revit automatically closes all worksets and detaches the file as central upon opening
    openОptions = OpenOptions()
    openОptions.DetachFromCentralOption = DetachFromCentralOption.DetachAndPreserveWorksets
    openConfig = WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets)
    openОptions.SetOpenWorksetsConfiguration(openConfig)
    
    # call the application and subscribe to an event
    uiApp = UIApplication(__revit__.Application)
    uiApp.DialogBoxShowing += on_dialog_open

    # open Revit document
    revitDocument = __revit__.Application.OpenDocumentFile(revitModelPath, openОptions)
    
    # save and close Revit document
    if revitDocument.IsWorkshared:
        revitDocument.SaveAs(revitModel, saveAsOptionsWorksharing)
        revitDocument.SynchronizeWithCentral(tOptions, syncOptions)
    else:
        revitDocument.SaveAs(revitModel, saveAsOptions)
        
    # unsibscribe to an event
    uiApp.DialogBoxShowing -= on_dialog_open

    revitDocument.Close(True)

You will probably have better luck on pyrevit forums given this is a pyrevit question. Look into the errorswallower class in pyrevit as that might help deal with these.

Theres a good thread here with some tips/warnings about using the ifailureprocessor or derivative versions of it as well, read well:

1 Like

Thank you, Gavin.

I am trying to avoid using pyRevit classes and functions, but base my scripts on the RevitAPI entirely. In that sense, even though this script works under pyRevit, it doesn’t really use anything from it (actually one single thing - the form to pick up folders).

In that sense, I think it’s a general API question and I found my answer within the API, been just struggling to translate it into Python :slight_smile: ( if you ask anything Python related in the API forum, you usually get the answer to go ask in the dynamo forum instead :smiley: )

Pretty much everything available in pyrevit is actually written quite raw in its libraries if you go digging, but no worries! I’ve learnt a lot about the API by digging through lots of the py files and tools.

but why would you dig there when you have https://www.revitapidocs.com/ ?

Easier to see how it can be applied sometimes. I use both, but not everything in the api is very intuitive until you see it in a practical scenario I find.

Yeap, that’s true

1 Like

I think you were right, since no rescue is coming here, I will have to search in the pyRevit forum :slight_smile:

I tried using the ErrorSwallower() you are mentioning in the other post, but I am having some issues:

I just did my registration there, so I guess I will find some help

Instead of swallowing the error (usually a bad practice - they pop up for a reason after all) you might want to consider checking to see if the file is workshared. If so use the current method you’re working with, and if not use a different method (avoiding the workset issue and others) to process the file.

Start by extracting the basic file info from the document with this method: Extract Method. Then after you have the basic file info object get the worksharing status with this property: IsWorkshared Property.

As an added benefit while you’re working with the basic file info object you can get a bunch of other useful data, such as the file format (Revit release year), if all changes have been saved to the central (ensuring that no one has work locally saved but not synced before you upgrade), and what version the file is (how many times it’s been saved).

1 Like

Hi, the worksets issue is not a thing, the problem is with messages of this kind:

image

image

image

etc.

And they would still appear when following the workflow you are mentioning. Maybe you see in my code that I wanted to try overriding the pop up message result with 1001 in any case. However, this is not ok, as it means for example ‘delete rooms’ in certain cases. That’s why I think the method I need to use is the one mentioned above, in the youtube video.

I just can’t translate it in Python, so I have no choice but to try with the pyRevit method and see if it helps :slight_smile: if not, I will have to rewrite the script in C#, I just wanted to avoid having to do that

Hmmm… I find it odd that the worksharing status is what triggers these… perhaps a coincidence?

I do not believe that the various background open nodes trigger such issues. What happens if say you use the node in the Rhythm package?

1 Like

nope, the worksharing status does not have anything to do with these messages, that’s exactly what I was saying

Those warnings appear related to links either not loading that bound rooms and/or references being lost. Test carefully with error swallowing as i believe it may potentially use deletion options to bypass them sometimes.

2 Likes

yeap, I will definitely check if they are dismissed properly, but I see I might have to recreate it in C#, so that I can properly explore the error messages and the ‘correct’ answer to each. Another example of an error one might get upon opening:

image

Anyway, thx for your help and suggestions

2 Likes

For warnings DialogBox that appear at the end of transactions, you can implement an IFailuresPreprocessor interface (to be used with moderation)

https://forum.dynamobim.com/search?q=IFailuresPreprocessor

1 Like

I realised why you were asking that, it’s cause I mentioned they do not appear for central models :slight_smile: What I meant was when all worksets are closed upon opening the file, there is basically nothing that could go wrong. For instance, if all dimensions are in a closed workset, there is no way any of them would lose its reference, etc. At least, while testing, I couldn’t find a single workshared model, producing any of these errors with this workflow. But still, it doesn’t depend on the workshared status, but the fact the script is closing all worksets

Did you find a solution to get rid of those warning messages when running a script that opens documents?

This query has come up quite a few times now on threads. The failures processor mentioned by Cyril above is the only option offered in Revit to deal with this to my understanding.

If you’re trying to figure out how to implement it, I’d suggest looking at the pyRevit error swallower which packages it up very neatly. See bottom of this py file for how Ehsan makes it into a class:

2 Likes