Introduction
Installation
Guides
- Engine
- Profile
- Browser
- BrowserView
- Navigation
- Content
- Context menu
- DOM
- JavaScript
- Pop-ups
- Dialogs
- Downloads
- Chrome extensions
- Network
- Cache
- Cookies
- Proxy
- Authentication
- Permissions
- Plugins
- Printing
- Passwords
- User data profiles
- Credit cards
- Media
- Zoom
- Spell checker
- Deployment
- Chromium
Troubleshooting
- Logging
- Common exceptions
- Application does not terminate
- Video does not play
- Cannot sign in to Google account
- User data is not stored
- Color scheme
- Startup failure
- Slow startup on Windows
- Unresponsive .NET Application
- Unexpected Chromium process termination
- Unexpected behavior
- Windows 7/8/8.1 end of support
Migration
Common Exceptions
This guide describes the common exceptions that can be thrown when working with the DotNetBrowser library.
Initialization exceptions
License exceptions
These exceptions are thrown when the license check fails for some reason.
NoLicenseException
is thrown when the license is missing. It usually happens when no license key is set in theEngineOptions
, and DotNetBrowser cannot locate adotnetbrowser.license
file containing the license key. To troubleshoot this case, check if the license is added to the project.InvalidLicenseException
is thrown when the license is configured properly, but the license check fails. The exact reason of the license check failure is provided as the exception message. For instance, this exception can be thrown when the license is expired, or the product binding in the license does not match any of the namespaces.
For example, one of the possible InvalidLicenseException
messages: DotNetBrowser license check failed. Reason: This product version is incompatible with the license.
It means that the license key specified in the project is incompatible with the referenced DotNetBrowser version. You need to make sure that the correct and valid key is used.
Otherwise, feel free to contact our Sales team at sales@teamdev.com to get the updated license.
Chromium binaries exceptions
The ChromiumBinariesMissingException
is thrown when DotNetBrowser cannot launch the bound Chromium engine because the Chromium binaries are missing and cannot be restored. The actual reason of the exception is provided as the exception message. For instance, this exception can be thrown when no compatible Chromium binaries are found in the Chromium binaries directory, and DotNetBrowser cannot find an assembly containing the compatible binaries.
Failed to extract the Chromium binaries in the separate process
This exception is thrown when the Chromium binaries were found in the assembly, however, there was an issue with extracting them to the Chromium binaries directory.
In most cases, the binaries extraction from the DLL is performed via GZipCompress.exe
, a utility that is a part of DotNetBrowser. This utility may fail to extract the binaries for some reason. For example, if it is blocked by a third-party application (antivirus or firewall) or there is a lack of permissions for this operation. The following exception message is observed in this case: Failed to extract the Chromium binaries in the separate process. GZipCompress.exe has exited with code <exit_code>
.
When this exception occurs, the detailed output of the GZipCompress.exe
is written to DotNetBrowser logs. Examining the logs usually helps to understand the actual cause of the failure.
Other engine initialization exceptions
The EngineInitializationException
is thrown when something goes wrong during initializing the IEngine
instance.
User data directory is already in use
It is not allowed to create two or more IEngine
instances pointing to the same user data directory, even if those IEngine
instances are created in separate .NET processes. Such use case is not supported by Chromium itself and leads to unpredictable behavior and sudden crashes of the engine.
As a result, when such case is detected, the EngineInitializationException
is thrown with the following message:
The user data directory is already in use: <path>
There are a few possible solutions:
- Create multiple
IBrowser
instances using the sameIEngine
:IEngine engine = EngineFactory.Create(engineOptions); IBrowser browser1 = engine.CreateBrowser(); IBrowser browser2 = engine.CreateBrowser();
Dim engine As IEngine = EngineFactory.Create(engineOptions) Dim browser1 As IBrowser = engine.CreateBrowser() Dim browser2 As IBrowser = engine.CreateBrowser()
- Create separate
IEngine
instances using different user data directories:IEngine engine1 = EngineFactory.Create(new EngineOptions.Builder { UserDataDirectory = @"C:\Users\Me\DotNetBrowser1" }.Build()); IEngine engine2 = EngineFactory.Create(new EngineOptions.Builder { UserDataDirectory = @"C:\Users\Me\DotNetBrowser2" }.Build()); IBrowser browser1 = engine1.CreateBrowser(); IBrowser browser2 = engine2.CreateBrowser();
Dim engine1 As IEngine = EngineFactory.Create(New EngineOptions.Builder With { .UserDataDirectory = "C:\Users\Me\DotNetBrowser" }.Build()) Dim engine2 As IEngine = EngineFactory.Create(New EngineOptions.Builder With { .UserDataDirectory = "C:\Users\Me\DotNetBrowser" }.Build()) Dim browser1 As IBrowser = engine1.CreateBrowser() Dim browser2 As IBrowser = engine2.CreateBrowser()
Runtime exceptions
ObjectDisposedException
The ObjectDisposedException
is thrown when there is an attempt to use an object which is already disposed. For example, this exception is thrown when working with:
- some previously cached DOM element or JavaScript object after loading a different web page;
- some frame that does not exist anymore in the browser;
IEngine
instance, anyIBrowser
instances created by this engine, or any other objects related to those instances after theIEngine.Dispose()
is called;IEngine
instance, anyIBrowser
instances created by this engine, or any other objects related to those instances after the Chromium crash.
ConnectionClosedException
The ConnectionClosedException
is thrown when the connection to the Chromium engine appears to be closed. This exception is usually related to IEngine.Dispose()
method call or a Chromium crash.
Cross-thread operation not valid
When you try to modify UI on the DotNetBrowser event, you can see System.InvalidOperationException
with the following description: Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on.
.
DotNetBrowser fires its events through the separate threads and does not use the main UI thread for this purpose. To modify UI on the DotNetBrowser event, pass the execution to the main UI thread using Invoke
and BeginInvoke
in WinForms or Dispatcher.Invoke
and Dispatcher.BeginInvoke
in WPF. The Control.InvokeRequired
property in WinForms or the Dispatcher.CheckAccess()
call in WPF can be used to check if it is necessary to pass the execution.
The code samples below demonstrate how to get access to UI from another thread.
WinForms
browser.Navigation.FrameLoadFinished += (s, e) =>
{
if (e.Frame.IsMain)
{
if (InvokeRequired)
{
BeginInvoke(new Action(() =>
{
this.Title = e.Browser.Url;
}));
}
else
{
this.Title = e.Browser.Url;
}
}
};
browser.Navigation.LoadUrl("https://www.teamdev.com");
AddHandler browser.Navigation.FrameLoadFinished, Sub(s, e)
If e.Frame.IsMain Then
If InvokeRequired Then
BeginInvoke(New Action(Sub()
Me.Title = e.Browser.Url
End Sub))
Else
Me.Title = e.Browser.Url
End If
End If
End Sub
browser.Navigation.LoadUrl("https://www.teamdev.com")
WPF
browser.Navigation.FrameLoadFinished += (s, e) =>
{
if (e.Frame.IsMain)
{
if (!Dispatcher.CheckAccess())
{
Dispatcher.BeginInvoke(new Action(() =>
{
this.Title = e.Browser.Url;
}));
}
else
{
this.Title = e.Browser.Url;
}
}
};
browser.Navigation.LoadUrl("https://www.teamdev.com");
AddHandler browser.Navigation.FrameLoadFinished, Sub(s, e)
If e.Frame.IsMain Then
If Not Dispatcher.CheckAccess() Then
Dispatcher.BeginInvoke(New Action(Sub()
Me.Title = e.Browser.Url
End Sub))
Else
Me.Title = e.Browser.Url
End If
End If
End Sub
browser.Navigation.LoadUrl("https://www.teamdev.com")
Avalonia UI
browser.Navigation.FrameLoadFinished += (s, e) =>
{
if (e.Frame.IsMain)
{
if (!Dispatcher.UIThread.CheckAccess())
{
Dispatcher.UIThread.InvokeAsync(new Action(() =>
{
this.Title = e.Browser.Url;
}));
}
else
{
this.Title = e.Browser.Url;
}
}
};
browser.Navigation.LoadUrl("https://www.teamdev.com");
AddHandler browser.Navigation.FrameLoadFinished, Sub(s, e)
If e.Frame.IsMain Then
If Not Dispatcher.UIThread.CheckAccess() Then
Dispatcher.UIThread.InvokeAsync(New Action(Sub()
Me.Title = e.Browser.Url
End Sub))
Else
Me.Title = e.Browser.Url
End If
End If
End Sub
browser.Navigation.LoadUrl("https://www.teamdev.com")