Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression: DllNotFoundException: Unable to load DLL 'WebView2Loader.dll' #2372

Closed
ShaunLoganOracle opened this issue Apr 18, 2022 · 25 comments
Assignees
Labels
bug Something isn't working tracked We are tracking this work internally.

Comments

@ShaunLoganOracle
Copy link

ShaunLoganOracle commented Apr 18, 2022

Description
We started getting a failure to load WebView2Loader.dll when we upgraded the WV2 SDK from 1.0.902.49 to 1.0.1108.44. The DllNotFoundException comes when we call Microsoft.Web.WebView2.Core.CoreWebView2Environment.GetAvailableBrowserVersionString() - before doing anything else with WV2. The same solution and code works as expected with 1.0.902.49 but fails after upgrading to 1.0.1108.44 (with no other changes).

Stack

DllNotFoundException: Unable to load DLL 'WebView2Loader.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Source: Microsoft.Web.WebView2.Core
Stack: 
  at Microsoft.Web.WebView2.Core.CoreWebView2Environment.GetAvailableCoreWebView2BrowserVersionString(String browserExecutableFolder, String& versionInfo)
  at Microsoft.Web.WebView2.Core.CoreWebView2Environment.GetAvailableBrowserVersionString(String browserExecutableFolder

Version
SDK: 1.0.902.49 works, as do others < 1.0.1108.44, then 1.0.1108.44 fails, as do others up to latest stable (1.0.1185.39)
Runtime: Evergreen 100.0.1185.39
Framework: Excel VSTO add-ins (1 with Winforms, 1 with WPF)
OS: Win 10 Enterprise, 21H2 19044.1586

Repro Steps
Microsoft.Web.WebView2.Core.CoreWebView2Environment.GetAvailableBrowserVersionString()
Observed: get exception (Expected: no exception)

Additional context
We have several test machines where we do not see this issue, but have identified a couple of machines where it fails as described (and succeeds using the earlier SDK).
We have looked at issues #2046 and #1236 and while we have very similar symptoms, we do not have non-english and/or special characters like # in the path (we do have hyphen, as in runtimes\win-x86).
The add-in is compiled in VS2019 for Debug/Any CPU config.
The UserDataFolder is set to a folder under %localappdata%, and there are no other WV2 instances using that folder (although we have not gotten to the WV2 init code yet).

Questions
@champnic
Is there a way to get additional diagnostics about the details of the load failure? I tried fuslogvw but that did not seem to help (caveat: it was my first time using that tool).

AB#39143740

@ShaunLoganOracle ShaunLoganOracle added the bug Something isn't working label Apr 18, 2022
@LiangTheDev
Copy link
Member

The best way to debug this is to repro the issue with procmon running and capturing file system activities. The captured events should tell us where the code tries to find the dll.

@ShaunLoganOracle
Copy link
Author

Thanks! We'll try it and report back.

@ShaunLoganOracle
Copy link
Author

Thanks @LiangTheDev , it is clearer now where the loading logic is looking for the WebView2Loader.dll, and what behavior has changed between the working SDK (1.0.1072.54) and the non-working SDK (1.0.1108.44).

First a little background: since we're talking about a VSTO add-in running under Excel, there are two interesting folders for the add-in .DLLs and their dependencies:

  1. the "installed to" folder: this is where our installer puts the add-in; for example: %appdata%\OurCompany\OurProductName. This folder has the add-in .DLLs along with Microsoft.Web.WebView2.Core.dll (and either the associated WinForms or Wpf .dll as needed). In a debug build in VS2019, this folder is something like c:\OurAddin...\bin\Debug. Under the "installed to" folder, we ship the \runtimes\win-x86\native\ folder with the WebView2Loader.dll.
  2. The "run-from" folder: Since we are a VSTO add-in, some part of the integration between VSTO and Excel (the VSTOLoader?) copies the add-in .dlls to a cache under %localappdata%\assembly\dl3.

With that as background, here is what we observed using Process Monitor as the difference between the working and non-working cases:
Working:
After Microsoft.Web.WebView2.Core.dll is loaded (AFAICT, this is from the "run-from" folder), an attempt is made to read WebView2Loader.dll from the "installed to" folder (under the runtimes\win-x86\native\ subfolder). This succeeds.

Non-working:
After Microsoft.Web.WebView2.Core.dll is loaded (also from the "run-from" folder), an attempt is made to read WebView2Loader.dll from the "run-from" folder (under runtimes\win-x86\native\ subfolder). This fails with PATH NOT FOUND. Next, there are many attempts to read WebView2Loader.dll which all fail. None of these attempts use the "installed to" folder + \runtimes\win-x86\native subfolder as with the prior SDK.
For reference, the locations searched, unsuccessfully, include:
"run-from" folder\runtimes\win-x86\native
"run-from" folder
"installed-to" folder // root, does not include runtimes\win-x86\native\ subfolder
C:\program files (x86)\Microsoft Office\Office16
// various other system locations
%userprofile%\Documents
// all the locations from the PATH environment variable (as far as I can tell).

This is a breaking change for us, we are unable to upgrade to a new SDK until this is fixed.

Footnote: As reported, we don't see the issue (WebView2Loader not found) on all test machines. We discovered that the machines where this issue is reproducible do not have Microsoft/Office 365, instead they have a non-subscription installation of Office. On the MS/Office 365 machines, a version of WebView2Loader is found under C:\Program Files\Microsoft Office\root\Office16, so we're just lucking out that that .DLL is on the search path. This is not desirable, since we want to do all of our testing with a known SDK and with a known WebView2Loader.dll, and so don't want to use some other WebView2Loader.dll.

@LiangTheDev LiangTheDev added the tracked We are tracking this work internally. label Apr 19, 2022
@LK-Global
Copy link

Hello Shaun,
"After Microsoft.Web.WebView2.Core.dll is loaded (AFAICT, this is from the "run-from" folder)"
if the Procmon output is not sufficiently precise for locating the load location of the dotNet Assembly, you can use fusion logging to absolutely tell from where it was loaded. From looking at the load sequence in the Procmon output, I believe that one place that the native loader DLL will be looked for and loaded is the folder where the dotNet Assembly was loaded. If the bitness appropriate WebView2Loader.dll is there then the runtime will load as expected. You may need to change your installer code...

@LiangTheDev
Copy link
Member

While there might be workaround to put the loader dll at a place that we know it will be searched for from the procmon output. This seems to be a regression. I've opened internal tracking issue for this.

@AndyT-MS
Copy link

Hi @ShaunLoganOracle,

Thanks for all of the details and context that you provided, it's very helpful. I'm checking into this issue and I suspect that I've located the cause of the regression. Could you please help me verify by checking what typeof(CoreWebView2Environment).Assembly.CodeBase and typeof(CoreWebView2Environment).Assembly.Location return in your add-in (at the time you call GetAvailableBrowserVersionString) ? I suspect that CodeBase will return the "installed to" folder and Location will return the "run-from" folder.

@ShaunLoganOracle
Copy link
Author

Hi @AndyT-MS -
Yes, when I build and run from Visual Studio, I see CodeBase and Location as you suspected:
CodeBase = file:///<my-code-root>/<project-root>/bin/Debug/Microsoft.Web.WebView2.Core.DLL
Location = %UserProfile%\AppData\Local\assembly\dl3\CGRRV32B.0C1\6E3J63RV.QV8\20e36d59\003c9457_e419d801\Microsoft.Web.WebView2.Core.dll
I see these same paths for both the working (1.0.902.49) and non-working (1.0.1108.44) SDKs.

@champnic
Copy link
Member

champnic commented May 6, 2022

We have a fix for this issue currently in a pull request. Thanks!

@ShaunLoganOracle
Copy link
Author

@champnic I don't have visibility into the progress of this issue AB#39143740, but I am hoping that the fix will appear soon in an official release, since we are blocked from updating our WV2 SDK until then.

@ShaunLoganOracle
Copy link
Author

I just confirmed that the issue still exists using SDK 1.0.1245.22.

@champnic
Copy link
Member

@ShaunLoganOracle There's a new API for explicitly setting the loader path. Can you try using that in the meantime?
https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2environment.loaderdllfolderpath?view=webview2-dotnet-1.0.1245.22

Apologies the other fix has gotten bogged down and isn't available yet.

@ShaunLoganOracle
Copy link
Author

ShaunLoganOracle commented Jul 5, 2022

EDIT: if I set the LoaderDllFolderPath before invoking any SDK API (including CoreWebView2Environment.GetAvailableBrowserVersionString()), then indeed the .dll is loaded from that path (if it exists). The rest of this post no longer applies.

@champnic Thanks for the pointer to this new property. I have tried setting this static property early on and it does not appear to control which WebView2Loader.dll gets loaded (for me). Recall that my code runs as an an add-in inside of Excel. When I use Process Explorer and watch the Excel.exe process, I can trigger the WV2 initialization in my add-in and I see that WebView2Loader.dll gets loaded from C:\Program Files\Microsoft Office\root\Office16\WebView2Loader.dll , not the folder I have set into CoreWebView2Environment.LoaderDllFolderPath
Here's the initialization code:

      CoreWebView2EnvironmentOptions options = new CoreWebView2EnvironmentOptions ()
         {
            AdditionalBrowserArguments = GetBrowserArguments (),
            Language = <snip>,
            AllowSingleSignOnUsingOSPrimaryAccount = true,
         };
         const string browserExeFolder = null;
         string userDataFolder = <snip>; // a folder under %localappdata%

         if (TryGetWebView2LoaderFolder (out string newLoaderPath))
         {
            LogVerbose ("WebView2 environment loader path set to: {0}", newLoaderPath);
            CoreWebView2Environment.LoaderDllFolderPath = newLoaderPath;
         }
         CoreWebView2Environment webView2Environment = await CoreWebView2Environment.CreateAsync (browserExeFolder, userDataFolder, options);
         LogVerbose ("WebView2 browser version: {0}", webView2Environment.BrowserVersionString);
         await EnsureCoreWebView2Async (webView2Environment);
         LogVerbose ("CoreWebView2 initialized.");
         . . .

Here's how I compute the loader folder path for testing this new property, which points at the folder containing the WebView2Loader.dll that I package with my add-in:

       private static bool TryGetWebView2LoaderFolder (out string loaderFolder)
         {
         // TEMP code for testing only! undoubtedly there are better ways to do this
         loaderFolder = null;
         try
         {
            var assy = Assembly.GetExecutingAssembly ();
            var codeBase = assy.CodeBase; // something like: file:///{user profile directory}/AppData/Local/My Company/My Product Name/my-excellent-module.DLL
            var folder = codeBase.Substring (0, codeBase.LastIndexOf ('/')); // drops the filename portion
            var loaderFolderUri = new Uri (folder + @"/runtimes/win-x86/native");
            loaderFolder = loaderFolderUri.LocalPath; // converts to file system syntax: c:\...\runtimes\win-x86\native
            return true;
         }
         catch (Exception ex)
         {
            LogError (ex, "Unable to compute WebView2Loader folder");
            return false;
         }
      }

When running in the debugger from VS2019, I the folder path returned is something like:
C:\myproduct\source\my-excel-addin\bin\Debug\runtimes\win-x86\native
and there is definitely a WebView2Loader.dll there.

Is this the correct usage for this property?

@champnic
Copy link
Member

champnic commented Jul 5, 2022

Yes - in an add-in scenario it's possible for multiple WebView2Loader.dll's to get loaded. Has this caused a problem so far? In a non-add-in scenario, I would expect it to load from that one location.

The fix for the underlying issue in finding the correct path got checked in last week, but unfortunately just missed the cutoff for the prerelease SDK. It should be in the following one. Thanks!

@ShaunLoganOracle
Copy link
Author

it's possible for multiple WebView2Loader.dll's to get loaded. Has this caused a problem so far?

We are not sure, but ideally we'd be able to control which WebView2Loader.dll is used when we spin up a WebView2, in order to be confident that what we've tested before shipping is what the customer will see.

@ShaunLoganOracle
Copy link
Author

I kept looking at using the new LoaderDllFolderPath approach and discovered that earlier in my code path, prior to the init code shown above, I was calling CoreWebView2Environment.GetAvailableBrowserVersionString() - this call triggers the load of WebView2Loader.dll. So I was setting the static property too late - sorry for the false report.

However, after fixing that and setting CoreWebView2Environment.LoaderDllFolderPath = "C:\source\my-add-in\bin\Debug\runtimes\win-x86\native"; before getting the version, I am seeing an exception get thrown:

DllNotFoundException: Unable to load DLL 'C:\source\my-add-in\bin\Debug\runtimes\win-x86\native\WebView2Loader.dll' 
or one of its dependencies: %1 is not a valid Win32 application (0x800700C1)
Source: Microsoft.Web.WebView2.Core
Stack: 
   at Microsoft.Web.WebView2.Core.CoreWebView2Environment.LoadWebView2LoaderDll()
   at Microsoft.Web.WebView2.Core.CoreWebView2Environment.GetAvailableBrowserVersionString(String browserExecutableFolder)

My calling code passes null for browserExecutableFolder to GetAvailableBrowserVersionString()
This is using the WV2 SDK 1.0.1245.22 (and a VSTO/C# add-in running w/in Excel)
Any clues as to how to proceed further?
Shall I create a separate issue here in WebView2Feedback for this particular case?

@champnic
Copy link
Member

champnic commented Jul 6, 2022

I wonder if there's a bitness mismatch - is the process and your addin running as x86 or x64? The WebView2Loader.dll is architecture specific.

@ShaunLoganOracle
Copy link
Author

ShaunLoganOracle commented Jul 7, 2022

In this case, Excel/Office is 32-bit, and the add-in is built using the Any CPU platform/configuration.
EDIT: for this issue I encountered when testing CoreWebView2Environment.LoaderDllFolderPath I had a bit-ness mismatch. Thanks! Now back to seeing if it helps with the original issue...

@ShaunLoganOracle
Copy link
Author

from @champnic :

There's a new API for explicitly setting the loader path. Can you try using that in the meantime?
https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2environment.loaderdllfolderpath?view=webview2-dotnet-1.0.1245.22

Yes, I have (finally) confirmed on our test machines where we were encountering the regression, that using SDK 1.0.1245.22 and setting CoreWebView2Environment.LoaderDllFolderPath to our "install location" + "\runtimes\win-NNN\native" works as expected: the WebView2Loader.dll is loaded from the specified path. The test machines where we saw this issue both happened to be using Excel/Office 32-bit, so that is the only confirmation I have for the workaround.

@AlexDavisOracle
Copy link

The fix for the underlying issue in finding the correct path got checked in last week, but unfortunately just missed the cutoff for the prerelease SDK. It should be in the following one. Thanks!

When should we expect to see this fix in a non-prerelease SDK? An estimate will help us plan our next steps. Thanks!

@champnic
Copy link
Member

champnic commented Jul 8, 2022

It should be in prerelease SDK around early August, and release SDK around early September.

@ShaunLoganOracle
Copy link
Author

Confirmed the fix in SDK 1.0.1340-prerelease. Looking forward to getting it in the next stable SDK so we can upgrade and get all the fixes and features added since 1.0.902.49.

@VesterT
Copy link

VesterT commented Aug 15, 2022

@ShaunLoganOracle There's a new API for explicitly setting the loader path. Can you try using that in the meantime? https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2environment.loaderdllfolderpath?view=webview2-dotnet-1.0.1245.22

Apologies the other fix has gotten bogged down and isn't available yet.

Hello @champnic ...

I'm having the same problem than @ShaunLoganOracle. In my case is a Word VSTO add-ins (WPF).

I follow this thread and I try to solve the issue by using CoreWebView2Environment.LoaderDllFolderPath property...
The problem is that apparently that property was removed in the latest version of WebView2.
Is there any other way to tell the add-in the location of the WebView2Loader.dll ?

I only have this problem with some users (mostly users NOT using a subscription based Office).

@champnic
Copy link
Member

@champnic
Copy link
Member

Additionally, the fix for the underlying issue is now in 1.0.1340-prerelease SDK, and should be available in the following release SDK. Thanks!

@ahmed-salem-me
Copy link

@champnic Hi, I have the same issue happening plz check #2834
would appreciate any advise, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working tracked We are tracking this work internally.
Projects
None yet
Development

No branches or pull requests

8 participants