【问题标题】:C# console get Windows 10 Accent ColorC# 控制台获取 Windows 10 强调色
【发布时间】:2018-11-23 05:20:22
【问题描述】:

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

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

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

【问题讨论】:

  • .NET Core 是跨平台的。 Linux 或 Mac 上是否有强调色?
  • 我知道,但我无法更改框架。所以问题更多的是:“是否有可能得到它。如果可能的话,我怎样才能得到它”
  • 这在 .NET Framework 中是不可能的,所以我很难相信它会在 .NET Core 中可用。如果您可以使用 .NET Framework,类似的问题有一个答案(与 Win8 相关)可能会让您接近:stackoverflow.com/questions/13660976/…

标签: c# windows-10 console-application .net-core-2.0


【解决方案1】:

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

【讨论】:

  • 这个答案很棒,也是一个开始寻找的好地方,但如果使用 MCVE 会更好。不错的第一个答案,冈米拉。欢迎来到堆栈溢出! :)
  • @JamesWhyte 现在怎么样?
  • 很不错,但它足够坚固。好喧嚣:)
  • 如果启用了“自动从我的背景中选择强调色”,这将无法获得正确的颜色。
【解决方案2】:

从 .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。这应该是公认的答案,因为它不依赖于未记录的函数或与注册表混淆。
【解决方案3】:

在 .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 - Calling Windows APIs in .NET5

【讨论】:

    【解决方案4】:

    您可以使用“一对”调用,并且在启用“自动从我的背景中选择强调色”时也可以使用

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

    希望这会有所帮助 安杰洛

    【讨论】:

      猜你喜欢
      • 2020-01-14
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多