webview_csharp
webview_csharp copied to clipboard
Call to SharpWebview.Webview.Navigate fails on call to SingleOrDefault
When calling the Navigate
method at application startup, GetWebViewAppContainerSid
seems to find more than one AppContainer with a name matching microsoft.win32webviewhost_cw5n1h2txyewy
, resulting in this error (this stacktrace is from the example DesktopApp, but the same happens with my own app)
~\webview_csharp\examples\DesktopApp> dotnet run
Unhandled exception. System.InvalidOperationException: Sequence contains more than one matching element
at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at SharpWebview.Loopback.GetWebViewAppContainerSid() in ~\webview_csharp\src\SharpWebview\Loopback.cs:line 31
at SharpWebview.Loopback.IsWebViewLoopbackEnabled() in ~\webview_csharp\src\SharpWebview\Loopback.cs:line 21
at SharpWebview.Webview.CheckLoopbackException(String url) in ~\webview_csharp\src\SharpWebview\Webview.cs:line 260
at SharpWebview.Webview.Navigate(IWebviewContent webviewContent) in ~\webview_csharp\src\SharpWebview\Webview.cs:line 94
at DesktopApp.Program.Main(String[] args) in ~\webview_csharp\examples\DesktopApp\Program.cs:line 24
I have checked that I added the loopback exemption
> CheckNetIsolation.exe LoopbackExempt -s
List Loopback Exempted AppContainers
[1] -----------------------------------------------------------------
Name: AppContainer NOT FOUND
SID: S-1-15-2-490905099-2794809881-2632752266-3514030558-4166392763-3416490339-321513134
[2] -----------------------------------------------------------------
Name: microsoft.win32webviewhost_cw5n1h2txyewy
SID: S-1-15-2-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646
OK.
(I actually tried clearing and re-adding the exemption a couple of times to no avail, because apparently the exemption list can become corrupted)
This is on Windows 11 21H2, using .NET 6.0.8 (SDK 6.0.400), WebView2 Runtime 105.0.1343.27
I did some console.log debugging in my local clone to log out the properties of the multiple matching AppContainers, and saw this:
displayName: @{Microsoft.Win32WebViewHost_10.0.22000.1_neutral_neutral_cw5n1h2txyewy?ms-resource://Windows.Win32WebViewHost/resources/DisplayName}
appContainerName: Microsoft.Win32WebViewHost_cw5n1h2txyewy
packageFullName: Microsoft.Win32WebViewHost_10.0.22000.1_neutral_neutral_cw5n1h2txyewy
workingDirectory: C:\Windows\SystemApps\Microsoft.Win32WebViewHost_cw5n1h2txyewy\
appContainerSid: 1867581628288
description: @{Microsoft.Win32WebViewHost_10.0.22000.1_neutral_neutral_cw5n1h2txyewy?ms-resource://Windows.Win32WebViewHost/resources/Description}
displayName: @{Microsoft.Win32WebViewHost_10.0.19041.1_neutral_neutral_cw5n1h2txyewy?ms-resource://Windows.Win32WebViewHost/resources/DisplayName}
appContainerName: microsoft.win32webviewhost_cw5n1h2txyewy
packageFullName: Microsoft.Win32WebViewHost_10.0.19041.1_neutral_neutral_cw5n1h2txyewy
workingDirectory: C:\Windows\SystemApps\Microsoft.Win32WebViewHost_cw5n1h2txyewy\
appContainerSid: 1867581635808
description: @{Microsoft.Win32WebViewHost_10.0.19041.1_neutral_neutral_cw5n1h2txyewy?ms-resource://Windows.Win32WebViewHost/resources/Description}
Noticed one of the appContainerNames is all lowercase and the other is mixed case, I removed the ToLower
call when matching by name, and then the app appears to have run correctly. Then I changed the value of WebViewAppContainerName
to match the mixed case appContainerName, and it also worked.
I'm new to Webview so a lot of this is beyond me and certainly don't know this well enough for a PR, but hopefully that is helpful? I'll keep looking at it, and if I learn enough to actually contribute a meaningful fix I'll submit a PR.
Okay, this may be simpler to fix than I thought. It seems like the Loopback
class's only public method is there to check if the loopback is allowed before proceeding, if so I think the following would work (I'll submit a PR shortly)
public bool IsWebViewLoopbackEnabled()
{
- var webViewSid = GetWebViewAppContainerSid();
+ var webViewSids = GetWebViewAppContainerSids();
return GetAllAppContainerConfigs().Any(c =>
{
ConvertSidToStringSid(c.Sid, out var currentSid);
- return currentSid == webViewSid;
+ return webViewSids.Any(webViewSid => currentSid == webViewSid);
});
}
- private string GetWebViewAppContainerSid()
+ private IEnumerable<string> GetWebViewAppContainerSids()
{
- var webviewAppContainer = GetAllAppContainers()
- .SingleOrDefault(a => a.appContainerName.ToLower() == WebViewAppContainerName);
- ConvertSidToStringSid(webviewAppContainer.appContainerSid, out var webViewSid);
- return webViewSid;
+ return GetAllAppContainers()
+ .Where(a => a.appContainerName.ToLower() == WebViewAppContainerName)
+ .Select(firewallAppContainer => {
+ ConvertSidToStringSid(firewallAppContainer.appContainerSid, out var webViewSid);
+ return webViewSid;
+ });
}