Skip to content

Commit

Permalink
DYN-5208-DynamoRevit-Crash-Fix (#13245)
Browse files Browse the repository at this point in the history
* Squashed commit of the following:

commit c81f3fe
Merge: 98ff9c0 7240196
Author: t-tellro <[email protected]>
Date:   Thu Aug 25 12:46:28 2022 -0500

    Merge branch 'master' into DYN-5106-WebView2-DocumentationBrowser

commit 98ff9c0
Author: t-tellro <[email protected]>
Date:   Thu Aug 25 12:32:33 2022 -0500

    DYN-5106-WebView2-DocumentationBrowser

    DocumentationBrowser was crashing in Dynamo for Revit due that WebView2 was trying to create the cache folder in the path "C:\Program Files\Autodesk\Revit 2023\AddIns\DynamoForRevit" due to permissions so in this fix I'm changing the folder to use the AppData for Revit "C:\Users\roberto.tellez\AppData\Roaming\Dynamo\Dynamo Revit\2.16".
    The same medicin was applied for the WebView2 used in Guided Tours, when using the ResourceUtilities.LoadWebBrowser() method it will using the cache folder passed as parameter.

commit 715626f
Merge: 979f0fc 3491e96
Author: t-tellro <[email protected]>
Date:   Tue Aug 16 13:12:47 2022 -0500

    Merge branch 'master' into DYN-5106-WebView2-DocumentationBrowser

commit 979f0fc
Author: t-tellro <[email protected]>
Date:   Mon Aug 15 22:46:10 2022 -0500

    DYN-5106-WebView2-DocumentationBrowser Code Review

    Fixing CanCreateNodeDocumenationHtmlFromNodeAnnotationEventArgsWithPackageNodeWithAddtionalDocumentation test due that it was using and old format of the html <img> tab, then I updated the image to use the virtual folder and http.

commit 284eb7a
Merge: ab4326d b95ef11
Author: Roberto T <[email protected]>
Date:   Mon Aug 15 13:48:44 2022 -0500

    Merge branch 'master' into DYN-5106-WebView2-DocumentationBrowser

commit ab4326d
Merge: dc993a0 fc26f34
Author: t-tellro <[email protected]>
Date:   Mon Aug 15 13:43:15 2022 -0500

    Merge branch 'DYN-5106-WebView2-DocumentationBrowser' of https://github.com/RobertGlobant20/Dynamo into DYN-5106-WebView2-DocumentationBrowser

commit dc993a0
Author: t-tellro <[email protected]>
Date:   Mon Aug 15 13:42:26 2022 -0500

    DYN-5106-WebView2-DocumentationBrowser Code Review

    - changing the visibility for the property FallbackDirectoryName
    - renaming coreDir by docsDir

commit fc26f34
Merge: b0526ab 933f16c
Author: Aaron (Qilong) <[email protected]>
Date:   Mon Aug 15 10:00:24 2022 -0700

    Merge branch 'master' into DYN-5106-WebView2-DocumentationBrowser

commit b0526ab
Author: t-tellro <[email protected]>
Date:   Fri Aug 12 18:52:22 2022 -0500

    DYN-5106-WebView2-DocumentationBrowser Code Review

    Due that the fallback_doc directory path can change depending if Dynamo is executed as Sandbox or if is over Revit then the path can be different so I added a code that will create the virtual directory depending of the correct fallback_doc directory path.
    Also I modified the Md2Html class so now it will be inserting in the image source (<img src) the prefix "http://appassets" so it can be loaded from a virtual directory created by the DocumentationBrowser.

commit 417069a
Merge: 0c12dff bef463e
Author: t-tellro <[email protected]>
Date:   Thu Aug 11 18:11:39 2022 -0500

    Merge branch 'master' into DYN-5106-WebView2-DocumentationBrowser

commit 0c12dff
Author: t-tellro <[email protected]>
Date:   Thu Aug 11 18:01:50 2022 -0500

    DYN-5106-WebView2-DocumentationBrowser

    I replaced the WebBrowser component by WebView2 in the file DocumentationBrowserView.xaml, also I added some functions for initializing WebView2,
    The method ShouldAllowNavigation was modified due that WebView2 doesn't have the Navigating event and also the event handler receive different parameters then modified the function to implement the same behavior than the previous one.
    Also I noticed that WebView2 CORS was blocking to load the jpg images that are shown for several nodes, then I had to create a mapped virtual directory in this way the html will be able to load the images and show them in the web page.
    Finally I removed a tag in all the html that was making the web page compatible for IE based browsers (due that now we are using WebView2 a Chromium based browser).

* DYN-5208-DynamoRevit-Crash-Fix

Removing comment.

* DYN-5208-DynamoRevit-Crash-Fix

Updating comment

* DYN-5208-DynamoRevit-Crash-Fix Code Review

Fix that will create the WebView2 cache folder always in the AppData path.
e.g.
Revit
C:\Users\roberto.tellez\AppData\Roaming\Dynamo\Dynamo Revit\2.16

Sandbox
C:\Users\roberto.tellez\AppData\Roaming\Dynamo\Dynamo Core\2.16

* DYN-5208-DynamoRevit-Crash-Fix Code Review 2

Fix that will set the WebView2.UserDataFolder only when the popup is using an html page.

* DYN-5208-DynamoRevit-Crash-Fix Code Review 2

Updating comment due that was specific to Revit.
  • Loading branch information
RobertGlobant20 authored Aug 29, 2022
1 parent df681c8 commit 2632111
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public partial class DocumentationBrowserView : UserControl, IDisposable
private const string VIRTUAL_FOLDER_MAPPING = "appassets";
static readonly string HTML_IMAGE_PATH_PREFIX = @"http://";

internal string WebBrowserUserDataFolder { get; set; }
internal string FallbackDirectoryName { get; set; }

/// <summary>
Expand Down Expand Up @@ -116,6 +117,15 @@ protected virtual void Dispose(bool disposing)

async void InitializeAsync()
{
if (!string.IsNullOrEmpty(WebBrowserUserDataFolder))
{
//This indicates in which location will be created the WebView2 cache folder
documentationBrowser.CreationProperties = new CoreWebView2CreationProperties()
{
UserDataFolder = WebBrowserUserDataFolder
};
}

//Initialize the CoreWebView2 component otherwise we can't navigate to a web page
await documentationBrowser.EnsureCoreWebView2Async();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class DocumentationBrowserViewExtension : ViewExtensionBase, IViewExtensi
private const string FALLBACK_DOC_DIRECTORY_NAME = "fallback_docs";
//these fields should only be directly set by tests.
internal DirectoryInfo fallbackDocPath;
internal DirectoryInfo webBrowserUserDataFolder;

internal DocumentationBrowserView BrowserView { get; private set; }
internal DocumentationBrowserViewModel ViewModel { get; private set; }
Expand Down Expand Up @@ -71,14 +72,29 @@ public override void Startup(ViewStartupParams viewStartupParams)

if (!string.IsNullOrEmpty(pathManager.HostApplicationDirectory))
{
var docsDir = new DirectoryInfo(Path.Combine(pathManager.HostApplicationDirectory, FALLBACK_DOC_DIRECTORY_NAME));
//when running over any host app like Revit, FormIt, Civil3D... the path to the fallback_docs can change.
//e.g. for Revit the variable HostApplicationDirectory = C:\Program Files\Autodesk\Revit 2023\AddIns\DynamoForRevit\Revit
//Then we need to remove the last folder from the path so we can find the fallback_docs directory.
var hostAppDirectory = Directory.GetParent(pathManager.HostApplicationDirectory).FullName;
var docsDir = new DirectoryInfo(Path.Combine(hostAppDirectory, FALLBACK_DOC_DIRECTORY_NAME));
fallbackDocPath = docsDir.Exists ? docsDir : null;
}

if(this.BrowserView != null)
//When executing Dynamo as Sandbox or inside any host like Revit, FormIt, Civil3D the WebView2 cache folder will be located in the AppData folder
var userDataDir = new DirectoryInfo(pathManager.UserDataDirectory);
webBrowserUserDataFolder = userDataDir.Exists ? userDataDir : null;

if (this.BrowserView == null) return;

if(fallbackDocPath != null)
{
this.BrowserView.FallbackDirectoryName = fallbackDocPath.FullName;
}

if(webBrowserUserDataFolder != null)
{
this.BrowserView.WebBrowserUserDataFolder = webBrowserUserDataFolder.FullName;
}
}

public override void Loaded(ViewLoadedParams viewLoadedParams)
Expand Down
16 changes: 16 additions & 0 deletions src/DynamoCoreWpf/UI/GuidedTour/GuidesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,17 @@ private Step CreateStep(Step jsonStepInfo, HostControlInfo hostControlInfo, int
var formattedText = Res.ResourceManager.GetString(jsonStepInfo.StepContent.FormattedText);
var title = Res.ResourceManager.GetString(jsonStepInfo.StepContent.Title);

DirectoryInfo userDataFolder = null;
if (dynamoViewModel != null)
{
var pathManager = dynamoViewModel.Model.PathManager;

//When executing Dynamo as Sandbox or inside any host like Revit, FormIt, Civil3D the WebView2 cache folder will be located in the AppData folder
var docsDir = new DirectoryInfo(pathManager.UserDataDirectory);
userDataFolder = docsDir.Exists ? docsDir : null;

}

switch (jsonStepInfo.StepType)
{
case Step.StepTypes.TOOLTIP:
Expand All @@ -446,6 +457,11 @@ private Step CreateStep(Step jsonStepInfo, HostControlInfo hostControlInfo, int
Title = title
}
};
var popupWindow = newStep.stepUIPopup as PopupWindow;
if(popupWindow != null && hostControlInfo.HtmlPage != null && !string.IsNullOrEmpty(hostControlInfo.HtmlPage.FileName))
{
popupWindow.WebBrowserUserDataFolder = userDataFolder != null ? userDataFolder.FullName : string.Empty;
}
break;
case Step.StepTypes.SURVEY:
newStep = new Survey(hostControlInfo, jsonStepInfo.Width, jsonStepInfo.Height)
Expand Down
14 changes: 13 additions & 1 deletion src/DynamoCoreWpf/Utilities/ResourceUtilities.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Dynamo.Logging;
using Dynamo.Wpf.Properties;
using Dynamo.Wpf.UI.GuidedTour;
using Dynamo.Wpf.Utilities;
using Microsoft.Web.WebView2.Wpf;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -330,12 +331,23 @@ internal static object ExecuteJSFunction(UIElement MainWindow, HostControlInfo p
/// <param name="resourcesPath">Path of the resources that will be loaded into the HTML page</param>
/// <param name="fontStylePath">Path to the Font Style that will be used in some part of the HTML page</param>
/// <param name="localAssembly">Local Assembly in which the resource will be loaded</param>
internal static async void LoadWebBrowser(HtmlPage htmlPage, WebView2 webBrowserComponent, string resourcesPath, string fontStylePath, Assembly localAssembly)
/// <param name="userDataFolder">the folder that WebView2 will use for storing cache info</param>
internal static async void LoadWebBrowser(HtmlPage htmlPage, WebView2 webBrowserComponent, string resourcesPath, string fontStylePath, Assembly localAssembly, string userDataFolder = default(string))
{
var bodyHtmlPage = ResourceUtilities.LoadContentFromResources(htmlPage.FileName, localAssembly, false, false);

bodyHtmlPage = LoadResouces(bodyHtmlPage, htmlPage.Resources, resourcesPath);
bodyHtmlPage = LoadResourceAndReplaceByKey(bodyHtmlPage, "#fontStyle", fontStylePath);

if (!string.IsNullOrEmpty(userDataFolder))
{
//This indicates in which location will be created the WebView2 cache folder
webBrowserComponent.CreationProperties = new CoreWebView2CreationProperties()
{
UserDataFolder = userDataFolder
};
}

await webBrowserComponent.EnsureCoreWebView2Async();
// Context menu disabled
webBrowserComponent.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
Expand Down
7 changes: 6 additions & 1 deletion src/DynamoCoreWpf/Views/GuidedTour/PopupWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public partial class PopupWindow : Popup
//Assembly path to the Resources folder
private const string resourcesPath = "Dynamo.Wpf.Views.GuidedTour.HtmlPages.Resources";

/// <summary>
/// This property will be hold the path of the WebView2 cache folder, the value will change based in if DynamoSandbox is executed or Dynamo is executed from a different host (like Revit, FormIt, Civil, etc).
/// </summary>
internal string WebBrowserUserDataFolder { get; set; }

public PopupWindow(PopupWindowViewModel viewModel, HostControlInfo hInfo)
{
InitializeComponent();
Expand Down Expand Up @@ -116,7 +121,7 @@ private async void InitWebView2Component()
contentGrid.Children.Add(webBrowserComponent);
Grid.SetRow(webBrowserComponent, 1);

ResourceUtilities.LoadWebBrowser(hostControlInfo.HtmlPage, webBrowserComponent, resourcesPath, mainFontStylePath, GetType().Assembly);
ResourceUtilities.LoadWebBrowser(hostControlInfo.HtmlPage, webBrowserComponent, resourcesPath, mainFontStylePath, GetType().Assembly, WebBrowserUserDataFolder);
}


Expand Down

0 comments on commit 2632111

Please sign in to comment.