在已部署的应用

时间:2017-04-03 07:40:21

标签: c# wpf xaml

我想更改任务栏图标,以便在收到新邮件时收到类似Outlook的新邮件时通知用户。

我已经在网上搜索解决方案了,所有关于改变窗口图标的方法都是这样的:

Uri iconUri = new Uri("Resources/envelop.ico", UriKind.Relative);
this.Icon = BitmapFrame.Create(iconUri);

它在Visual Studio上运行良好,但我发现它没有在部署的应用上更改我的任务栏,因为它是一个只读变量。更糟糕的是,它只改变了我不想改变的左上角附加图标。

那么有办法吗? Outlook做到了,Chrome也是如此,所以必须有办法。

更新

要强制在我已部署的应用上刷新图标,我必须固定/取消固定我的图标任务栏,不幸的是这只是一个用户命令,因此我无法通过编程方式在wpf中执行此操作而不会利用一些肮脏的方式不稳定。

实际上,我试图找到一种方法来刷新Icon缓存而不为每个Windows操作系统或版本执行此操作。

3 个答案:

答案 0 :(得分:0)

您需要考虑的两个步骤:

  1. 如果“控制面板”中也安装了软件,则需要注意。如果是这样,请尝试从此处卸载它,但将软件的运行时文件夹保留在某处以进行测试。

  2. 从%AppData%中删除您的软件数据文件,然后尝试在不安装软件的情况下再次运行该软件(复制了运行时文件夹的位置),您应该能够看到Taskbar如何刷新它。

您需要解决的一件事是,为什么在“控制面板”中安装软件会出现故障,以至于它不会刷新任务栏中的图标。

答案 1 :(得分:-1)

对我来说,这个解决方案正在发挥作用。

使用Write text on bitmap in C#

中的代码创建此代码
    private Icon DrawIcon(Brush brush)
    {
        //https://stackoverflow.com/questions/6311545/c-sharp-write-text-on-bitmap     
        Bitmap bmp = new Bitmap(MyNameSpace.Properties.Resources.desktop_windows_48px);

        // Create a rectangle for the entire bitmap
        RectangleF rectf = new RectangleF(0, 0, bmp.Width, bmp.Height);

        // Create graphic object that will draw onto the bitmap
        Graphics g = Graphics.FromImage(bmp);

        // The smoothing mode specifies whether lines, curves, and the edges of filled areas use smoothing (also called antialiasing). One exception is that path gradient brushes do not obey the smoothing mode. Areas filled using a PathGradientBrush are rendered the same way (aliased) regardless of the SmoothingMode property.
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

        // The interpolation mode determines how intermediate values between two endpoints are calculated.
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

        // Use this property to specify either higher quality, slower rendering, or lower quality, faster rendering of the contents of this Graphics object.
        g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;

        // This one is important
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;

        // Draw the text onto the image
        g.FillRectangle(brush, new Rectangle(2, 4, 20, 12));

        // Flush all graphics changes to the bitmap
        g.Flush();

        Bitmap temp = bmp;

        // Get an Hicon for myBitmap.
        IntPtr Hicon = temp.GetHicon();

        // Create a new icon from the handle.
        Icon newIcon = Icon.FromHandle(Hicon);

        return newIcon;            
    }

我也在使用NotifyIcon,但这并没有改变很多。

_notifyIcon.Icon = DrawIcon(Brushes.Blue);
MainWindow.Icon =  Imaging.CreateBitmapSourceFromHIcon(_notifyIcon.Icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

后来我改变它(就像更改图标来源时可能类似。

    private void App_StateChanged(object sender, StateChangedEventArgs e)
    {
        if(e.State == ApplicationState.Defective)
        {
            //Show window on error !
            ShowMainWindow();
            //(sender as Window).Activate();
        }
        _notifyIcon.Icon = DrawIcon(e.StateBrush);
        MainWindow.Icon = Imaging.CreateBitmapSourceFromHIcon(_notifyIcon.Icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
        _notifyIcon.Visible = true;
    }

看起来与此类似:

默认值:

enter image description here

出错:

enter image description here

希望这有用!

答案 2 :(得分:-1)

这是一个小的工作演示,正在完成这项工作!

添加图标

enter image description here enter image description here

选择2个图标(例如Outlook Standard& Outlook MailReceived):

将此添加到MainWindow

后面的代码中
public partial class MainWindow : Window
{
    private int _imgId;

    public MainWindow()
    {
        InitializeComponent();
        this.Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        //Start timer to periodically change the App Icon:
        new System.Threading.Thread(() =>
        {
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Interval = 100;
            timer.AutoReset = true;
            timer.Elapsed += Timer_Elapsed;
            timer.Start();
        }).Start();
    }

    private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        try
        {      
            //Change AppIcon on UI-Thread         
            Dispatcher.Invoke(() =>
            {
                /* CHANGE YOUR ICONS HERE !!! */
                BitmapSource ms_icon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(Properties.Resources.Microsoft_logo.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                BitmapSource so_icon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(Properties.Resources.images.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                if (_imgId == 0)
                {
                    this.Icon = so_icon;
                    _imgId = 1;
                }
                else
                {
                    this.Icon = ms_icon;
                    _imgId = 0;
                }
            });
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(ex.Message);               
        }            
    }
}

将产生此输出(每100ms切换一次):

enter image description here