From 328e7e569d8327bce20ec887d6d64b669cdfbcba Mon Sep 17 00:00:00 2001 From: Robin Krom Date: Sat, 23 Jan 2021 23:41:22 +0100 Subject: [PATCH 1/2] BUG-2693: This should fix an issue where Greenshot doesn't detect a MAPI client, we weren't looking at the 32 bit location. --- GreenshotPlugin/Core/EmailConfigHelper.cs | 50 +++++------------ GreenshotPlugin/Core/RegistryHelper.cs | 66 +++++++++++++++++++++++ 2 files changed, 80 insertions(+), 36 deletions(-) create mode 100644 GreenshotPlugin/Core/RegistryHelper.cs diff --git a/GreenshotPlugin/Core/EmailConfigHelper.cs b/GreenshotPlugin/Core/EmailConfigHelper.cs index 7da960b09..bbd816e96 100644 --- a/GreenshotPlugin/Core/EmailConfigHelper.cs +++ b/GreenshotPlugin/Core/EmailConfigHelper.cs @@ -1,6 +1,6 @@ /* * Greenshot - a free and open source screenshot tool - * Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom + * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom * * For more information see: http://getgreenshot.org/ * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot @@ -18,46 +18,25 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + using System.IO; -using Microsoft.Win32; namespace GreenshotPlugin.Core { /// /// Description of EmailConfigHelper. /// public static class EmailConfigHelper { - private const string OutlookPathKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\OUTLOOK.EXE"; - private const string MapiClientKey = @"SOFTWARE\Clients\Mail"; - private const string MapiLocationKey = @"SOFTWARE\Microsoft\Windows Messaging Subsystem"; - private const string MapiKey = @"MAPI"; - public static string GetMapiClient() { - using (RegistryKey key = Registry.CurrentUser.OpenSubKey(MapiClientKey, false)) { - if (key != null) { - return (string)key.GetValue(string.Empty); - } - } - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(MapiClientKey, false)) - { - return (string) key?.GetValue(string.Empty); - } - } - - public static bool HasMapi() - { - using RegistryKey key = Registry.LocalMachine.OpenSubKey(MapiLocationKey, false); - return key != null && "1".Equals(key.GetValue(MapiKey, "0")); - } + public static string GetMapiClient() => RegistryHelper.ReadLocalMachineSoftwareKey(@"Clients\Mail"); - public static string GetOutlookExePath() { - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(OutlookPathKey, false)) { - if (key != null) { - // "" is the default key, which should point to the outlook location - return (string)key.GetValue(string.Empty); - } - } - return null; + public static bool HasMapi() + { + var value = RegistryHelper.ReadLocalMachineSoftwareKey(@"Microsoft\Windows Messaging Subsystem", "MAPI", "0"); + return "1".Equals(value); + } + + public static string GetOutlookExePath() => RegistryHelper.ReadLocalMachineSoftwareKey(@"Microsoft\Windows\CurrentVersion\App Paths\OUTLOOK.EXE"); /// /// Check if Outlook is installed @@ -65,12 +44,11 @@ namespace GreenshotPlugin.Core { /// Returns true if outlook is installed public static bool HasOutlook() { string outlookPath = GetOutlookExePath(); - if (outlookPath != null) { - if (File.Exists(outlookPath)) { - return true; - } + if (outlookPath == null) + { + return false; } - return false; + return File.Exists(outlookPath); } } } diff --git a/GreenshotPlugin/Core/RegistryHelper.cs b/GreenshotPlugin/Core/RegistryHelper.cs new file mode 100644 index 000000000..e5f068ab4 --- /dev/null +++ b/GreenshotPlugin/Core/RegistryHelper.cs @@ -0,0 +1,66 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom + * + * For more information see: http://getgreenshot.org/ + * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot + * + * 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 1 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 System; +using Microsoft.Win32; + +namespace GreenshotPlugin.Core +{ + /// + /// A helper class for accessing the registry + /// + public static class RegistryHelper + { + /// + /// Retrieve a registry value + /// + /// string with the name of the key + /// string with the name of the value below the key, null will retrieve the default + /// string with the default value to return + /// string with the value + public static string ReadLocalMachineSoftwareKey(string keyName, string value = null, string defaultValue = null) + { + string result = null; + value ??= string.Empty; + if (Environment.Is64BitOperatingSystem) + { + using var key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\{keyName}", false); + + if (key != null) + { + result = (string)key.GetValue(value, defaultValue); + } + } + + if (string.IsNullOrEmpty(result)) + { + using var key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\wow6432node\{keyName}", false); + + if (key != null) + { + result = (string)key.GetValue(value, defaultValue); + } + } + + return result; + } + } +} From 2733c6cf2651e3d3fbe7e677762df3cc7bae2838 Mon Sep 17 00:00:00 2001 From: Robin Krom Date: Wed, 27 Jan 2021 23:50:22 +0100 Subject: [PATCH 2/2] Fixed an issue with the build, where MSBuild.Community.Tasks.Targets wasn't found. Also improved the registry reading for the MAPI control. --- Directory.Build.props | 9 ++++++--- Greenshot/Greenshot.csproj | 7 +++++++ Greenshot/Helpers/MailHelper.cs | 14 +++++++------- GreenshotJiraPlugin/GreenshotJiraPlugin.csproj | 4 ++-- GreenshotPlugin/Core/EmailConfigHelper.cs | 7 ++++--- ...{RegistryHelper.cs => RegistryKeyExtensions.cs} | 9 +++++---- GreenshotPlugin/GreenshotPlugin.csproj | 4 ++-- 7 files changed, 33 insertions(+), 21 deletions(-) rename GreenshotPlugin/Core/{RegistryHelper.cs => RegistryKeyExtensions.cs} (82%) diff --git a/Directory.Build.props b/Directory.Build.props index 520eb0976..ce53be91e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -102,11 +102,14 @@ - - + + + + $(userprofile)\.nuget\packages\msbuildtasks\1.5.0.235\tools\ + - + diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj index 9419fb179..630501ce8 100644 --- a/Greenshot/Greenshot.csproj +++ b/Greenshot/Greenshot.csproj @@ -46,6 +46,13 @@ Always + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/Greenshot/Helpers/MailHelper.cs b/Greenshot/Helpers/MailHelper.cs index d3daaf446..a78799eae 100644 --- a/Greenshot/Helpers/MailHelper.cs +++ b/Greenshot/Helpers/MailHelper.cs @@ -174,7 +174,7 @@ namespace Greenshot.Helpers { /// public void ShowDialog() { // Create the mail message in an STA thread - var thread = new Thread(_ShowMail) + var thread = new Thread(ShowMail) { IsBackground = true, Name = "Create MAPI mail" @@ -202,7 +202,7 @@ namespace Greenshot.Helpers { /// /// Sends the mail message. /// - private void _ShowMail() { + private void ShowMail() { var message = new MapiHelperInterop.MapiMessage(); using var interopRecipients = Recipients.GetInteropRepresentation(); @@ -215,7 +215,7 @@ namespace Greenshot.Helpers { // Check if we need to add attachments if (Files.Count > 0) { // Add attachments - message.Files = _AllocAttachments(out message.FileCount); + message.Files = AllocAttachments(out message.FileCount); } // Signal the creating thread (make the remaining code async) @@ -227,7 +227,7 @@ namespace Greenshot.Helpers { if (Files.Count > 0) { // Deallocate the files - _DeallocFiles(message); + DeallocFiles(message); } MAPI_CODES errorCode = (MAPI_CODES)Enum.ToObject(typeof(MAPI_CODES), error); @@ -245,14 +245,14 @@ namespace Greenshot.Helpers { return; } Recipients = new RecipientCollection(); - _ShowMail(); + ShowMail(); } /// /// Deallocates the files in a message. /// /// The message to deallocate the files from. - private void _DeallocFiles(MapiHelperInterop.MapiMessage message) { + private void DeallocFiles(MapiHelperInterop.MapiMessage message) { if (message.Files != IntPtr.Zero) { Type fileDescType = typeof(MapiFileDescriptor); int fsize = Marshal.SizeOf(fileDescType); @@ -274,7 +274,7 @@ namespace Greenshot.Helpers { /// /// /// - private IntPtr _AllocAttachments(out int fileCount) { + private IntPtr AllocAttachments(out int fileCount) { fileCount = 0; if (Files == null) { return IntPtr.Zero; diff --git a/GreenshotJiraPlugin/GreenshotJiraPlugin.csproj b/GreenshotJiraPlugin/GreenshotJiraPlugin.csproj index 2c4e72fe6..d37465111 100644 --- a/GreenshotJiraPlugin/GreenshotJiraPlugin.csproj +++ b/GreenshotJiraPlugin/GreenshotJiraPlugin.csproj @@ -12,7 +12,7 @@ - - + + \ No newline at end of file diff --git a/GreenshotPlugin/Core/EmailConfigHelper.cs b/GreenshotPlugin/Core/EmailConfigHelper.cs index bbd816e96..354f02c33 100644 --- a/GreenshotPlugin/Core/EmailConfigHelper.cs +++ b/GreenshotPlugin/Core/EmailConfigHelper.cs @@ -20,6 +20,7 @@ */ using System.IO; +using Microsoft.Win32; namespace GreenshotPlugin.Core { /// @@ -27,16 +28,16 @@ namespace GreenshotPlugin.Core { /// public static class EmailConfigHelper { - public static string GetMapiClient() => RegistryHelper.ReadLocalMachineSoftwareKey(@"Clients\Mail"); + public static string GetMapiClient() => Registry.LocalMachine.ReadKey64Or32(@"Clients\Mail"); public static bool HasMapi() { - var value = RegistryHelper.ReadLocalMachineSoftwareKey(@"Microsoft\Windows Messaging Subsystem", "MAPI", "0"); + var value = Registry.LocalMachine.ReadKey64Or32(@"Microsoft\Windows Messaging Subsystem", "MAPI", "0"); return "1".Equals(value); } - public static string GetOutlookExePath() => RegistryHelper.ReadLocalMachineSoftwareKey(@"Microsoft\Windows\CurrentVersion\App Paths\OUTLOOK.EXE"); + public static string GetOutlookExePath() => Registry.LocalMachine.ReadKey64Or32(@"Microsoft\Windows\CurrentVersion\App Paths\OUTLOOK.EXE"); /// /// Check if Outlook is installed diff --git a/GreenshotPlugin/Core/RegistryHelper.cs b/GreenshotPlugin/Core/RegistryKeyExtensions.cs similarity index 82% rename from GreenshotPlugin/Core/RegistryHelper.cs rename to GreenshotPlugin/Core/RegistryKeyExtensions.cs index e5f068ab4..73fd66a47 100644 --- a/GreenshotPlugin/Core/RegistryHelper.cs +++ b/GreenshotPlugin/Core/RegistryKeyExtensions.cs @@ -27,22 +27,23 @@ namespace GreenshotPlugin.Core /// /// A helper class for accessing the registry /// - public static class RegistryHelper + public static class RegistryKeyExtensions { /// /// Retrieve a registry value /// + /// RegistryKey like Registry.LocalMachine /// string with the name of the key /// string with the name of the value below the key, null will retrieve the default /// string with the default value to return /// string with the value - public static string ReadLocalMachineSoftwareKey(string keyName, string value = null, string defaultValue = null) + public static string ReadKey64Or32(this RegistryKey registryKey, string keyName, string value = null, string defaultValue = null) { string result = null; value ??= string.Empty; if (Environment.Is64BitOperatingSystem) { - using var key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\{keyName}", false); + using var key = registryKey.OpenSubKey($@"SOFTWARE\{keyName}", false); if (key != null) { @@ -52,7 +53,7 @@ namespace GreenshotPlugin.Core if (string.IsNullOrEmpty(result)) { - using var key = Registry.LocalMachine.OpenSubKey($@"SOFTWARE\wow6432node\{keyName}", false); + using var key = registryKey.OpenSubKey($@"SOFTWARE\wow6432node\{keyName}", false); if (key != null) { diff --git a/GreenshotPlugin/GreenshotPlugin.csproj b/GreenshotPlugin/GreenshotPlugin.csproj index 3caa4a7c4..29371bcfd 100644 --- a/GreenshotPlugin/GreenshotPlugin.csproj +++ b/GreenshotPlugin/GreenshotPlugin.csproj @@ -13,9 +13,9 @@ - + - +