using System.Runtime.InteropServices; using System.Windows.Shell; namespace Bloxstrap.UI.Utility { // Modified from https://github.com/PowerShell/PSReadLine/blob/e9122d38e932614393ff61faf57d6518990d7226/PSReadLine/PlatformWindows.cs#L704 internal static class TaskbarProgress { private enum TaskbarStates { NoProgress = 0, Indeterminate = 0x1, Normal = 0x2, Error = 0x4, Paused = 0x8, } [ComImport()] [Guid("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface ITaskbarList3 { // ITaskbarList [PreserveSig] int HrInit(); [PreserveSig] int AddTab(IntPtr hwnd); [PreserveSig] int DeleteTab(IntPtr hwnd); [PreserveSig] int ActivateTab(IntPtr hwnd); [PreserveSig] int SetActiveAlt(IntPtr hwnd); // ITaskbarList2 [PreserveSig] int MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen); // ITaskbarList3 [PreserveSig] int SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal); [PreserveSig] int SetProgressState(IntPtr hwnd, TaskbarStates state); // N.B. for copy/pasters: we've left out the rest of the ITaskbarList3 methods... } [ComImport()] [Guid("56fdf344-fd6d-11d0-958a-006097c9a090")] [ClassInterface(ClassInterfaceType.None)] private class TaskbarInstance { } private static Lazy _taskbarInstance = new Lazy(() => (ITaskbarList3)new TaskbarInstance()); private static TaskbarStates ConvertEnum(TaskbarItemProgressState state) { return state switch { TaskbarItemProgressState.None => TaskbarStates.NoProgress, TaskbarItemProgressState.Indeterminate => TaskbarStates.Indeterminate, TaskbarItemProgressState.Normal => TaskbarStates.Normal, TaskbarItemProgressState.Error => TaskbarStates.Error, TaskbarItemProgressState.Paused => TaskbarStates.Paused, _ => throw new Exception($"Unrecognised TaskbarItemProgressState: {state}") }; } private static int SetProgressState(IntPtr windowHandle, TaskbarStates taskbarState) { return _taskbarInstance.Value.SetProgressState(windowHandle, taskbarState); } public static int SetProgressState(IntPtr windowHandle, TaskbarItemProgressState taskbarState) { return SetProgressState(windowHandle, ConvertEnum(taskbarState)); } public static int SetProgressValue(IntPtr windowHandle, int progressValue, int progressMax) { return _taskbarInstance.Value.SetProgressValue(windowHandle, (ulong)progressValue, (ulong)progressMax); } } }