C# console get Windows 10 强调色

C# console get Windows 10 Accent Color

.Net Core 2.X 中有没有办法在控制台应用程序中读取选定的 Windows 10 强调色。

我找到的大多数解决方案都是 UWP 或 WPF 应用程序。

也告诉你我的意思是什么颜色,这是它的图片:

HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ - 存储所有装饰颜色。因此,如果应用程序以 HKEY_CURRENT_USER 的权限启动,您可以读取或更改“AccentColor”属性(以及目录中的其他内容)或更改十六进制表示法中的颜色代码你自己的。

要访问 windows 注册表,您需要安装软件包: https://www.nuget.org/packages/Microsoft.Windows.Compatibility/

有关包裹的信息如下: https://docs.microsoft.com/en-us/dotnet/core/porting/windows-compat-pack/


颜色值以 ABGR 顺序存储为注册表 DWORD(32 位整数)值(与 ARGBRGBA 顺序相反)。

using Microsoft.Win32;

public static ( Byte r, Byte g, Byte b, Byte a ) GetAccentColor()
{
    const String DWM_KEY = @"Software\Microsoft\Windows\DWM";
    using( RegistryKey dwmKey = Registry.CurrentUser.OpenSubKey( DWM_KEY, RegistryKeyPermissionCheck.ReadSubTree ) )
    {
        const String KEY_EX_MSG = "The \"HKCU\" + DWM_KEY + "\" registry key does not exist.";
        if( dwmKey is null ) throw new InvalidOperationException( KEY_EX_MSG );

        Object accentColorObj = dwmKey.GetValue( "AccentColor" );
        if( accentColorObj is Int32 accentColorDword )
        {
            return ParseDWordColor( accentColorDword );
        }
        else
        {
            const String VALUE_EX_MSG = "The \"HKCU\" + DWM_KEY + "\AccentColor\" registry key value could not be parsed as an ABGR color.";
            throw new InvalidOperationException( VALUE_EX_MSG );
        }
    }

}

private static ( Byte r, Byte g, Byte b, Byte a ) ParseDWordColor( Int32 color )
{
    Byte
        a = ( color >> 24 ) & 0xFF,
        b = ( color >> 16 ) & 0xFF,
        g = ( color >>  8 ) & 0xFF,
        r = ( color >>  0 ) & 0xFF;

    return ( r, g, b, a );
}

从 .NET Core 3.0 开始,也可以在 Microsoft.Windows.SDK.Contracts 包的帮助下从非 UWP 应用调用 UWP APIs。

因此我们可以使用 UWP API 从 .NET Core 控制台应用程序获取强调色:

var uiSettings = new UISettings();
var accentColor = uiSettings.GetColorValue(UIColorType.Accent);

返回的颜色是 Windows.UI.Color 类型,但可以很容易地转换成例如 System.Drawing.Color

Color.FromArgb(accentColor.A, accentColor.R, accentColor.G, accentColor.B);

在 .NET 5 中(与 .NET Core 3.0 不同)您不必引用 Microsoft.Windows.SDK.Contracts NuGet 包。

打开您的 csproj 文件并按如下方式更新它:

<PropertyGroup>
  <TargetFramework>net5.0-windows10.0.17763.0</TargetFramework>
</PropertyGroup>

支持的平台: 10.0.17763.0 10.0.18362.0 10.0.19041.0

然后像这样使用它(来自 Erko 的回答):

var uiSettings = new UISettings();
var accentColor = uiSettings.GetColorValue(UIColorType.Accent);

这适用于桌面应用程序和 Web 应用程序(ASP.NET 核心)。

就我而言,我使用的是 Electron.NET 和 ASP.NET Core,它运行得非常完美。

来源:Windows Developer Blog - Calling Windows APIs in .NET5

您可以使用 'couple' 个调用,并且在启用“自动从我的背景中选择强调色”时它也有效

    public static Color GetWindowsAccentColor()
    {
        WinApi.DWMCOLORIZATIONcolors colors = new WinApi.DWMCOLORIZATIONcolors();
        WinApi.DwmGetColorizationParameters(ref colors);

        //get the theme --> only if Windows 10 or newer
        if (OS.IsWindows10orGreater())
            return ParseColor((int)colors.ColorizationColor); 
        else
            return Color.CadetBlue; 
    }

    private static Color ParseColor(Int32 color)
    {
        var opaque = true;

        return Color.FromArgb((byte)(opaque ? 255 : (color >> 24) & 0xff),
            (byte)((color >> 16) & 0xff),
            (byte)((color >> 8) & 0xff),
            (byte)(color) & 0xff);
    }

拥有 WinApi class 以及:

    public struct DWMCOLORIZATIONcolors
    {
        public uint ColorizationColor,
            ColorizationAfterglow,
            ColorizationColorBalance,
            ColorizationAfterglowBalance,
            ColorizationBlurBalance,
            ColorizationGlassReflectionIntensity,
            ColorizationOpaqueBlend;
    }

    [DllImport("dwmapi.dll", EntryPoint = "#127")]
    public static extern void DwmGetColorizationParameters(ref DWMCOLORIZATIONcolors colors);

和OSclass与:

    public static bool IsWindows10orGreater()
    {
        if (WindowsVersion() >= 10)
            return true;
        else
            return false;

    }

    public static int WindowsVersion()
    {
        //for .Net4.8 and Minor
        int result = 10;
        var reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
        string[] productName = reg.GetValue("ProductName").ToString().Split((char)32);
        int.TryParse(productName[1], out result);
        return result;

        //fixed .Net6
        //return System.Environment.OSVersion.Version.Major;
    }

希望对您有所帮助 安杰洛