Community.PowerToys.Run.Plugin.Update 0.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Community.PowerToys.Run.Plugin.Update --version 0.1.0                
NuGet\Install-Package Community.PowerToys.Run.Plugin.Update -Version 0.1.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="Community.PowerToys.Run.Plugin.Update" Version="0.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Community.PowerToys.Run.Plugin.Update --version 0.1.0                
#r "nuget: Community.PowerToys.Run.Plugin.Update, 0.1.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 Community.PowerToys.Run.Plugin.Update as a Cake Addin
#addin nuget:?package=Community.PowerToys.Run.Plugin.Update&version=0.1.0

// Install Community.PowerToys.Run.Plugin.Update as a Cake Tool
#tool nuget:?package=Community.PowerToys.Run.Plugin.Update&version=0.1.0                

Community.PowerToys.Run.Plugin.Update

build Community.PowerToys.Run.Plugin.Update

This NuGet package adds support for updating PowerToys Run Plugins.

It contains a ARM64 and x64 version of:

  • Community.PowerToys.Run.Plugin.Update.dll

the images:

  • update.dark.png
  • update.light.png

and the script:

  • update.ps1

Make sure these files are distributed together with your plugin.

Installation

.NET CLI:

dotnet add package Community.PowerToys.Run.Plugin.Update

Package Manager:

PM> NuGet\Install-Package Community.PowerToys.Run.Plugin.Update

PackageReference:

<PackageReference Include="Community.PowerToys.Run.Plugin.Update" Version="0.1.0" />

Example

Example of a .csproj file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
    <Platforms>x64;ARM64</Platforms>
    <PlatformTarget>$(Platform)</PlatformTarget>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Community.PowerToys.Run.Plugin.Update" Version="0.1.0" />
  </ItemGroup>

  <ItemGroup>
    <None Include="plugin.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Include="Images/*.png">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>

Remember to enable DynamicLoading in the plugin.json file:

"DynamicLoading": true

Example of a Main.cs file:

public class Main : IPlugin, IContextMenu, ISettingProvider, ISavable, IDisposable
{
    public Main()
    {
        Storage = new PluginJsonStorage<Plugin1Settings>();
        Settings = Storage.Load();
        Updater = new PluginUpdateHandler(Settings.Update);
        Updater.UpdateInstalling += OnUpdateInstalling;
        Updater.UpdateInstalled += OnUpdateInstalled;
        Updater.UpdateSkipped += OnUpdateSkipped;
    }

    public static string PluginID => "00000000000000000000000000000000";

    public string Name => "Plugin1";

    public string Description => "Plugin1 Description";

    public IEnumerable<PluginAdditionalOption> AdditionalOptions => Settings.GetAdditionalOptions();

    private PluginJsonStorage<Plugin1Settings> Storage { get; }

    private Plugin1Settings Settings { get; }

    private PluginUpdateHandler Updater { get; }

    private PluginInitContext? Context { get; set; }

    private string? IconPath { get; set; }

    private bool Disposed { get; set; }

    public List<Result> Query(Query query)
    {
        if (Updater.IsUpdateAvailable())
        {
            return Updater.GetResults();
        }

        // TODO: implement
        return [];
    }

    public void Init(PluginInitContext context)
    {
        Context = context ?? throw new ArgumentNullException(nameof(context));
        Context.API.ThemeChanged += OnThemeChanged;
        UpdateIconPath(Context.API.GetCurrentTheme());

        Updater.Init(Context);
    }

    public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
    {
        var results = Updater.GetContextMenuResults(selectedResult);
        if (results.Count != 0) return results;

        // TODO: implement
        return [];
    }

    public Control CreateSettingPanel() => throw new NotImplementedException();

    public void UpdateSettings(PowerLauncherPluginSettings settings)
    {
        ArgumentNullException.ThrowIfNull(settings);

        Settings.SetAdditionalOptions(settings.AdditionalOptions);
        Save();
    }

    public void Save() => Storage.Save();

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (Disposed || !disposing)
        {
            return;
        }

        if (Context?.API != null)
        {
            Context.API.ThemeChanged -= OnThemeChanged;
        }

        Updater.Dispose();

        Disposed = true;
    }

    private void UpdateIconPath(Theme theme) => IconPath = theme == Theme.Light || theme == Theme.HighContrastWhite ? "Images/plugin1.light.png" : "Images/plugin1.dark.png";

    private void OnThemeChanged(Theme currentTheme, Theme newTheme) => UpdateIconPath(newTheme);

    private void OnUpdateInstalling(object? sender, PluginUpdateEventArgs e)
    {
        Log.Info("UpdateInstalling: " + e.Version, GetType());
    }

    private void OnUpdateInstalled(object? sender, PluginUpdateEventArgs e)
    {
        Log.Info("UpdateInstalled: " + e.Version, GetType());
        Context!.API.ShowNotification($"{Name} {e.Version}", "Update installed");
    }

    private void OnUpdateSkipped(object? sender, PluginUpdateEventArgs e)
    {
        Log.Info("UpdateSkipped: " + e.Version, GetType());
        Save();
        Context?.API.ChangeQuery(Context.CurrentPluginMetadata.ActionKeyword, true);
    }
}

Example of a Settings class:

public class Plugin1Settings
{
    public PluginUpdateSettings Update { get; set; } = new PluginUpdateSettings();

    internal IEnumerable<PluginAdditionalOption> GetAdditionalOptions() => Update.GetAdditionalOptions();

    internal void SetAdditionalOptions(IEnumerable<PluginAdditionalOption> additionalOptions) => Update.SetAdditionalOptions(additionalOptions);
}

Disclaimer

This is not an official Microsoft PowerToys package.

Product Compatible and additional computed target framework versions.
.NET net8.0-windows7.0 is compatible. 
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 (1)

Showing the top 1 popular GitHub repositories that depend on Community.PowerToys.Run.Plugin.Update:

Repository Stars
hlaueriksson/GEmojiSharp
:octocat: GitHub Emoji for C#, ASP.NET Core and Blazor, dotnet tool for the terminal and PowerToys Run plugin
Version Downloads Last updated
0.2.0 101 8/7/2024
0.1.0 114 8/4/2024

Initial release