-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
[feat] Expose AddBrowserExtension for Windows #11259
Comments
You can use
|
I've spent some decent three hours trying to get this right 😂 Had to learn a bit about the Windows API and how it's used in Rust. I also got sidetracked by the whole COM thing. Anyway, here's the final code, in case anybody needs it: [target.'cfg(target_os = "windows")'.dependencies]
windows-core = "0.58.0"
webview2-com-sys = "0.33.0" use std::path::Path;
use tauri::webview::PlatformWebview;
/// Represents an Error that occurs when adding a browser extension
#[derive(Debug)]
pub enum Error {
Unsupported,
#[cfg(target_os = "windows")]
WindowsError(windows_core::Error),
}
/// Defines extensions for [PlatformWebview] to easily add extensions
/// to web-views
pub trait BrowserExtensionsExt {
fn add_extension<P: AsRef<Path>>(&self, extension_folder: P) -> Result<(), Error>;
}
impl BrowserExtensionsExt for PlatformWebview {
#[cfg(not(target_os = "windows"))]
fn add_extension<P: AsRef<Path>>(&self, extension_folder: P) -> Result<(), Error> {
Err(Error::Unsupported)
}
#[cfg(target_os = "windows")]
fn add_extension<P: AsRef<Path>>(&self, extension_folder: P) -> Result<(), Error> {
windows_webview::add_extension(self, extension_folder.as_ref()).map_err(|e| Error::WindowsError(e))
}
}
#[cfg(target_os = "windows")]
mod windows_webview {
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::path::Path;
use tauri::webview::PlatformWebview;
use webview2_com_sys::Microsoft::Web::WebView2::Win32::ICoreWebView2BrowserExtension;
use webview2_com_sys::Microsoft::Web::WebView2::Win32::ICoreWebView2ProfileAddBrowserExtensionCompletedHandler;
use webview2_com_sys::Microsoft::Web::WebView2::Win32::ICoreWebView2ProfileAddBrowserExtensionCompletedHandler_Impl;
use webview2_com_sys::Microsoft::Web::WebView2::Win32::{ICoreWebView2Profile7, ICoreWebView2_13};
use windows_core::{Interface, Result, PCWSTR};
use windows_core::{implement, HRESULT};
#[implement(ICoreWebView2ProfileAddBrowserExtensionCompletedHandler)]
pub struct AddBrowserExtensionCallback;
impl ICoreWebView2ProfileAddBrowserExtensionCompletedHandler_Impl for AddBrowserExtensionCallback_Impl {
#[allow(non_snake_case)]
fn Invoke(&self, error_code: HRESULT, _extension: Option<&ICoreWebView2BrowserExtension>) -> windows_core::Result<()> {
error_code.ok()
}
}
impl AddBrowserExtensionCallback {
pub fn new() -> Self {
Self
}
}
pub(crate) fn add_extension(webview: &PlatformWebview, path: &Path) -> Result<()> {
unsafe {
let web_view2 = webview.controller().CoreWebView2()?;
let profile = web_view2.cast::<ICoreWebView2_13>()?.Profile()?;
let profile: ICoreWebView2Profile7 = profile.cast()?;
add_extension_to_profile(profile, path.as_os_str())?;
}
Ok(())
}
fn add_extension_to_profile(profile: ICoreWebView2Profile7, extension_folder: &OsStr) -> Result<()> {
unsafe {
let str: Vec<u16> = extension_folder.encode_wide()
.chain(std::iter::once(0))
.collect();
let path_ptr = PCWSTR(str.as_ptr());
let handler = AddBrowserExtensionCallback::new();
let h = ICoreWebView2ProfileAddBrowserExtensionCompletedHandler::from(handler);
profile.AddBrowserExtension(path_ptr, Some(&h))?;
}
Ok(())
}
} Which can be used as follows: let window = tauri::WebviewWindowBuilder::new(...)
.title(website)
.browser_extensions_enabled(true)
.build().unwrap();
window.with_webview(|webview| {
let r = webview.add_extension(r#"<extension path here>"#);
if let Err(why) = r {
println!("Failed to add extension: {why:?}");
}
}).unwrap(); (Excuse my unwrap() use) |
Once tauri-apps/wry#1399 is merged (which contains my |
added in #11628 |
Describe the problem
I can see in #10909 that it is possible now to enable browser extensions on Windows. Unfortunately, we can hardly take advantage of this feature as you currently don't have any way to actually add extensions :P
Describe the solution you'd like
Add a function that invokes ICoreWebviewProfile7#AddBrowserExtension.
A possible approach is to add an
extensions
function inWebviewWindowBuilder
, as shown below:Since this is only possible on Windows, it could either:
The second approach is likely better, as it is consistent with Tauri's overall design and ensures forward compatibility in case other platforms allow extensions in the future.
Alternatives considered
Modifying the underlying Wry window. Looks like this is not possible.
Additional context
No response
The text was updated successfully, but these errors were encountered: