C#控制台获取Windows 10强调色

3
在 .Net Core 2.X 中,有没有一种方法可以在控制台应用程序中读取所选的 Windows 10 强调颜色。我发现大多数解决方案都是 UWP 或 WPF 应用程序。为了向您展示我指的颜色,这里是一张图片:

.NET Core是跨平台的。在Linux或Mac上有强调颜色吗? - Alexander Petrov
我知道它,但我没有更改框架的可能性。因此问题更多是:“是否有可能获得它?何时可以获得它?” - threater
在.NET Framework中不可能实现,所以我很难相信它会在.NET Core中可用。如果您可以使用.NET Framework,类似的问题有一个答案(与Win8相关),这可能会让您接近:https://dev59.com/_GYr5IYBdhLWcg3wdp4C - Paul Suart
5个回答

8

从.NET Core 3.0开始,通过使用Microsoft.Windows.SDK.Contracts包,非UWP应用程序也可以调用UWP API。

因此,我们可以使用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);

1
+1。这应该是被接受的答案,因为它不依赖于未记录的函数或更改注册表。 - Xam

2

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

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

以下是有关该包的信息: https://learn.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 );
}


如果启用了“从我的背景自动选择强调颜色”,则无法获取正确的颜色。 - Aidan Fitzpatrick

1
在 .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 Core)。
在我的情况下,我正在使用Electron.NET和ASP.NET Core,它可以无缝运行。
来源:Windows Developer Blog - 在.NET5中调用Windows API

1

使用 winrt-api

.net 5 示例:

GetAccentColor.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
  </PropertyGroup>

</Project>

Program.cs

using System;

namespace GetAccentColor
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine($"GetAccentColor = {GetAccentColor()}");
        }

        public static Windows.UI.Color GetAccentColor()
        {
            var color = new Windows.UI.Color();
            if (Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.UI.ViewManagement.UISettings", "GetColorValue"))
            {
                var uiSettings = new Windows.UI.ViewManagement.UISettings();
                color = uiSettings.GetColorValue(Windows.UI.ViewManagement.UIColorType.Accent);
            }
            return color;
        }
    }
}

结果: GetAccentColor


0

你可以使用“几个”调用,当“从我的背景自动选择强调颜色”也启用时,它也能正常工作。

    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类:

    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);

和操作系统类一起:

    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;
    }

希望这可以帮到你 安吉洛


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接