ExcelDna
ExcelDna copied to clipboard
Packaging WebView2 dlls
Hello,
I am struggling to properly package the webview2 dlls. In the ExcelDnaClient.dna config file, I have the following dlls added for webview2:
I have also confirmed by unpacking the .xll file that the dlls did make it in the xll file.
When I try to use the webview2. it throws "The path is not of a legal form." error message as shown below:
************** Exception Text ************** System.ArgumentException: The path is not of a legal form. at System.IO.Path.LegacyNormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths) at System.IO.Path.InternalGetDirectoryName(String path) at Microsoft.Web.WebView2.Core.CoreWebView2Environment.LoadWebView2LoaderDll() at Microsoft.Web.WebView2.Core.CoreWebView2Environment.<CreateAsync>d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at ExcelDnaClient.Utilities.Signin.<InitializeAsync>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
If I place the 3 mentioned webview2 dlls next to the xll file everything works as expected. Can someone please shed some light what might be going on?
Packed assemblies are loaded directly from memory, and not unpacked to an on-disk file first. That means the assembly does not have the normal location property that describes the file location. WebView2 might be trying to use the location as part of the probe for related libraries somehow. I'm not sure whether the WebView2 source is available, but it might be worth having a look.
As far as I can tell source code of webview 2 isn’t available. Do you have any other suggestions apart from just copying the dlls next to the xll file?
Accidentally got closed
Maybe figuring out and setting the loader path yourself can help: https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2environment.loaderdllfolderpath?view=webview2-dotnet-1.0.1245.22 from this discussion: https://github.com/MicrosoftEdge/WebView2Feedback/issues/2372
are you sure you need to include the assemblies?
We use WebView2 in our add-in. We follow the procedure @ https://github.com/MicrosoftEdge/WebView2Samples/tree/main/SampleApps/WV2DeploymentWiXBurnBundleSample to verify the user has WebView2 installed on the user's computer. I was expecting an infinite number of issues installing it but that has not been the case.
@andrewkittredge - that is very interesting. On my dev machine I do have webview2 runtime installed as shown below:
However, it doesn't work until I put the dlls in the same directory as the plugin. In your case are you saying you didn't include any webview2 dlls in the xll package?
We have the below in our .dna file
<Reference Path="Microsoft.Web.WebView2.Core.dll" Pack="true" />
<Reference Path="Microsoft.Web.WebView2.WinForms.dll" Pack="true" />
We have the below XML in the wxs file we use to build our bundle and the below c# in our application that runs before we render the webview2 control.
<!--
https://github.com/MicrosoftEdge/WebView2Samples/issues/62
-->
<Property Id="WVRTINSTALLED64BIT">
<RegistrySearch Id="WVRTInstalled"
Root="HKLM"
Key="SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"
Name="pv"
Type="raw"
Win64="no"/>
</Property>
<Property Id="WVRTINSTALLED32BIT">
<RegistrySearch Id="WVRTInstalled32Bit"
Root="HKLM"
Key="SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"
Name="pv"
Type="raw"
Win64="no"/>
</Property>
<CustomAction Id='DownloadAndInvokeBootstrapper'
Directory="AddIns"
Execute="deferred"
ExeCommand='powershell.exe -windowstyle hidden Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -OutFile "$env:TEMP\MicrosoftEdgeWebview2Setup.exe" ; & $env:TEMP\MicrosoftEdgeWebview2Setup.exe /install'
Return='check'/>
public static async void InitializeAsync(WebView2 webView21, Uri URI, HandlesMessage handleWebMessage = null)
{
string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string cacheFolder = Path.Combine(localAppData, "WindowsFormsWebView2");
LogDisplay.RecordLine($"Available Browser Version String is {CoreWebView2Environment.GetAvailableBrowserVersionString()}, cache folder is {cacheFolder}");
var environment = await CoreWebView2Environment.CreateAsync(null, cacheFolder);
LogDisplay.RecordLine($"CoreWebView2Environment is {environment}");
await webView21.EnsureCoreWebView2Async(environment);
LogDisplay.RecordLine($"Done ensuring CoreWebView2Environment");
}
Thanks for providing the detail.
Your C# code is same as what I have so there is no issue there. I am a bit surprised this is working for you without packaging any webview2 dlls in xll or supplying dlls next to xll file.
What's in your wxs xml is all about making sure runtime is installed so I would think that has nothing to do with what happens within excel dna and the how it uses the webview2.
I do see that in your InitializeAsync you are passing in the webView21. Would you happen to know if there is any specific property being set for it before it is passed into the InitializeAsync() function?
Sorry, I misspoke previously, we do bundle two dlls for WebView2.
We have the below in our .dna file
<Reference Path="Microsoft.Web.WebView2.Core.dll" Pack="true" />
<Reference Path="Microsoft.Web.WebView2.WinForms.dll" Pack="true" />
Yeh, I did have that as well. Sort of giving up on this and for now I plan on providing the two dlls next to xll file which is not ideal.
I created the most simplistic ExcelDna project, added webview2 and simply called it from the =HelloDna() function. In the dna config I have added both the dlls as below:
<Reference Path="Microsoft.Web.WebView2.Core.dll" Pack="true" /> <Reference Path="Microsoft.Web.WebView2.WinForms.dll" Pack="true" />
If I move the packed xll file outside of debug folder, I get the following error:
Placing the two dlls next to xll works as shown below:
If you have a few minutes to look at the project that will be very much appreciated.
I had to change how we load webview2.
Based on https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#files-to-ship-with-the-app I am now bundling the three architecture specific WebView2Loader.dll
in our .msi file.
Before we instantiate the WebView2 I run the below to point to the correct WebView2Loader.dll.
string dllPath = Path.Combine(Path.GetDirectoryName(ExcelDnaUtil.XllPath), "runtimes", $"win-{RuntimeInformation.ProcessArchitecture}", "native");
LogDisplay.RecordLine($"Setting Dll path to: {dllPath}");
CoreWebView2Environment.SetLoaderDllFolderPath(dllPath);
See further discussion of WebView2 and ExcelDNA @ https://github.com/MicrosoftEdge/WebView2Feedback/issues/767#issuecomment-1017840877.
If you want to have a single file XLL and don't want to have to ship the native DLLs separately, you should consider using Costura to embed the native libraries (and other .NET libraries) instead of ExcelDnaPack. We are packaging WebView2 and SQLite3 which both rely on platform-specific native libraries. It's working well for us.
@andrewkittredge - Thank you for looking into it further. It was exactly what I needed. I followed the conversation at MicrosoftEdge/WebView2Feedback/issues/767#issuecomment-1017840877 and ended up adding the "WebView2Loader.dll" as embedded resource. Before using the webview, I am extracting the dll to a temporary user directory and setting the CoreWebView2Environment.LoaderDllFolderPath to point to the directory. Seems to work well!