Windows 7进度栏在C#中的任务栏中?


73

如果您在Windows 7 Beta中注意到了,如果您复制文件或其他系统操作,则任务栏中的Windows资源管理器图标将充满绿色的进度条,该进度条等同于表单上的进度条。在我的C#表单中,是否可以强制我的任务栏进度栏与我正在执行的任何任务的进度相匹配?转换,转移,生成,该进度条有很多用途。

Answers:


83

我只是想在WinForms应用程序中添加一些任务栏进度动画,而不必下载代码包或切换到WPF来使用TaskbarItemInfo。

解决方案是使用ITaskbarList3接口的类:

using System;
using System.Runtime.InteropServices;

public static class TaskbarProgress
{
    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, UInt64 ullCompleted, UInt64 ullTotal);
        [PreserveSig]
        void SetProgressState(IntPtr hwnd, TaskbarStates state);
    }

    [ComImport()]    
    [Guid("56fdf344-fd6d-11d0-958a-006097c9a090")]
    [ClassInterface(ClassInterfaceType.None)]
    private class TaskbarInstance
    {
    }

    private static ITaskbarList3 taskbarInstance = (ITaskbarList3)new TaskbarInstance();
    private static bool taskbarSupported = Environment.OSVersion.Version >= new Version(6, 1);

    public static void SetState(IntPtr windowHandle, TaskbarStates taskbarState)
    {
        if (taskbarSupported) taskbarInstance.SetProgressState(windowHandle, taskbarState);
    }

    public static void SetValue(IntPtr windowHandle, double progressValue, double progressMax)
    {
        if (taskbarSupported) taskbarInstance.SetProgressValue(windowHandle, (ulong)progressValue, (ulong)progressMax);
    }
}

简单易用的示例:

TaskbarProgress.SetState(this.Handle, TaskbarProgress.TaskbarStates.Indeterminate);

or

TaskbarProgress.SetValue(this.Handle, 50, 100);
TaskbarProgress.SetState(this.Handle, TaskbarProgress.TaskbarStates.Error);

4
这是一个了不起的奇妙答案。没有外部依赖关系或下载,并且可以正常工作
2014年

1
如果要像我一样添加SetOverlayIcon,请确保以正确的顺序添加所有其他方法。参见stackoverflow.com/questions/1024786/…
Todd Myhre 2014年

1
不幸的是,这在Windows XP上运行时会破坏应用程序!有什么办法吗?
Kevin Vuilleumier

6
解决方案是确保您不在XP中执行此操作。
Chibueze Opata 2015年

@KevinVuilleumier真正的解决方案是在运行代码之前检查Windows版本

48

对于那些想跳过阅读文档而只是得到一些有用的东西的人...

  • 下载 适用于Microsoft .Net FrameworkWindows API代码包
  • 运行安装程序以创建一个zip文件
  • 从zip文件的binaries文件夹中提取以下dll:
    • Microsoft.WindowsAPICodePack.dll
    • Microsoft.WindowsAPICodePack.Shell.dll
  • 在您的项目中添加对它们的引用
  • 将以下代码放入您的应用中,并根据需要进行修改:

-

  int max = 100;
  var prog = Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.Instance;
  prog.SetProgressState(Microsoft.WindowsAPICodePack.Taskbar.TaskbarProgressBarState.Normal);
  for(int i=0;i<max;i++) {
     prog.SetProgressValue(i, max);
     Thread.Sleep(100);     
  }
  prog.SetProgressState(Microsoft.WindowsAPICodePack.Taskbar.TaskbarProgressBarState.NoProgress);

nuget下载有点烦人,但是不错。在我的进度栏处理程序类中实现:)
Nyerguds,

@Nyerguds:nuget下载有什么烦恼?只需将命令复制并粘贴到nuget的控制台上就可以了。
杰克

这意味着必须下载并安装另一件事...即nuget。
Nyerguds




0

我找到了一篇漂亮的文章(Link),该文章为任务栏进度栏问题提供了简单的解决方案。总之,它指示您从MSDN网站下载Windows API包,添加对其包含的Microsoft.WindowsAPICodePack.Shell.dll的引用,最后向您的应用程序添加三行代码:

Imports Microsoft.WindowsAPICodePack
Imports Microsoft.WindowsAPICodePack.Taskbar
// ...
TaskbarManager.Instance.SetProgressValue(X, 100)

X是您要显示的进度。


2
请注意,不鼓励仅链接的答案,因此SO答案应该是搜索解决方案的终点(相对于引用的另一种中途停留,随着时间的流逝,它们会变得陈旧)。请考虑在此处添加独立的摘要,并保留该链接作为参考。
kleopatra 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.