From 5e9fff54ef78b469607c2b0f783df3c03fc371bb Mon Sep 17 00:00:00 2001 From: David Hall Date: Mon, 29 Jan 2018 17:57:03 -0700 Subject: [PATCH] Added ControlPanel class to Shell assembly --- UnitTests/Shell/ControlPanelTests.cs | 18 ++++++++++ UnitTests/UnitTests.csproj | 1 + Windows.Shell/ControlPanel.cs | 66 ++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 UnitTests/Shell/ControlPanelTests.cs create mode 100644 Windows.Shell/ControlPanel.cs diff --git a/UnitTests/Shell/ControlPanelTests.cs b/UnitTests/Shell/ControlPanelTests.cs new file mode 100644 index 00000000..0bb77db3 --- /dev/null +++ b/UnitTests/Shell/ControlPanelTests.cs @@ -0,0 +1,18 @@ +using NUnit.Framework; +using static Vanara.PInvoke.Shell32; + +namespace Vanara.Windows.Shell.Tests +{ + [TestFixture] + public class ControlPanelTests + { + [Test] + public void ControlPanelOpenTest() + { + Assert.That(() => ControlPanel.Open(ControlPanelItem.BitLockerDriveEncryption), Throws.Nothing); + Assert.That(() => ControlPanel.Open((ControlPanelItem)0xFFFF), Throws.Exception); + Assert.That(() => ControlPanel.Open(ControlPanelItem.DefaultPrograms, "pageFileAssoc"), Throws.Nothing); + Assert.That(() => ControlPanel.Open(ControlPanelItem.DefaultPrograms, "XX"), Throws.Exception); + } + } +} \ No newline at end of file diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index dfd75d45..de1ff24b 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -115,6 +115,7 @@ + diff --git a/Windows.Shell/ControlPanel.cs b/Windows.Shell/ControlPanel.cs new file mode 100644 index 00000000..0997bc15 --- /dev/null +++ b/Windows.Shell/ControlPanel.cs @@ -0,0 +1,66 @@ +using System; +using System.Runtime.InteropServices; +using Vanara.Extensions; +using static Vanara.PInvoke.Shell32; + +namespace Vanara.Windows.Shell +{ + /// Provides a means to open Control Panel items and get their paths. + public static class ControlPanel + { + private static SafeCP cp; + + private static IOpenControlPanel CP => cp != null ? cp.icp : (cp = new SafeCP()).icp; + + /// Gets the path of a Control Panel item. + /// The Control Panel item. + /// The path. + public static string GetPath(ControlPanelItem item) => GetPath(item.CanonicalName()); + + /// Gets the path of a Control Panel GUID. + /// The Control Panel GUID. + /// The path. + public static string GetPath(Guid item) => GetPath(item.ToString()); + + /// Opens the specified Control Panel item. + /// The Control Panel item. + /// Optional. The Control Panel page. + /// page + public static void Open(ControlPanelItem item, string page = null) + { + if (page != null && Array.IndexOf(item.ValidPages(), page) == -1) throw new ArgumentOutOfRangeException(nameof(page)); + // TODO: handle minOsVer gracefully + CP.Open(item.CanonicalName(), page, null); + } + + private static string GetPath(string item) + { + var sb = new System.Text.StringBuilder(1024); + CP.GetPath(item, sb, (uint)sb.Capacity); + return sb.ToString(); + } + + private class SafeCP : IDisposable + { + internal readonly IOpenControlPanel icp; + private bool disposedValue = false; + + public SafeCP() { icp = new IOpenControlPanel(); } + + ~SafeCP() { Dispose(false); } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposedValue) return; + Marshal.ReleaseComObject(icp); + disposedValue = true; + } + } + } +} \ No newline at end of file