Incus J 10 Posted March 24, 2023 TWebBrowser and TEdgeBrowser VCL components have a property named UserDataFolder/EdgeUserDataFolder which sets a folder for the Edge engine (WebView2) to write session data. TWebBrowser FMX component does not expose this property, and the component defaults to using the app executable folder to write session data. That default value is problematic because the Program Files folder where the app is installed to is not writable. So I need to set a different location. I know the UserDataFolder property is in there somewhere, so I'm hopeful that I can surface it somehow. But I'm having trouble navigating through the FMX.WebBrowser code since it branches and calls services depending on the platform and engine - FindDeclaration only gets me so far. How can I access and set the Edge UserDataFolder when using the FMX TWebBrowser component? Share this post Link to post
programmerdelphi2k 237 Posted March 24, 2023 (edited) did you see in "Winapi.EdgeUtils.pas"? you have "CreateCoreWebView2EnvironmentWithOptions" NOTE: after changing the UserDataFolder or BrowserExecutableFolder property, you must reinitialize the WebView2 by calling the ReinitializeWebView or ReinitializeWebViewWithNewBrowser method. Edited March 24, 2023 by programmerdelphi2k Share this post Link to post
Incus J 10 Posted March 24, 2023 (edited) That would make sense. So far I've navigated: TWinNativeWebBrowser.CreateHandle calls TWinNativeWebBrowser.CreateWebView which calls TWinNativeWebBrowser.InitializeWebView which calls CreateCoreWebView2EnvironmentWithOptions I've yet to find the bit where FMX.TWebBrowser calls TWinNativeWebBrowser.CreateHandle - but there must be a connection between those two somewhere. I've noticed there's a TEdgeBrowserHelper = class helper for TWinNativeWebBrowser which has: property UserDataFolder: string read GetUserDataFolder write SetUserDataFolder; ...that's the property I'm after I think. Now I need to figure out how to access that property from my FMX application, when all I have is my instance of FMX.TWebBrowser on a form. Could I do something like TMyWebBrowser=class(TWebBrowser) and then cast TMyWebBrowser(WebBrowser1) to get at its internals? Edited March 24, 2023 by Incus J Share this post Link to post
Incus J 10 Posted March 24, 2023 If I subclass FMX.TWebBrowser e.g. TWebBrowserPlus=class(TWebBrowser) can I surface and access Private member FWeb ? I thought perhaps I could simply redeclare FWeb like this: type TWebBrowserPlus=class(TWebBrowser) private FWeb: ICustomBrowser; //redeclare private ancestor field to surface it in my subclass...? ...but that doesn't seem to work. Share this post Link to post
programmerdelphi2k 237 Posted March 24, 2023 I think that not because all setup was already defined on WebView2, for that you'll need re-CALL it as above... Share this post Link to post
programmerdelphi2k 237 Posted March 24, 2023 see this Gibhub project https://stackoverflow.com/questions/64433920/avoid-userdatafolder-for-ms-edge-webview2 Share this post Link to post
programmerdelphi2k 237 Posted March 24, 2023 SHDocVw.TWebBrowser.EdgeUserDataFolder on Help: If SelectedEngine is EdgeOnly, or is EdgeIfAvailable and Edge is available, then the EdgeUserDataFolder property tells Edge (or, more accurately, the WebView2 runtime) in which folder to store user data (e.g. cookies, permissions and cached resources). This property defaults to a local app data folder (i.e. the folder in which the path is stored in the LOCALAPPDATA environment variable) called <executable_file_name>.WebView2. The property value can include embedded environment variables if needed (e.g. %LOCALAPPDATA%\MyEdgeCacheFolder). Note: Microsoft states "The app is responsible to clean up the associated user data folder when it is done." uses SHDocVw; // <--- procedure TForm1.Button1Click(Sender: TObject); var MyWebBrowser: TWebBrowser; begin ... MyWebBrowser.EdgeUserDataFolder := '.....'; end; Share this post Link to post
Incus J 10 Posted March 24, 2023 (edited) Quote This property defaults to a local app data folder Yes, with VCL TWebBrowser EdgeUserDataFolder defaults to a path beginning with %LOCALAPPDATA%...etc... and this can be customised. Unfortunately with FMX TWebBrowser the default seems to be the folder of the app executable instead. So I'm trying to find a way to surface and set the underlying UserDataFolder property (defined in TEdgeBrowserHelper) for an FMX TWebBrowser. That way I can: Set the FMX TWebBrowser engine to IEOnly at design time At runtime my app can set Edge UserDataFolder to my new desired (writable) path - and only then: Switch the engine to EdgeOnly so it will initialize WebView2 with my new path. Quote for that you'll need re-CALL it as above... I'm not sure how to (re-)call it. Note that as things initially stand it will not have been called successfully yet. Edited March 24, 2023 by Incus J Share this post Link to post
Yaroslav Brovin 30 Posted March 30, 2023 (edited) Hello, Just use FMX.WebBrowser.Win.TGlobalEdgeBrowserSettings.UserDataFolder. It's global settings for all instances of Edge browsers in FMX applications. Be sure, you do it before showing forms. /// <summary>Global settings, which is applied for creating Edge browser instances.</summary> TGlobalEdgeBrowserSettings = class private class var FBrowserExecutableFolder: string; class var FUserDataFolder: string; public /// <summary> /// If set this specifies the location of msedgewebview2.exe, used with WebView2 Fixed Version Distribution mode: /// https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#fixed-version-distribution-mode /// If not set this defaults to looking for an installed version of the WebView2 runtime or alternatively an /// installation of Edge Canary. /// Note that setting this property affects the next creation of the underlying WebView2 control. If this /// component has already created a WebView2 control then setting this property will have no effect unless the /// WebView2 control gets recreated (e.g. by ReinitializeWebView or ReinitializeWebViewWithNewBrowser). /// If the path contains \Edge\Application\ then the WebView2 creation will fail. /// </summary> class property BrowserExecutableFolder: string read FBrowserExecutableFolder write FBrowserExecutableFolder; /// <summary> /// If set this specifies the location of the user data folder. /// If not set this defaults to the folder {your_exe_name}.WebView2 in the same folder as the executable. /// If folder creation permission is not available to the process where the user data folder needs to be created /// then the creation of the underlying WebView2 control can fail. /// The application will need to take responsibility for cleaning up the user data folder when it is no longer /// required. /// Note that setting this property affects the next creation of the underlying WebView2 control. If this /// component has already created a WebView2 control then setting this property will have no effect unless the /// WebView2 control gets recreated (e.g. by ReinitializeWebView or ReinitializeWebViewWithNewBrowser). /// </summary> class property UserDataFolder: string read FUserDataFolder write FUserDataFolder; end; Edited March 30, 2023 by Yaroslav Brovin 1 Share this post Link to post
Incus J 10 Posted March 31, 2023 A global setting sounds promising. FMX.WebBrowser.Win.TGlobalEdgeBrowserSettings.UserDataFolder:='(my path)'; That's giving me an error of Undeclared identifier TGlobalEdgeBrowserSettings at the moment. That class doesn't seem to be present in the FMX.WebBrowser.Win unit. I'll have a look around for it elsewhere - maybe it's moved in 11.3? Share this post Link to post