From 9c66eba82eef2249030a282da796c330a54e9a4a Mon Sep 17 00:00:00 2001 From: ema Date: Thu, 19 Mar 2026 02:06:57 +0800 Subject: [PATCH] Add plugin icon registration and include QLPlugin.ico --- QuickLook/App.xaml.cs | 9 +- .../Helpers/PluginIconRegistrationHelper.cs | 114 ++++++++++++++++++ QuickLook/QuickLook.csproj | 7 ++ README.md | 3 +- 4 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 QuickLook/Helpers/PluginIconRegistrationHelper.cs diff --git a/QuickLook/App.xaml.cs b/QuickLook/App.xaml.cs index 75570cd..bc6bbc9 100644 --- a/QuickLook/App.xaml.cs +++ b/QuickLook/App.xaml.cs @@ -235,6 +235,8 @@ public partial class App : Application MessageBoxPatcher.Initialize(); CheckUpdate(); + + CheckAndRegisterPluginIcon(); } protected virtual void OnSessionEnding(object sender, SessionEndingEventArgs e) @@ -317,7 +319,7 @@ public partial class App : Application // Invalid path, continue to show duplicate message } } - + // Second instance: duplicate MessageBox.Show(TranslationHelper.Get("APP_SECOND_TEXT"), TranslationHelper.Get("APP_SECOND"), MessageBoxButton.OK, MessageBoxImage.Information); @@ -337,6 +339,11 @@ public partial class App : Application SettingHelper.Set("LastUpdateTicks", DateTime.Now.Ticks); } + private void CheckAndRegisterPluginIcon() + { + _ = Task.Delay(3000).ContinueWith(_ => PluginIconRegistrationHelper.CheckAndRegisterPluginIcon()); + } + private void RunListener(StartupEventArgs e) { TrayIconManager.GetInstance(); diff --git a/QuickLook/Helpers/PluginIconRegistrationHelper.cs b/QuickLook/Helpers/PluginIconRegistrationHelper.cs new file mode 100644 index 0000000..e0cce5b --- /dev/null +++ b/QuickLook/Helpers/PluginIconRegistrationHelper.cs @@ -0,0 +1,114 @@ +// Copyright © 2017-2026 QL-Win Contributors +// +// 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 . + +using Microsoft.Win32; +using QuickLook.Common.Helpers; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Security.Principal; + +namespace QuickLook.Helpers; + +internal static class PluginIconRegistrationHelper +{ + internal static void CheckAndRegisterPluginIcon() + { + try + { + var isElevated = new WindowsPrincipal(WindowsIdentity.GetCurrent()) + .IsInRole(WindowsBuiltInRole.Administrator); + if (!isElevated) + return; + + var iconPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "QLPlugin.ico"); + if (!File.Exists(iconPath)) + return; + + bool changed = false; + + // Computer\HKEY_CLASSES_ROOT\.qlplugin + using (var key = Registry.ClassesRoot.CreateSubKey(".qlplugin", true)) + { + if (key != null) + { + if (key.GetValue(string.Empty) as string != "QuickLook.Plugin") + { + key.SetValue(string.Empty, "QuickLook.Plugin"); + changed = true; + } + + if (key.GetValue("PerceivedType") as string != "compressed") + { + key.SetValue("PerceivedType", "compressed"); + changed = true; + } + } + } + + // Computer\HKEY_CLASSES_ROOT\QuickLook.Plugin\DefaultIcon + using (var key = Registry.ClassesRoot.CreateSubKey(@"QuickLook.Plugin\DefaultIcon", true)) + { + var iconValue = $"{iconPath},0"; + if (key != null && key.GetValue("") as string != iconValue) + { + key.SetValue("", iconValue); + changed = true; + } + } + + // Computer\HKEY_CLASSES_ROOT\QuickLook.Plugin + using (var key = Registry.ClassesRoot.CreateSubKey("QuickLook.Plugin", true)) + { + const string fileTypeName = "QuickLook Plugin File"; + if (key != null && key.GetValue(string.Empty) as string != fileTypeName) + { + key.SetValue(string.Empty, fileTypeName); + changed = true; + } + } + + // Computer\HKEY_CLASSES_ROOT\QuickLook.Plugin\shell\open\command + using (var key = Registry.ClassesRoot.CreateSubKey(@"QuickLook.Plugin\shell\open\command", true)) + { + var commandValue = $"\"{App.AppFullPath}\" \"%1\""; + if (key != null && key.GetValue(string.Empty) as string != commandValue) + { + key.SetValue(string.Empty, commandValue); + changed = true; + } + } + + // Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.qlplugin + { + // It is left to the user to choose whether to restore the default option in the future + } + + if (changed) + { + SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero); // SHCNE_ASSOCCHANGED + } + } + catch (Exception ex) + { + ProcessHelper.WriteLog(ex.ToString()); + } + } + + [DllImport("shell32.dll", SetLastError = true)] + private static extern void SHChangeNotify(int wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); +} diff --git a/QuickLook/QuickLook.csproj b/QuickLook/QuickLook.csproj index 2c18ea3..9aaaee8 100644 --- a/QuickLook/QuickLook.csproj +++ b/QuickLook/QuickLook.csproj @@ -136,6 +136,13 @@ + + + QLPlugin.ico + PreserveNewest + + + {85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95} diff --git a/README.md b/README.md index 72cda7f..de9e90a 100644 --- a/README.md +++ b/README.md @@ -790,7 +790,8 @@ Interested in contributing? Check out our development resources: [@OiCkilL](https://twitter.com/OiCkilL) [@QubitsDev](https://twitter.com/qubitsdev) -[Donno](https://github.com/Donnnno) +[@Donno](https://github.com/Donnnno) +[@Shomnipotence](https://github.com/Shomnipotence) *Fluent UI & Icons*