diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs
index 8eb1058c28..6e4fc59452 100644
--- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs
+++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs
@@ -16,7 +16,6 @@ using Microsoft.PowerToys.PreviewHandler.Svg.Utilities;
using Microsoft.PowerToys.Telemetry;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
-using PreviewHandlerCommon;
namespace Microsoft.PowerToys.PreviewHandler.Svg
{
@@ -38,7 +37,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
///
/// Name of the virtual host
///
- public const string VirtualHostName = "PowerToysLocalSvg";
+ private const string VirtualHostName = "PowerToysLocalSvg";
///
/// Gets the path of the current assembly.
@@ -46,7 +45,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
///
/// Source: https://stackoverflow.com/a/283917/14774889
///
- public static string AssemblyDirectory
+ private static string AssemblyDirectory
{
get
{
@@ -67,12 +66,20 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
///
private bool _infoBarAdded;
+ ///
+ /// Represent WebView2 user data folder path.
+ ///
+ private string _webView2UserDataFolder = System.Environment.GetEnvironmentVariable("USERPROFILE") +
+ "\\AppData\\LocalLow\\Microsoft\\PowerToys\\SvgPreview-Temp";
+
///
/// Start the preview on the Control.
///
/// Stream reference to access source file.
public override void DoPreview(T dataSource)
{
+ CleanupWebView2UserDataFolder();
+
string svgData = null;
bool blocked = false;
@@ -88,9 +95,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
blocked = SvgPreviewHandlerHelper.CheckBlockedElements(svgData);
}
-#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
-#pragma warning restore CA1031 // Do not catch general exception types
{
PreviewError(ex, dataSource);
return;
@@ -100,9 +105,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
{
svgData = SvgPreviewHandlerHelper.AddStyleSVG(svgData);
}
-#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
-#pragma warning restore CA1031 // Do not catch general exception types
{
PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewError { Message = ex.Message });
}
@@ -125,9 +128,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
base.DoPreview(dataSource);
PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewed());
}
-#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
-#pragma warning restore CA1031 // Do not catch general exception types
{
PreviewError(ex, dataSource);
}
@@ -169,8 +170,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
ConfiguredTaskAwaitable.ConfiguredTaskAwaiter
webView2EnvironmentAwaiter = CoreWebView2Environment
- .CreateAsync(userDataFolder: System.Environment.GetEnvironmentVariable("USERPROFILE") +
- "\\AppData\\LocalLow\\Microsoft\\PowerToys\\SvgPreview-Temp")
+ .CreateAsync(userDataFolder: _webView2UserDataFolder)
.ConfigureAwait(true).GetAwaiter();
webView2EnvironmentAwaiter.OnCompleted(() =>
{
@@ -183,10 +183,24 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
await _browser.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.addEventListener('contextmenu', window => {window.preventDefault();});");
_browser.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, AssemblyDirectory, CoreWebView2HostResourceAccessKind.Allow);
_browser.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
- _browser.NavigateToString(svgData);
+
+ // WebView2.NavigateToString() limitation
+ // See https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.navigatetostring?view=webview2-dotnet-1.0.864.35#remarks
+ // While testing the limit, it turned out it is ~1.5MB, so to be on a safe side we go for 1.5m bytes
+ if (svgData.Length > 1_500_000)
+ {
+ string filename = _webView2UserDataFolder + "\\" + Guid.NewGuid().ToString() + ".html";
+ File.WriteAllText(filename, svgData);
+ _browser.Source = new Uri(filename);
+ }
+ else
+ {
+ _browser.NavigateToString(svgData);
+ }
+
Controls.Add(_browser);
}
- catch (NullReferenceException)
+ catch (Exception)
{
}
});
@@ -224,5 +238,25 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
AddTextBoxControl(Properties.Resource.SvgNotPreviewedError);
base.DoPreview(dataSource);
}
+
+ ///
+ /// Cleanup the previously created tmp html files from svg files bigger than 2MB.
+ ///
+ private void CleanupWebView2UserDataFolder()
+ {
+ try
+ {
+ // Cleanup temp dir
+ var dir = new DirectoryInfo(_webView2UserDataFolder);
+
+ foreach (var file in dir.EnumerateFiles("*.html"))
+ {
+ file.Delete();
+ }
+ }
+ catch (Exception)
+ {
+ }
+ }
}
}
diff --git a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs
index 620cb8627b..b25e9ed4d8 100644
--- a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs
+++ b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs
@@ -49,7 +49,7 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
///
/// Name of the virtual host
///
- public const string VirtualHostName = "PowerToysLocalSvgThumbnail";
+ private const string VirtualHostName = "PowerToysLocalSvgThumbnail";
///
/// Gets the path of the current assembly.
@@ -57,7 +57,7 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
///
/// Source: https://stackoverflow.com/a/283917/14774889
///
- public static string AssemblyDirectory
+ private static string AssemblyDirectory
{
get
{
@@ -68,6 +68,12 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
}
}
+ ///
+ /// Represent WebView2 user data folder path.
+ ///
+ private string _webView2UserDataFolder = System.Environment.GetEnvironmentVariable("USERPROFILE") +
+ "\\AppData\\LocalLow\\Microsoft\\PowerToys\\SvgThumbnailPreview-Temp";
+
///
/// Render SVG using WebView2 control, capture the WebView2
/// preview and create Bitmap out of it.
@@ -76,6 +82,8 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
/// The maximum thumbnail size, in pixels.
public Bitmap GetThumbnail(string content, uint cx)
{
+ CleanupWebView2UserDataFolder();
+
if (cx == 0 || cx > MaxThumbnailSize || string.IsNullOrEmpty(content) || !content.Contains("svg"))
{
return null;
@@ -117,8 +125,7 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
ConfiguredTaskAwaitable.ConfiguredTaskAwaiter
webView2EnvironmentAwaiter = CoreWebView2Environment
- .CreateAsync(userDataFolder: System.Environment.GetEnvironmentVariable("USERPROFILE") +
- "\\AppData\\LocalLow\\Microsoft\\PowerToys\\SvgThumbnailPreview-Temp")
+ .CreateAsync(userDataFolder: _webView2UserDataFolder)
.ConfigureAwait(true).GetAwaiter();
webView2EnvironmentAwaiter.OnCompleted(async () =>
{
@@ -129,9 +136,22 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
await _browser.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.addEventListener('contextmenu', window => {window.preventDefault();});");
_browser.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, AssemblyDirectory, CoreWebView2HostResourceAccessKind.Allow);
_browser.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
- _browser.NavigateToString(wrappedContent);
+
+ // WebView2.NavigateToString() limitation
+ // See https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.navigatetostring?view=webview2-dotnet-1.0.864.35#remarks
+ // While testing the limit, it turned out it is ~1.5MB, so to be on a safe side we go for 1.5m bytes
+ if (wrappedContent.Length > 1_500_000)
+ {
+ string filename = _webView2UserDataFolder + "\\" + Guid.NewGuid().ToString() + ".html";
+ File.WriteAllText(filename, wrappedContent);
+ _browser.Source = new Uri(filename);
+ }
+ else
+ {
+ _browser.NavigateToString(wrappedContent);
+ }
}
- catch (NullReferenceException)
+ catch (Exception)
{
}
});
@@ -249,5 +269,25 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
{
GC.SuppressFinalize(this);
}
+
+ ///
+ /// Cleanup the previously created tmp html files from svg files bigger than 2MB.
+ ///
+ private void CleanupWebView2UserDataFolder()
+ {
+ try
+ {
+ // Cleanup temp dir
+ var dir = new DirectoryInfo(_webView2UserDataFolder);
+
+ foreach (var file in dir.EnumerateFiles("*.html"))
+ {
+ file.Delete();
+ }
+ }
+ catch (Exception)
+ {
+ }
+ }
}
}