Adding OneNote plugin for PowerToys Run (#18558)

* Adding OneNote plugin for PowerToys Run

* Updating to 3.0.1 dependency, updating md, spellcheck, ready for PR

* Updating spelling and using localized string

* Adding OneNote link to readme

* Adding OneNote requirement to description

* removing 'open' from description

* Updating interop version, PR feedback
This commit is contained in:
Union Palenshus
2022-06-15 10:15:58 -07:00
committed by GitHub
parent b6ff870549
commit 9b7a7f93b7
17 changed files with 2004 additions and 1423 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

View File

@@ -0,0 +1,151 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using ManagedCommon;
using Microsoft.PowerToys.Run.Plugin.OneNote.Properties;
using ScipBe.Common.Office.OneNote;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;
using Wox.Plugin;
namespace Microsoft.PowerToys.Run.Plugin.OneNote
{
/// <summary>
/// A power launcher plugin to search across time zones.
/// </summary>
public class Main : IPlugin, IPluginI18n
{
/// <summary>
/// A value indicating if the OneNote interop library was able to successfully initialize.
/// </summary>
private bool _oneNoteInstalled;
/// <summary>
/// The initial context for this plugin (contains API and meta-data)
/// </summary>
private PluginInitContext? _context;
/// <summary>
/// The path to the icon for each result
/// </summary>
private string _iconPath;
/// <summary>
/// Initializes a new instance of the <see cref="Main"/> class.
/// </summary>
public Main()
{
UpdateIconPath(Theme.Light);
}
/// <summary>
/// Gets the localized name.
/// </summary>
public string Name => Resources.PluginTitle;
/// <summary>
/// Gets the localized description.
/// </summary>
public string Description => Resources.PluginDescription;
/// <summary>
/// Initialize the plugin with the given <see cref="PluginInitContext"/>
/// </summary>
/// <param name="context">The <see cref="PluginInitContext"/> for this plugin</param>
public void Init(PluginInitContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
try
{
_ = OneNoteProvider.PageItems.Any();
_oneNoteInstalled = true;
}
catch (COMException)
{
// OneNote isn't installed, plugin won't do anything.
_oneNoteInstalled = false;
}
_context.API.ThemeChanged += OnThemeChanged;
UpdateIconPath(_context.API.GetCurrentTheme());
}
/// <summary>
/// Return a filtered list, based on the given query
/// </summary>
/// <param name="query">The query to filter the list</param>
/// <returns>A filtered list, can be empty when nothing was found</returns>
public List<Result> Query(Query query)
{
if (!_oneNoteInstalled || query is null || string.IsNullOrWhiteSpace(query.Search))
{
return new List<Result>(0);
}
var pages = OneNoteProvider.FindPages(query.Search);
return pages.Select(p => new Result
{
IcoPath = _iconPath,
Title = p.Name,
QueryTextDisplay = p.Name,
SubTitle = @$"{p.Notebook.Name}\{p.Section.Name}",
Action = (_) =>
{
p.OpenInOneNote();
ShowOneNote();
return true;
},
ContextData = p,
ToolTipData = new ToolTipData(Name, @$"{p.Notebook.Name}\{p.Section.Name}\{p.Name}"),
}).ToList();
}
/// <summary>
/// Return the translated plugin title.
/// </summary>
/// <returns>A translated plugin title.</returns>
public string GetTranslatedPluginTitle() => Resources.PluginTitle;
/// <summary>
/// Return the translated plugin description.
/// </summary>
/// <returns>A translated plugin description.</returns>
public string GetTranslatedPluginDescription() => Resources.PluginDescription;
private void OnThemeChanged(Theme currentTheme, Theme newTheme)
{
UpdateIconPath(newTheme);
}
[MemberNotNull(nameof(_iconPath))]
private void UpdateIconPath(Theme theme)
{
_iconPath = theme == Theme.Light || theme == Theme.HighContrastWhite ? "Images/oneNote.light.png" : "Images/oneNote.dark.png";
}
/// <summary>
/// Brings OneNote to the foreground and restores it if minimized.
/// </summary>
private void ShowOneNote()
{
using var process = Process.GetProcessesByName("onenote").FirstOrDefault();
if (process?.MainWindowHandle != null)
{
HWND handle = (HWND)process.MainWindowHandle;
if (PInvoke.IsIconic(handle))
{
PInvoke.ShowWindow(handle, SHOW_WINDOW_CMD.SW_RESTORE);
}
PInvoke.SetForegroundWindow(handle);
}
}
}
}

View File

@@ -0,0 +1,103 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<RootNamespace>Microsoft.PowerToys.Run.Plugin.OneNote</RootNamespace>
<AssemblyName>Microsoft.PowerToys.Run.Plugin.OneNote</AssemblyName>
<ImplicitUsings>enable</ImplicitUsings>
<Version>$(Version).0</Version>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<Nullable>enable</Nullable>
<OutputPath>..\..\..\..\..\$(Platform)\$(Configuration)\modules\launcher\Plugins\OneNote\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<DebugSymbols>true</DebugSymbols>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\..\..\codeAnalysis\GlobalSuppressions.cs">
<Link>GlobalSuppressions.cs</Link>
</Compile>
<AdditionalFiles Include="..\..\..\..\codeAnalysis\StyleCop.json">
<Link>StyleCop.json</Link>
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Interop.Microsoft.Office.Interop.OneNote" Version="1.1.0.2" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.691-beta">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ScipBe.Common.Office.OneNote" Version="3.0.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="Images\oneNote.dark.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\oneNote.light.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,3 @@
IsIconic
SetForegroundWindow
ShowWindow

View File

@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.PowerToys.Run.Plugin.OneNote.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.PowerToys.Run.Plugin.OneNote.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Searches your local OneNote notebooks. This plugin requires the OneNote desktop app which is included in Microsoft Office..
/// </summary>
internal static string PluginDescription {
get {
return ResourceManager.GetString("PluginDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to OneNote.
/// </summary>
internal static string PluginTitle {
get {
return ResourceManager.GetString("PluginTitle", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PluginTitle" xml:space="preserve">
<value>OneNote</value>
</data>
<data name="PluginDescription" xml:space="preserve">
<value>Searches your local OneNote notebooks. This plugin requires the OneNote desktop app which is included in Microsoft Office.</value>
</data>
</root>

View File

@@ -0,0 +1,14 @@
{
"ID": "0778F0C264114FEC8A3DF59447CF0A74",
"Disabled": true,
"ActionKeyword": "o:",
"IsGlobal": true,
"Name": "OneNote",
"Author": "palenshus",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.PowerToys.Run.Plugin.OneNote.dll",
"IcoPathDark": "Images\\oneNote.dark.png",
"IcoPathLight": "Images\\oneNote.light.png"
}

View File

@@ -8,7 +8,7 @@
<UseWindowsForms>true</UseWindowsForms>
<StartupObject>PowerLauncher.App</StartupObject>
<ApplicationIcon>Images\RunResource.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationManifest>app.manifest</ApplicationManifest>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
@@ -72,14 +72,15 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Page Include="App.xaml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Interop.Microsoft.Office.Interop.OneNote" Version="1.1.0.2" />
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" />
<PackageReference Include="Mages" Version="2.0.0" />
<PackageReference Include="Mages" Version="2.0.0" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -88,8 +89,9 @@
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="ScipBe.Common.Office.OneNote" Version="3.0.1" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
<PackageReference Include="System.Runtime" Version="4.3.1" />
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.7" />
<PackageReference Include="System.Data.OleDb" Version="6.0.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />