Skip to content

Commit

Permalink
Move ShlwApi method
Browse files Browse the repository at this point in the history
  • Loading branch information
emako committed Dec 15, 2024
1 parent aa53627 commit 822b22d
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright © 2024 Frank Becker
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace QuickLook.Plugin.HtmlViewer.NativeMethods;

internal static class ShlwApi
{
public static string GetAssociatedAppForScheme(string scheme)
{
try
{
// Try to get friendly app name first
uint pcchOut = 0;
AssocQueryString(AssocF.None, AssocStr.FriendlyAppName, scheme, null, null, ref pcchOut);

if (pcchOut > 0)
{
var pszOut = new StringBuilder((int)pcchOut);
AssocQueryString(AssocF.None, AssocStr.FriendlyAppName, scheme, null, pszOut, ref pcchOut);

var appName = pszOut.ToString().Trim();
if (!string.IsNullOrEmpty(appName))
return appName;
}

// Fall back to executable name if friendly name is not available
pcchOut = 0;
AssocQueryString(AssocF.None, AssocStr.Executable, scheme, null, null, ref pcchOut);

if (pcchOut > 0)
{
var pszOut = new StringBuilder((int)pcchOut);
AssocQueryString(AssocF.None, AssocStr.Executable, scheme, null, pszOut, ref pcchOut);

var exeName = pszOut.ToString().Trim();
if (!string.IsNullOrEmpty(exeName))
return Path.GetFileName(exeName);
}

return null;
}
catch (Exception ex)
{
Debug.WriteLine($"Failed to get associated app: {ex.Message}");
return null;
}
}

[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern uint AssocQueryString(
AssocF flags,
AssocStr str,
string pszAssoc,
string pszExtra,
[Out] StringBuilder pszOut,
ref uint pcchOut
);

[Flags]
public enum AssocF
{
None = 0,
VerifyExists = 0x1
}

public enum AssocStr
{
Command = 1,
Executable = 2,
FriendlyAppName = 4
}
}
73 changes: 2 additions & 71 deletions QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/WebpagePanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using QuickLook.Common.Helpers;
using QuickLook.Plugin.HtmlViewer.NativeMethods;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;

Expand Down Expand Up @@ -128,7 +127,7 @@ private void NavigationStarting_CancelNavigation(object sender, CoreWebView2Navi
}

// Ask user for unsafe schemes. Use dispatcher to avoid blocking thread.
string associatedApp = GetAssociatedAppForScheme(uri.Scheme);
string associatedApp = ShlwApi.GetAssociatedAppForScheme(uri.Scheme);
_ = Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
// TODO: translation
Expand Down Expand Up @@ -159,74 +158,6 @@ private void NavigationStarting_CancelNavigation(object sender, CoreWebView2Navi
}
}

#region Get Associated App For Scheme

[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern uint AssocQueryString(
AssocF flags,
AssocStr str,
string pszAssoc,
string pszExtra,
[Out] StringBuilder pszOut,
ref uint pcchOut);

[Flags]
private enum AssocF
{
None = 0,
VerifyExists = 0x1
}

private enum AssocStr
{
Command = 1,
Executable = 2,
FriendlyAppName = 4
}

private string GetAssociatedAppForScheme(string scheme)
{
try
{
// Try to get friendly app name first
uint pcchOut = 0;
AssocQueryString(AssocF.None, AssocStr.FriendlyAppName, scheme, null, null, ref pcchOut);

if (pcchOut > 0)
{
var pszOut = new StringBuilder((int)pcchOut);
AssocQueryString(AssocF.None, AssocStr.FriendlyAppName, scheme, null, pszOut, ref pcchOut);

var appName = pszOut.ToString().Trim();
if (!string.IsNullOrEmpty(appName))
return appName;
}

// Fall back to executable name if friendly name is not available
pcchOut = 0;
AssocQueryString(AssocF.None, AssocStr.Executable, scheme, null, null, ref pcchOut);

if (pcchOut > 0)
{
var pszOut = new StringBuilder((int)pcchOut);
AssocQueryString(AssocF.None, AssocStr.Executable, scheme, null, pszOut, ref pcchOut);

var exeName = pszOut.ToString().Trim();
if (!string.IsNullOrEmpty(exeName))
return Path.GetFileName(exeName);
}

return null;
}
catch (Exception ex)
{
Debug.WriteLine($"Failed to get associated app: {ex.Message}");
return null;
}
}

#endregion Get Associated App For Scheme

private void WebView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
_webView.DefaultBackgroundColor = Color.White; // Reset to white after page load to match expected default behavior
Expand Down

0 comments on commit 822b22d

Please sign in to comment.