提问人:Inbox 提问时间:11/2/2023 更新时间:11/2/2023 访问量:40
在 C# 控制台应用程序的任务栏按钮中显示进度栏
Show progress bar in C# console application's taskbar button
问:
我想在控制台应用程序的任务栏按钮中显示进度,就像复制文件时 Windows 资源管理器一样。
对于“任务栏按钮”,我指的是任务栏上代表打开程序的空间。例
我指的不是控制台窗口中进度条本身的文本表示形式。
我使用的是 .Net 7,而不是使用 WPF 或 WinForms。
我阅读了以下问题,这些问题没有回答我的:
- 如何在 C# Windows 应用程序中的任务栏图标上显示操作进度
- 如何使用 Winform C# 4.5 在任务栏中显示进度 [副本]
- 如何在 Windows 终端中更新控制台窗口的任务栏进度
- C# 任务栏中的 Windows 7 进度条?
我有以下代码,我发誓几年前曾经工作过:
public 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]
void HrInit();
[PreserveSig]
void AddTab(IntPtr hwnd);
[PreserveSig]
void DeleteTab(IntPtr hwnd);
[PreserveSig]
void ActivateTab(IntPtr hwnd);
[PreserveSig]
void SetActiveAlt(IntPtr hwnd);
// ITaskbarList2
[PreserveSig]
void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
// ITaskbarList3
[PreserveSig]
void SetProgressValue(IntPtr hwnd, ulong ullCompleted, ulong ullTotal);
[PreserveSig]
void SetProgressState(IntPtr hwnd, TaskbarStates state);
}
[ComImport()]
[Guid("56fdf344-fd6d-11d0-958a-006097c9a090")]
[ClassInterface(ClassInterfaceType.None)]
private class TaskbarInstance { }
private static readonly ITaskbarList3 taskbarInstance = (ITaskbarList3)new TaskbarInstance();
private static readonly bool taskbarSupported = Environment.OSVersion.Version >= new Version(6, 1);
public static void SetState(TaskbarStates taskbarState)
{
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
if (taskbarSupported)
taskbarInstance.SetProgressState(handle, taskbarState);
}
public static void SetValue(double progressValue, double progressMax)
{
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
if (taskbarSupported)
taskbarInstance.SetProgressValue(handle, (ulong)progressValue, (ulong)progressMax);
}
我会像这样使用代码:
SetState(TaskbarStates.Normal);
SetValue(20, 30);
但是,现在这什么也没做。我尝试了所有状态和值,并等待按键以确保消息已发布,并且不会因我在代码中设置断点而扭曲。
考虑到可能是句柄没有被正确捕获,我也尝试将句柄替换为:IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
const int STD_OUTPUT_HANDLE = -11;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
IntPtr handle = GetStdHandle(STD_OUTPUT_HANDLE);
但这也行不通。
我做错了什么?
答:
2赞
Inbox
11/2/2023
#1
像往常一样,在发布问题 5 分钟后,我得到了答案。
我不知道为什么既没有工作也没有工作,但确实有效是:GetStdHandle(STD_OUTPUT_HANDLE)
Process.GetCurrentProcess().MainWindowHandle
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
IntPtr handle = GetConsoleWindow();
一旦窗户把手正确,一切都很好。
评论