diff --git a/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/CLSIDRegister.cs b/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/CLSIDRegister.cs
index 7b07792..5fc1ed3 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/CLSIDRegister.cs
+++ b/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/CLSIDRegister.cs
@@ -23,8 +23,10 @@ namespace QuickLook.Plugin.OfficeViewer;
internal static class CLSIDRegister
{
- public const string Office = "{84F66100-FF7C-4fb4-B0C0-02CD7FB668FE}";
- public const string Visio = "{279D6C9A-652E-4833-BEFC-312CA8887857}";
+ public const string MicrosoftWord = "{84F66100-FF7C-4fb4-B0C0-02CD7FB668FE}";
+ public const string MicrosoftExcel = "{00020827-0000-0000-C000-000000000046}";
+ public const string MicrosoftPowerPoint = "{65235197-874B-4A07-BDC5-E65EA825B718}";
+ public const string MicrosoftVisio = "{21E17C2F-AD3A-4b89-841F-09CFE02D16B7}";
public static string GetName(string clsid)
{
diff --git a/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/Plugin.cs b/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/Plugin.cs
index c7d7abf..918093a 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/Plugin.cs
+++ b/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/Plugin.cs
@@ -31,8 +31,8 @@ public class Plugin : IViewer
[
".doc", ".docx", ".docm",
".xls", ".xlsx", ".xlsm", ".xlsb",
- ".vsd", ".vsdx",
".ppt", ".pptx",
+ ".vsd", ".vsdx",
".odt", ".ods", ".odp"
];
@@ -52,12 +52,41 @@ public class Plugin : IViewer
if (!Extensions.Any(path.ToLower().EndsWith))
return false;
- var previewHandler = PreviewHandlerHost.GetPreviewHandlerGUID(path);
+ var previewHandler = ShellExRegister.GetPreviewHandlerGUID(Path.GetExtension(path));
if (previewHandler == Guid.Empty)
return false;
- if (!string.IsNullOrWhiteSpace(CLSIDRegister.GetName($"{{{previewHandler}}}")))
+ if (!string.IsNullOrWhiteSpace(CLSIDRegister.GetName(previewHandler.ToString("B"))))
+ {
return true;
+ }
+ else
+ {
+ // To restore the preview handler CLSID to MS Office
+ // if running with administrative privileges
+ if (ShellExRegister.IsRunAsAdmin())
+ {
+ var fileExtension = Path.GetExtension(path);
+ var fallbackHandler = fileExtension switch
+ {
+ ".doc" or ".docx" or ".docm" or ".odt" => CLSIDRegister.MicrosoftWord,
+ ".xls" or ".xlsx" or ".xlsm" or ".xlsb" or ".ods" => CLSIDRegister.MicrosoftExcel,
+ ".ppt" or ".pptx" or ".odp" => CLSIDRegister.MicrosoftPowerPoint,
+ ".vsd" or ".vsdx" => CLSIDRegister.MicrosoftVisio,
+ _ => null,
+ };
+
+ if (fallbackHandler == null)
+ return false;
+
+ if (!string.IsNullOrWhiteSpace(CLSIDRegister.GetName(fallbackHandler)))
+ {
+ // Admin requested
+ ShellExRegister.SetPreviewHandlerGUID(fileExtension, new Guid(fallbackHandler));
+ return true;
+ }
+ }
+ }
return false;
}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/PreviewHandlerHost.cs b/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/PreviewHandlerHost.cs
index 1e94495..a1d304d 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/PreviewHandlerHost.cs
+++ b/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/PreviewHandlerHost.cs
@@ -21,7 +21,6 @@ using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
-using Microsoft.Win32;
namespace QuickLook.Plugin.OfficeViewer;
@@ -70,34 +69,6 @@ public class PreviewHandlerHost : Control
base.Dispose(disposing);
}
- ///
- /// Returns the GUID of the preview handler associated with the specified file.
- ///
- ///
- ///
- public static Guid GetPreviewHandlerGUID(string filename)
- {
- // open the registry key corresponding to the file extension
- var ext = Registry.ClassesRoot.OpenSubKey(Path.GetExtension(filename));
- if (ext != null)
- {
- // open the key that indicates the GUID of the preview handler type
- var test = ext.OpenSubKey(@"shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
- if (test != null) return new Guid(Convert.ToString(test.GetValue(null)));
-
- // sometimes preview handlers are declared on key for the class
- var className = Convert.ToString(ext.GetValue(null));
- if (className != null)
- {
- test = Registry.ClassesRoot.OpenSubKey(
- className + @"\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
- if (test != null) return new Guid(Convert.ToString(test.GetValue(null)));
- }
- }
-
- return Guid.Empty;
- }
-
///
/// Resizes the hosted preview handler when this PreviewHandlerHost is resized.
///
@@ -123,7 +94,7 @@ public class PreviewHandlerHost : Control
return false;
// try to get GUID for the preview handler
- var guid = GetPreviewHandlerGUID(path);
+ var guid = ShellExRegister.GetPreviewHandlerGUID(Path.GetExtension(path));
if (guid == Guid.Empty)
return false;
diff --git a/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/ShellExRegister.cs b/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/ShellExRegister.cs
new file mode 100644
index 0000000..f5d1026
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.OfficeViewer/ShellExRegister.cs
@@ -0,0 +1,66 @@
+using Microsoft.Win32;
+using System;
+using System.IO;
+using System.Security.Principal;
+
+namespace QuickLook.Plugin.OfficeViewer;
+
+internal static class ShellExRegister
+{
+ ///
+ /// Returns the GUID of the preview handler associated with the specified file extension.
+ ///
+ ///
+ ///
+ public static Guid GetPreviewHandlerGUID(string fileExtension)
+ {
+ // open the registry key corresponding to the file extension
+ var ext = Registry.ClassesRoot.OpenSubKey(fileExtension);
+ if (ext != null)
+ {
+ // open the key that indicates the GUID of the preview handler type
+ // Such as `Computer\HKEY_CLASSES_ROOT\.docx\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}`
+ // Such as `Computer\HKEY_CLASSES_ROOT\.xlsx\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}`
+ var test = ext.OpenSubKey(@"shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
+ if (test != null) return new Guid(Convert.ToString(test.GetValue(null)));
+
+ // sometimes preview handlers are declared on key for the class
+ var className = Convert.ToString(ext.GetValue(null));
+ if (className != null)
+ {
+ // Such as `Computer\HKEY_CLASSES_ROOT\{CLASS_NAME}\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}`
+ test = Registry.ClassesRoot.OpenSubKey(
+ className + @"\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}");
+ if (test != null) return new Guid(Convert.ToString(test.GetValue(null)));
+ }
+ }
+
+ return Guid.Empty;
+ }
+
+ ///
+ /// Set the GUID of the preview handler associated with the specified file extension.
+ ///
+ ///
+ ///
+ public static void SetPreviewHandlerGUID(string fileExtension, Guid guid)
+ {
+ // open the registry key corresponding to the file extension
+ var ext = Registry.ClassesRoot.OpenSubKey(fileExtension);
+ if (ext != null)
+ {
+ // open the key that indicates the GUID of the preview handler type
+ // Such as `Computer\HKEY_CLASSES_ROOT\.docx\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}`
+ // Such as `Computer\HKEY_CLASSES_ROOT\.xlsx\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}`
+ var test = ext.OpenSubKey(@"shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}", true);
+ test?.SetValue(null, guid.ToString("B"));
+ }
+ }
+
+ public static bool IsRunAsAdmin()
+ {
+ using WindowsIdentity identity = WindowsIdentity.GetCurrent();
+ WindowsPrincipal principal = new(identity);
+ return principal.IsInRole(WindowsBuiltInRole.Administrator);
+ }
+}