TrayAppUtility 1.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package TrayAppUtility --version 1.2.0                
NuGet\Install-Package TrayAppUtility -Version 1.2.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TrayAppUtility" Version="1.2.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add TrayAppUtility --version 1.2.0                
#r "nuget: TrayAppUtility, 1.2.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install TrayAppUtility as a Cake Addin
#addin nuget:?package=TrayAppUtility&version=1.2.0

// Install TrayAppUtility as a Cake Tool
#tool nuget:?package=TrayAppUtility&version=1.2.0                

TrayAppUtility

Provides high-level APIs to create task-executing tray applications in Window Presentation Foundation (WPF)

Features

  • Progress API
    • Ability to set total and processed items
    • Getter for estimated time to completion
  • Logging API
    • Each task generates a separate log file
    • All tasks are automatically measured for time. Runtime is appended to the log file.
    • Log files older than a month are automatically deleted
    • Time-intensive action parts can be measured manually
    • An attribute to disable logging for particular action
  • Action
    • Declared as a public static method
    • Ability to set tray action that will be used to populate tray icon context menu
    • Ability to set default tray action that will be executed on double click if the tray is not in the error state
    • Receives an instance of log writer
    • Can be canceled at any time by the user
  • Tray
    • Custom tray icon
    • Context menu populated with users' actions
    • Double-clicking executes default action if specified
    • When an action is being executed that uses Progress API, a radial progress bar is overlayed over the tray icon
    • When an action is being executed a tooltip is set containing
      • Action name
      • Processed and total item counts as well as percentage completed
      • Estimated time to completion
      • Last log entry written
    • When an action throws an unhandled exception tray app enters an error state
      • Progress bar overlay changes color to red
      • Double-clicking the tray icon opens the last log file and clears the error state
      • Any context menu action clears the error state and starts their respective action
  • Utilities
    • Nice name method
    • Open file or folder with default application (can wait for close)

Tutorial

Configuring tray app utility

In order to start using the tray app utility we need create a new project from WPF application template and set its window as the startup window. We can do this in App.xaml file

<Application x:Class="Tutorial.App"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   StartupUri="pack://application:,,,/TrayAppUtility;component/TrayApp.xaml"> 
</Application>

Without any further actions, the application should not generate an empty tray app with a context menu containing default utility actions.

BFjcNzG8kp

Changing tray icon

Using the tray app utility is quite simple. One of the first things we might want to do is set our custom icon. This can be done by adding a png image with the name "TrayIcon.png" to the project files.

devenv_1XKmYNLobO

Then you need to make the PNG file build action to be set to "Embedded resource".

devenv_6D8WrFX9iX

This will make your custom icon discoverable by tray app utility. Once the project is built, you should see tray app use your icon.

yYaggdnX8h

Defining an action

In order to start adding your own actions to the tray app, declare a public static method. The name of the method will be used as the name of the action. Here is an example of the full method signature:

[TrayAction]
public static void Action(CancellationTokenSource cancel)
{
}

Of course, there is no point in leaving an empty action so let's fill it with some work to do:

[TrayAction]
public static void Action(CancellationTokenSource cancel)
{
    var length = 100;
    Progress.Total = length;

    for (int i = 0; i < length; i++)
    {
        if (cancel.IsCancellationRequested)
        {
            Log.Write($"Cancelling Default Action");
            return;
        }

        Thread.Sleep(100);
        Progress.Increment($"Processed item {i}");
    }
}

This is a fully implemented tray action. That's how it should look in action:

oeZLAbwDB0

Defining a default action

Default actions are created identically as tray actions. In fact, both attributes can be used in accord. Here is an example of making a default action:

[TrayAction]
[TrayDefault]
public static void DefaultAction(CancellationTokenSource cancel)
{
...
}

Now tray app will execute this action upon double click.

rYYocKeURP

No logging

Some actions are so simple that they don't need logs. You can disable logging for a particular action using NoLog attribute:

[TrayAction]
[TrayDefault]
[NoLog]
public static void DefaultAction(CancellationTokenSource cancel)
{
...
}

You will still see log messages in tray tooltips but they won't be saved into a dedicated log file.

A complete tutorial app can be found here

Product Compatible and additional computed target framework versions.
.NET net6.0-windows7.0 is compatible.  net7.0-windows was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.1 166 11/14/2023
1.3.0 87 9/21/2023
1.2.1 182 8/18/2023
1.2.0 179 8/9/2023
1.1.1 184 8/7/2023
1.1.0 180 8/4/2023
1.0.0 171 8/1/2023