在 C# 控制台应用程序的任务栏按钮中显示进度条

问题描述 投票:0回答:1

我想在控制台应用程序的任务栏按钮中显示进度,就像复制文件时 Windows 资源管理器所做的那样。

“任务栏按钮”我指的是任务栏上代表打开程序的空间。 Example

我指的不是控制台窗口中进度条的文本表示。

我正在使用 .Net 7,而不是使用 WPF 或 WinForms。

我已阅读以下问题,但这些问题没有回答我的问题:

我有以下代码,我发誓几年前曾经使用过:

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

但这也行不通。

我做错了什么?

c# console-application handle taskbar window-handles
1个回答
0
投票

正如往常一样,发布问题 5 分钟后我就得到了答案。

我不知道为什么

GetStdHandle(STD_OUTPUT_HANDLE)
Process.GetCurrentProcess().MainWindowHandle
都不起作用,但起作用的是:

[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

IntPtr handle = GetConsoleWindow();

一旦窗口句柄正确,一切就OK了。

© www.soinside.com 2019 - 2024. All rights reserved.