I was recently asked by a client to have a look at embedding a WebView2 browser control into Revit’s Dockable Panel. Seems like a pretty straight forward request. I did a handful of Dockable Panels before so this was not something that I didn’t think was possible. WebView2 is basically a wrapper around Chromium web browser so technically similar to things like CEF Sharp or EO Web Browser. Let’s go over how to set up a Dockable Panel first, and then I will go into details of the WebView2 debacle.
First things first. When implementing a Dockable Browser we have to register it on startup of Revit Application. That’s best done in the OnStartup routine. I just wrap that functionality into a little utility like so:
Inside the CreateDockablePane() method we can add subscription methods if we want to subscribe to any events etc. Now, the actual implementation of the DockablePaneHelper looks like this:
Now the above class implements two interfaces IDockablePaneProvider, and IFrameworkElementCreator. What do we need these for?
- IFrameworkElementCreator is a method that will return a new Page object. Basically if we close Dockable Panel, or dispose of the Page that was meant to be shown in it, next time that we want to show our Dockable Panel, Revit will call this method to create a new instance of it.
- IDockablePaneProvider is a method that will return a new Dockable Panel settings. A subset of that is the IFrameworkElementCreator method and the Page object that it returns, while rest is just some general settings about where the Dockable Panel that is being created was meant to be shown etc.
Once we have these two instantiated, then we can basically show/hide our Dockable Panel. Now, the trick is to show a WebView2 browser control in it, and use that to navigate to our web app, or something else that we want to show.
The basic setup for our Page can look like this:
In order to have the Microsoft.Web.WebView2.Wpf class available we have to reference in a Nuget Package like so:
Once we have that setup we have to add a few code behind routines to properly setup the WebView2 temp folder etc. WebView2 needs a folder on the drive that it will store your settings in. Things that regular web browser does as well, when it remembers your browsing history, or your logins etc.
Couple of things to explain here. First off you need to create an “environment” for your WebView2 control. Like I have mentioned it’s a folder and a set of settings that the browser will use to initialize itself. You can for example allow SSO sign ins in your browser like I did above. Make sure that the userDataFolder is a location somewhere that your users will have access to. By default it will use the main process’ location so in this case it would be Revit’s Program Files location, and that’s usually restricted to only admin users. I also have implementation for NavigationCompleted event and OnUnloaded events. In the OnUnloaded event I make sure to dispose of the WebView2 control. NavigationCompleted event is just an example since it’s a one of the two Navigation related events that might be helpful. Anyways, this should do it.
Now, surprise, surprise, it actually won’t work. Well, it would work, and load the google page, but if you tried to change a view in Revit or close Revit, it would have caused it to crash. Why? My guess, is as good as anyone else’s, but as far as I was able to narrow it down, WebView2 has a conflict with older versions of CEF Sharp. Yes, CEF Sharp that I have mentioned before as one of the other wrappers around Chromium. Since both of these are wrappers around the same Chromium library, they are most likely referencing some of the same DLLs, some of them might be different versions, and this is likely causing a conflict. Yes, DLL hell in full swing.
I wasn’t the first one that saw WebView2 crashing when used in the same application with CEF Sharp (Revit uses that with P&ID plugin for example so it comes pre-loaded into Revit). I found some other users reporting that to Microsoft here: Link
What the above user found was the it seemed to work well, when CEF Sharp v83 was used with WebView2. Unfortunately Autodesk has been shipping v65 with Revit for the last 4 years I think. The latest Revit 2022 still has that v65 CEF Sharp, so no luck for us. Why can’t we ship our own CEF Sharp you ask? Well, this has been an issue with Revit for a while now or at least since Autodesk started shipping Revit with CEF Sharp. Ever since there was a specific version of CEF Sharp included with Revit, their recommendation and advice has been to not ship your own version or risk clashing with whatever they load into the context first. As far as I know, the response from the development community since then has been to basically align their version of CEF Sharp with whatever Autodesk shipped with. I don’t have a problem with that, but Autodesk stopped updating CEF Sharp a few years ago, and now we have a pickle. Let’s hope they do update one day, and we will be able to use WebView2 with Revit then…assuming it is a conflict with CEF Sharp that is stopping us now. I think it’s a very good guess though, so wait we must. Just don’t hold your breath.
You can still use WebView2 with Revit, just don’t embed it into a Dockable Panel. It seems to work fine with a pop-up Window control. Weird.
Ps. Special thanks to Deyan Nenov (Twitter: @didonenov) for responding to my questions on Twitter. I also referenced his answer here: Link, when I was attempting to sort out what was causing Revit to crash. From my conversations with Deyan, it seemed like he was able to use a combination of Revit’s ViewActivated and DocumentOpened events to disable and dispose WebView2 control, before Revit crashed. Basically his idea was that we close WebView2 before Revit opens a view and then reopen the WebView2 control once the view is opened/activated. That worked fine for me, but then launching Dynamo was crashing it again. It turned out that Dynamo is built on top of a different wrapper for Chromium, so that clashes with WebView2 as well. Deyan suggested disabling Dynamo, but it wasn’t a viable solution for me. Perhaps that would work for others. Anyways, thanks for taking the time to talk about these issues and sharing the code.
It’s so frustrating because DLL hell was solved by Microsoft, like 15 years ago, using strong naming, but Autodesk just doesn’t support it.
Personally I just use Electron, and built my whole client application their and just shuttle json data back and forth to a thin Revit wrapper over named pipes. Still the potential for dll conflicts with different versions of Newtonsoft.json, but thankfully it’s core api has stayed pretty stable and consistent.
Jason,
Yes, so the whole point of trying to integrate with WebView2 was that a client of mine was trying to get away from CEF Sharp. Because the one that ships with Revit is pretty old, it has security and performance issues as compared to newer releases. We thought we can get WebView2 integrated, to go around that. At the same time a requirement that we have is that we use a Dockable Panel, so Electron is not an issue. There is some kind of conflict between Revit/CEF/WebView2 when embedded in a Dockable Panel. It’s not happening when it’s launched from Revit in its own Window, but again, that’s not what my client’s spec called for. It is what it is. I am not very happy that Autodesk decided to release Revit 2022 yet again with an old version of CEF Sharp. It’s been a few years. It’s time to upgrade.
Cheers!
Hey Jason, that sounds pretty, very, extremely interesting indeed. I assume you are referring to https://www.electronjs.org? Would you be willing and able to put together a minimal Revit add-in and Electron UI demonstrating the basics of how your system works? I can imagine that might be of interest to a huge number of other Revit add-in developers as well. They just don’t know it, of course, unfortunately. Thank you!
Jeremy,
Sure, I agree that Jaroslav can post an example of how we can use Electron, but that’s not really solving the issue. The issue is that Revit crashes when we embed WebView2 into a Dockable Panel. If there is a solution to this, I would expect Autodesk to provide it, not to steer developers to a different platform/integration. Besides Electron is not a solution to my problem at all. I need a Dockable Panel, and I need to be able to embed WebView2 into it. At the moment it will crash without warning so it’s likely an unmanaged DLL issue and the only unmanaged DLLs that I can think of that are potentially in conflict with WebVIew2 are the ones that come with CEF Sharp. I hope that Autodesk developers can come up with a patch, and release it in the next version of Revit. That would be ideal. As always, thank you for your input.
Cheers!
Konrad,
Aha. Oh dear. Yes, now I hear you. I was previously not aware of the urgency of solving it this way and no other, and also that Jason’s approach is not useful for a dockable panel. Can you put together the above into a package with a minimal reproducible case that I can share with the development team to submit a development ticket for them to analyse? That is the first step to getting Autodesk to taking a look at the issue. Thank you!
Cheers, Jeremy.
Ahmad created a repo here: https://github.com/zahmadsaleem/revit-webview2-demo It has a WebView2 implementation for Dockable Panel that he commented out because it was crashing. He also has a case where that same WebView2 control is loaded into its own WPF Window, and that seems to work well.
Dear Konrad,
Thank you very much for your detailed report, motivation and sample material.
I logged the issue REVIT-180081 [WebView2 control cannot be used in in dockable panel] with our development team for this on your behalf as it requires further exploration and possibly a modification to our software. Please make a note of this number for future reference.
You are welcome to request an update on the status of this issue or to provide additional information on it at any time quoting this change request number.
This issue is important to me. What can I do to help?
This issue needs to be assessed by our engineering team and prioritised against all other outstanding change requests. Any information that you can provide to influence this assessment will help. Please provide the following where possible:
– Impact on your application and/or your development.
– The number of users affected.
– The potential revenue impact to you.
– The potential revenue impact to Autodesk.
– Realistic timescale over which a fix would help you.
– In the case of a request for a new feature or a feature enhancement, please also provide detailed Use cases for the workflows that this change would address.
This information is extremely important. Our engineering team have limited resources, and so must focus their efforts on the highest impact items. We do understand that this will cause you delays and affect your development planning, and we appreciate your cooperation and patience.
Best regards,
Jeremy
Hey guys,
did you find any solution to the problem or are there any ideas on how to solve it?
It looks like on zahmadsaleem’s GitHub the issue is also mentioned but is still not solved.
Best,
Sam
There is no solution. I would recommend not using WebView with Revit. It will likely take Autodesk another decade to address this so I would look to other solutions in the meantime.
Just an update – from my limited testing with Revit 2020 today, it appears that Autodesk may have fixed the issues with WebView2 and the view changing event. There is still a problem with document closing, but I was able to dispose of the WV2 control in the document closing event and it solved the issue.
Just thought some might be curious to know!