Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/Colorful.Console/Interop/NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace Colorful.Interop
{
internal static class NativeMethods
{
private const string Kernel32 = "kernel32.dll";

#region kernel32.dll
[DllImport(Kernel32, EntryPoint = "GetVersion", SetLastError = true)]
internal static extern int GetVersion();
[DllImport(Kernel32, EntryPoint = "SetConsoleMode", SetLastError = true)]
internal static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);
[DllImport(Kernel32, EntryPoint = "GetConsoleMode", SetLastError = true)]
internal static extern bool GetConsoleMode(IntPtr handle, out int mode);
[DllImport(Kernel32, EntryPoint = "GetStdHandle", SetLastError = true)]
internal static extern IntPtr GetStdHandle(int handle);
#endregion

private const string WinrtString = "api-ms-win-core-winrt-string-l1-1-0.dll";

#region api-ms-win-core-winrt-string-l1-1-0.dll
[DllImport(WinrtString, EntryPoint = "WindowsCreateString")]
internal static extern int WindowsCreateString([MarshalAs(UnmanagedType.LPWStr)]string sourceString, int stringLength, out IntPtr hstring);
[DllImport(WinrtString, EntryPoint = "WindowsDeleteString")]
internal static extern int WindowsDeleteString(IntPtr hstring);
#endregion

[DllImport("api-ms-win-core-winrt-l1-1-0.dll", EntryPoint = "RoGetActivationFactory")]
internal static extern int RoGetActivationFactory(IntPtr className, ref Guid guid, out IntPtr instance);
}
}
98 changes: 98 additions & 0 deletions src/Colorful.Console/OperationSystemDetector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using Colorful.Interop;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace Colorful
{
internal static class OperationSystemDetector
{
private static readonly bool _isAnniversaryUpdate;

static OperationSystemDetector()
{
// OS Detection for all CLR implementations (.NET Framework,Mono,.NET Core)
var windir = Environment.GetEnvironmentVariable("windir");

if ((!string.IsNullOrWhiteSpace(windir)) && windir.Contains(@"\") && Directory.Exists(windir))
{
// windows
int version=NativeMethods.GetVersion();
int major = version & 0xFF;
int minor = (version >> 8) & 0xFF;
if ((major < 6) || (minor < 2))
{
_isAnniversaryUpdate = false;
}
else
{
// Windows 6.2 is Windows 8 or later - first which supports Windows RT
_isAnniversaryUpdate = DetectAnniversaryUpdate();
}

}
else if (File.Exists("/proc/sys/kernel/ostype"))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wtf?
Please, use RuntimeInformation.IsOSPlatform()

{
string osType = File.ReadAllText(@"/proc/sys/kernel/ostype");
if (osType.StartsWith("Linux", StringComparison.OrdinalIgnoreCase))
{
// linux
}
}
else if (File.Exists(@"/System/Library/CoreServices/SystemVersion.plist"))
{
// Mac OS
}

}

public static bool IsAnniversaryUpdate
{
get { return _isAnniversaryUpdate; }
}

/// <summary>
/// ALL version info functions are DEPRECATED since Windows 10
/// https://msdn.microsoft.com/en-ca/library/windows/desktop/dn481241(v=vs.85).aspx
/// this code modified version of code:
/// http://answers.unity3d.com/questions/1249727/detect-if-windows-10-anniversary-version-number.html
/// </summary>
/// <returns></returns>
private static bool DetectAnniversaryUpdate()
{
const string kAppExtensionClassName = "Windows.ApplicationModel.AppExtensions.AppExtensionCatalog";
var classNameHString = IntPtr.Zero;
bool ok = false;
try
{
if (NativeMethods.WindowsCreateString(kAppExtensionClassName, kAppExtensionClassName.Length, out classNameHString) == 0)
{
IntPtr appExtensionCatalogStatics;
var IID_IAppExtensionCatalogStatics = new Guid(1010198154, 24344, 20235, 156, 229, 202, 182, 29, 25, 111, 17);

if (NativeMethods.RoGetActivationFactory(classNameHString, ref IID_IAppExtensionCatalogStatics, out appExtensionCatalogStatics) == 0)
{
if (appExtensionCatalogStatics != IntPtr.Zero)
{
Marshal.Release(appExtensionCatalogStatics);
ok = true;
}
}
}
}
finally
{
if (IntPtr.Zero != classNameHString)
{
NativeMethods.WindowsDeleteString(classNameHString);
}
}
return ok;
}



}
}
74 changes: 74 additions & 0 deletions src/Colorful.Console/VirtualTerminalConsole.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using Colorful.Interop;

namespace Colorful
{
/// <summary>
/// Virtual Terminal Helper class for Windows 10 after Anniversary Update
/// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx"/>
/// </summary>
public static class VirtualTerminalConsole
{
private static readonly bool _isVirtualTerminalProcessingActive;
static VirtualTerminalConsole()
{
if (OperationSystemDetector.IsAnniversaryUpdate)
{
_isVirtualTerminalProcessingActive = EnableVirtualTerminalProcessing();
}
}

public static bool IsActive
{
get { return _isVirtualTerminalProcessingActive; }
}

public static bool EnableVirtualTerminalProcessing()
{
var handle = NativeMethods.GetStdHandle(-11);
int mode;
NativeMethods.GetConsoleMode(handle, out mode);
NativeMethods.SetConsoleMode(handle, mode | 0x4);
NativeMethods.GetConsoleMode(handle, out mode);
return (mode & 0x4) == 0x4;
}

public static void RestoreForeground()
{
System.Console.Write(VirtualTerminalSequences.RestoreForeground);
}

public static void RestoreBackground()
{
System.Console.Write(VirtualTerminalSequences.RestoreBackground);
}

public static void SetBold()
{
System.Console.Write(VirtualTerminalSequences.Bold);
}

public static void AddUnderline()
{
System.Console.Write(VirtualTerminalSequences.Underline);
}

public static void RemoveUnderline()
{
System.Console.Write(VirtualTerminalSequences.NoUnderline);
}

public static void SetForegroundColor(Color color)
{
System.Console.Write(VirtualTerminalSequences.ForegroundRgb(color));
}

public static void SetBackgroundColor(Color color)
{
System.Console.Write(VirtualTerminalSequences.BackgroundRgb(color));
}
}
}
63 changes: 63 additions & 0 deletions src/Colorful.Console/VirtualTerminalSequences.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System.Drawing;
using System.Text;

namespace Colorful
{
internal static class VirtualTerminalSequences
{
private const char Escape = '\x1b';

internal static readonly string RestoreForeground= SgrCommand(39);
internal static readonly string RestoreBackground = SgrCommand(49);
internal static readonly string Bold = SgrCommand(1);
internal static readonly string Underline = SgrCommand(4);
internal static readonly string NoUnderline = SgrCommand(24);


private static readonly string SgrStart = "\x1b[";

private static StringBuilder SgrCommandBegin(int num)
{
StringBuilder ret = new StringBuilder(SgrStart, 20);
ret.Append(num);
return ret;
}

private static string SgrCommand(int num)
{
var ret = SgrCommandBegin(num);
ret.Append('m');
return ret.ToString();
}

private static void AppendRgb(StringBuilder builder, Color color)
{
builder.Append(';');
builder.Append(color.R);
builder.Append(';');
builder.Append(color.G);
builder.Append(';');
builder.Append(color.B);
}

private static string AdvancedColor(int num,Color color)
{
StringBuilder ret = SgrCommandBegin(num);
ret.Append(';');
ret.Append(2);
AppendRgb(ret, color);
ret.Append('m');
return ret.ToString();
}

public static string ForegroundRgb(Color color)
{
return AdvancedColor(38, color);
}

public static string BackgroundRgb(Color color)
{
return AdvancedColor(48,color);
}
}
}
15 changes: 14 additions & 1 deletion src/ExampleConsoleApplication/Examples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using Colorful;
using Console = Colorful.Console;
using System.Reflection;
using System.Resources;
using System.Collections;
using System.IO;
using Colorful;

namespace TestConsole
{
Expand All @@ -20,6 +20,19 @@ static void Main(string[] args)
// NOTE: Running all of the following examples at once will result in unexpected
// coloring behavior, as more than 16 different colors are used!

for(int rr = 0; rr < 255; rr+=25)
{
for (int gg=0; gg < 255; gg+= 25)
{
for (int bb = 0; bb < 255; bb+= 25)
{
//VirtualTerminalConsole.SetForegroundColor(Color.Pink);
VirtualTerminalConsole.SetForegroundColor(Color.FromArgb(rr, gg, bb));
Console.Write("*");
}
}
}

Console.WriteLine("hi", Color.Pink);
int r = 225;
int g = 255;
Expand Down