using System; using System.Diagnostics; using System.IO; using System.IO.Pipes; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("ConsoleIcon")] [assembly: AssemblyProduct("ConsoleIcon")] [assembly: AssemblyDescription("Pass a icon file path for set to current console window")] [assembly: AssemblyCopyright("Copyright © 2022")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 生成号 // 修订号 // //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 //通过使用 "*",如下所示: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] namespace ConsoleIcon { internal class Program { private const string PipeName = nameof(ConsoleIcon) + "-" + nameof(PipeName); private static void Main(string[] args) { if (args.Length == 1) { if (false == File.Exists($@"\\.\pipe\{PipeName}")) { var daemonProcess = new Process { StartInfo = { WindowStyle = ProcessWindowStyle.Hidden, FileName = Application.ExecutablePath } }; daemonProcess.Start(); } var pipe = new NamedPipeClientStream(PipeName); pipe.Connect(500); IntPtr hWnd = GetConsoleWindow(); // https://stackoverflow.com/a/28616832/2430943 var iconFilePath = Path.GetFullPath(args[0]); var writer = new StreamWriter(pipe); writer.WriteLine(hWnd.ToInt64()); writer.WriteLine(iconFilePath); writer.Flush(); pipe.Close(); } else //Daemon { Console.WriteLine("Daemon start."); while (true) { var pipe = new NamedPipeServerStream(PipeName); pipe.WaitForConnection(); Console.WriteLine("Accept Connection"); var reader = new StreamReader(pipe, Encoding.UTF8); var hWnd = reader.ReadLine(); var iconFilePath = reader.ReadLine(); pipe.Close(); Console.WriteLine($"Setting icon {iconFilePath}"); Console.WriteLine($" to {hWnd:X}"); try { var bytes = File.ReadAllBytes(iconFilePath); using var stream = new MemoryStream(bytes); System.Drawing.Icon icon = new System.Drawing.Icon(stream); SetWindowIcon(new IntPtr(long.Parse(hWnd)), icon); } catch (Exception e) { Console.WriteLine(e); } } } } private static void SetWindowIcon(IntPtr hWnd, System.Drawing.Icon icon) { IntPtr result01 = SendMessage(hWnd, (int)WinMessages.SETICON, 0, icon.Handle); IntPtr result02 = SendMessage(hWnd, (int)WinMessages.SETICON, 1, icon.Handle); } // https://stackoverflow.com/a/59897483/2430943 public static void SetConsoleIcon(string iconFilePath) { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { if (!string.IsNullOrEmpty(iconFilePath) && File.Exists(iconFilePath)) { var bytes = File.ReadAllBytes(iconFilePath); using var stream = new MemoryStream(bytes); System.Drawing.Icon icon = new System.Drawing.Icon(stream); SetWindowIcon(icon); } } } private static void SetWindowIcon(System.Drawing.Icon icon) { IntPtr mwHandle = GetConsoleWindow(); // https://stackoverflow.com/a/28616832/2430943 IntPtr result01 = SendMessage(mwHandle, (int)WinMessages.SETICON, 0, icon.Handle); IntPtr result02 = SendMessage(mwHandle, (int)WinMessages.SETICON, 1, icon.Handle); } [DllImport("kernel32.dll")] private static extern IntPtr GetConsoleWindow(); public enum WinMessages : uint { /// /// An application sends the WM_SETICON message to associate a new large or small icon with a window. /// The system displays the large icon in the ALT+TAB dialog box, and the small icon in the window caption. /// SETICON = 0x0080, } [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam); } }