mirror of
https://github.com/microsoft/PowerToys
synced 2025-09-04 00:15:11 +00:00
[PTRun] PowerToys Run - plugin dependency loading (#30513)
* Updated the Wox.Plugin to correctly load and resolve plugin dependecies * Included new plugin.props in all plugins to enable dynamic dependecy loading * Updated dev docs to include new plugin.props in plugins * Fixed double dependecy loading bug * - Updated to only use dynamic loading when explicitly set by the plugin. - Removed no longer required props from default plugins which do not need dynamic loading. - Updated dev-docs to align with latest changes * Removed line spacing changes in plugins csproj * fixed spelling * csproj cleanup * removed unnecessary null checking --------- Co-authored-by: Corey Hayward <coreyh@tigereyeconsulting.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
- [ ] Microsoft plugin project name pattern: `Microsoft.PowerToys.Run.Plugin.{PluginName}`
|
- [ ] Microsoft plugin project name pattern: `Microsoft.PowerToys.Run.Plugin.{PluginName}`
|
||||||
- [ ] Community plugin project name pattern: `Community.PowerToys.Run.Plugin.{PluginName}`
|
- [ ] Community plugin project name pattern: `Community.PowerToys.Run.Plugin.{PluginName}`
|
||||||
- [ ] The project file should import `Version.props` and specify `<Version>$(Version).0</Version>`
|
- [ ] The project file should import `Version.props` and specify `<Version>$(Version).0</Version>`
|
||||||
|
- [ ] If the plugin uses any 3rd party dependencies the project file should import `DynamicPlugin.props`
|
||||||
- [ ] Make sure `*.csproj` specify only x64 platform target
|
- [ ] Make sure `*.csproj` specify only x64 platform target
|
||||||
- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder
|
- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder
|
||||||
```
|
```
|
||||||
@@ -17,7 +18,8 @@
|
|||||||
"Website": "https://aka.ms/powertoys",
|
"Website": "https://aka.ms/powertoys",
|
||||||
"ExecuteFileName": string, // Should be {Type}.PowerToys.Run.Plugin.{PluginName}.dll
|
"ExecuteFileName": string, // Should be {Type}.PowerToys.Run.Plugin.{PluginName}.dll
|
||||||
"IcoPathDark": string, // Path to dark theme icon. The path is relative to the root plugin folder
|
"IcoPathDark": string, // Path to dark theme icon. The path is relative to the root plugin folder
|
||||||
"IcoPathLight": string // Path to light theme icon. The path is relative to the root plugin folder
|
"IcoPathLight": string // Path to light theme icon. The path is relative to the root plugin folder
|
||||||
|
"DynamicLoading": bool // Sets whether the plugin should dynamically load any dependencies isolated from the core application.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- [ ] Make sure your `Main` class contains a public, static string property for the `PluginID`. The plugin id has to be the same as the one in the `plugin.json`file.
|
- [ ] Make sure your `Main` class contains a public, static string property for the `PluginID`. The plugin id has to be the same as the one in the `plugin.json`file.
|
||||||
|
12
src/modules/launcher/Plugins/DynamicPlugin.props
Normal file
12
src/modules/launcher/Plugins/DynamicPlugin.props
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ProjectReference>
|
||||||
|
<Private Condition="'$(OutputType)' == 'library'">false</Private>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
</Project>
|
44
src/modules/launcher/Wox.Plugin/PluginLoadContext.cs
Normal file
44
src/modules/launcher/Wox.Plugin/PluginLoadContext.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// 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;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Loader;
|
||||||
|
|
||||||
|
namespace Wox.Plugin
|
||||||
|
{
|
||||||
|
internal class PluginLoadContext : AssemblyLoadContext
|
||||||
|
{
|
||||||
|
private AssemblyDependencyResolver _resolver;
|
||||||
|
|
||||||
|
public PluginLoadContext(string pluginPath)
|
||||||
|
{
|
||||||
|
_resolver = new AssemblyDependencyResolver(pluginPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Assembly Load(AssemblyName assemblyName)
|
||||||
|
{
|
||||||
|
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
|
||||||
|
if (assemblyPath != null)
|
||||||
|
{
|
||||||
|
var existingAssembly = Default.Assemblies.FirstOrDefault(x => x.FullName == assemblyName.FullName);
|
||||||
|
return existingAssembly ?? LoadFromAssemblyPath(assemblyPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
|
||||||
|
{
|
||||||
|
string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
|
||||||
|
if (libraryPath != null)
|
||||||
|
{
|
||||||
|
return LoadUnmanagedDllFromPath(libraryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -65,6 +65,8 @@ namespace Wox.Plugin
|
|||||||
|
|
||||||
public string IcoPathLight { get; set; }
|
public string IcoPathLight { get; set; }
|
||||||
|
|
||||||
|
public bool DynamicLoading { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Name;
|
return Name;
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
@@ -153,7 +154,15 @@ namespace Wox.Plugin
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Metadata.ExecuteFilePath);
|
if (Metadata.DynamicLoading)
|
||||||
|
{
|
||||||
|
var loadContext = new PluginLoadContext(Metadata.ExecuteFilePath);
|
||||||
|
_assembly = loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(Metadata.ExecuteFilePath)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Metadata.ExecuteFilePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user