[新增]第一版
This commit is contained in:
parent
c8b39771a0
commit
49114b711e
21
你好插件/你好命令.cs
Normal file
21
你好插件/你好命令.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using PluginBase;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace 你好插件
|
||||
{
|
||||
public class 你好命令 : ICommand
|
||||
{
|
||||
public string 名称 { get => "你好"; }
|
||||
public string 描述 { get => "显示一个你好的消息"; }
|
||||
|
||||
[DllImport("Kernel32.dll")]//引入命名空间
|
||||
public static extern bool Beep(int frequency, int duration);
|
||||
public int 执行()
|
||||
{
|
||||
Console.WriteLine("你好 !!!\n");
|
||||
Beep(700, 200);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
16
你好插件/你好插件.csproj
Normal file
16
你好插件/你好插件.csproj
Normal file
|
@ -0,0 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\加载dll\加载dll.csproj">
|
||||
<Private>False</Private>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33403.182
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "加载dll", "加载dll\加载dll.csproj", "{4E443C0A-8E49-4186-9069-9946B033135E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "加载dll", "加载dll\加载dll.csproj", "{4E443C0A-8E49-4186-9069-9946B033135E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "你好插件", "你好插件\你好插件.csproj", "{748E79C2-35E6-4B25-890A-B88064B47705}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -15,6 +17,10 @@ Global
|
|||
{4E443C0A-8E49-4186-9069-9946B033135E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4E443C0A-8E49-4186-9069-9946B033135E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4E443C0A-8E49-4186-9069-9946B033135E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{748E79C2-35E6-4B25-890A-B88064B47705}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{748E79C2-35E6-4B25-890A-B88064B47705}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{748E79C2-35E6-4B25-890A-B88064B47705}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{748E79C2-35E6-4B25-890A-B88064B47705}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
16
加载dll/PluginBase.cs
Normal file
16
加载dll/PluginBase.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PluginBase
|
||||
{
|
||||
public interface ICommand
|
||||
{
|
||||
string 名称 { get; }//Name
|
||||
string 描述 { get; }//Description
|
||||
|
||||
int 执行();
|
||||
}
|
||||
}
|
113
加载dll/Program.cs
113
加载dll/Program.cs
|
@ -1,11 +1,118 @@
|
|||
namespace 加载dll
|
||||
using PluginBase;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using 加载dll;
|
||||
|
||||
namespace 加载Dll
|
||||
{
|
||||
internal class Program
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hello, World!");
|
||||
try
|
||||
{
|
||||
if (args.Length == 1 && args[0] == "/d")
|
||||
{
|
||||
Console.WriteLine("按下任何按钮开始运行...");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
// 从插件加载指令
|
||||
string[] pluginPaths = new string[]
|
||||
{
|
||||
"D:\\插件\\你好插件.dll",
|
||||
"C:\\Users\\misaka20001\\source\\repos\\加载dll\\你好插件\\bin\\Debug\\net6.0\\你好插件.dll"
|
||||
// Paths to plugins to load.
|
||||
// 这里填写需要加载插件的路径
|
||||
};
|
||||
|
||||
IEnumerable<ICommand> commands = pluginPaths.SelectMany(pluginPath =>
|
||||
{
|
||||
Assembly pluginAssembly = 加载插件(pluginPath);
|
||||
return 创建命令(pluginAssembly);
|
||||
}).ToList();
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
Console.WriteLine("命令: ");
|
||||
// 输出加载的命令.
|
||||
foreach (ICommand command in commands)
|
||||
{
|
||||
Console.WriteLine($"{command.名称}\t - {command.描述}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string commandName in args)
|
||||
{
|
||||
Console.WriteLine($"-- {commandName} --");
|
||||
|
||||
// Execute the command with the name passed as an argument.
|
||||
// 使用作为参数传递的名称执行命令
|
||||
ICommand? command = commands.FirstOrDefault(c => c.名称 == commandName);
|
||||
if (command == null)
|
||||
{
|
||||
Console.WriteLine("没有找到任何已知命令");
|
||||
return;
|
||||
}
|
||||
|
||||
command.执行();
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
static Assembly 加载插件(string 相对路径)
|
||||
{
|
||||
//throw new NotImplementedException();//未实现异常
|
||||
string? root = Path.GetFullPath(Path.Combine(
|
||||
Path.GetDirectoryName(
|
||||
Path.GetDirectoryName(
|
||||
Path.GetDirectoryName(
|
||||
Path.GetDirectoryName(
|
||||
Path.GetDirectoryName(path:typeof(Program).Assembly.Location)))))));
|
||||
|
||||
string pluginLocation = Path.GetFullPath(Path.Combine(root, 相对路径.Replace('\\', Path.DirectorySeparatorChar)));
|
||||
Console.WriteLine($"加载插件: {pluginLocation}");
|
||||
加载插件上下文 loadContext = new 加载插件上下文(pluginLocation);
|
||||
return loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));
|
||||
}
|
||||
|
||||
static IEnumerable<ICommand> 创建命令(Assembly 程序集)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
foreach (Type type in 程序集.GetTypes())
|
||||
{
|
||||
if (typeof(ICommand).IsAssignableFrom(type))
|
||||
{
|
||||
ICommand result = Activator.CreateInstance(type) as ICommand;
|
||||
if (result != null)
|
||||
{
|
||||
count++;
|
||||
yield return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
string availableTypes = string.Join(",", 程序集.GetTypes().Select(t => t.FullName));
|
||||
throw new ApplicationException(
|
||||
$"在{程序集.Location}的{程序集}中找不到实现了ICommand的任何可用类型\n"+
|
||||
$"可用类型: {availableTypes}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
61
加载dll/加载插件上下文.cs
Normal file
61
加载dll/加载插件上下文.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using 加载Dll;
|
||||
|
||||
namespace 加载dll
|
||||
{
|
||||
|
||||
class 加载插件上下文 : AssemblyLoadContext
|
||||
{
|
||||
private AssemblyDependencyResolver? _解析器;
|
||||
|
||||
public 加载插件上下文(string 插件路径)
|
||||
{
|
||||
_解析器 = new AssemblyDependencyResolver(插件路径);
|
||||
}
|
||||
|
||||
protected override Assembly? Load(AssemblyName 程序集名称)
|
||||
{
|
||||
string? 程序集路径 = _解析器?.ResolveAssemblyToPath(程序集名称);
|
||||
if (程序集路径 != null)
|
||||
{
|
||||
return LoadFromAssemblyPath(程序集路径);//从路径加载程序集
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override IntPtr LoadUnmanagedDll(string 非托管DLL名称)//重写加载非托管DLL方法
|
||||
{
|
||||
string? libraryPath = _解析器?.ResolveUnmanagedDllToPath(非托管DLL名称);//解析非托管类型DLL为路径
|
||||
if (libraryPath != null)
|
||||
{
|
||||
return LoadUnmanagedDllFromPath(libraryPath);//从路径加载程序集
|
||||
}
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
static Assembly LoadPlugin(string relativePath)
|
||||
{
|
||||
// Navigate up to the solution root
|
||||
string root = Path.GetFullPath(Path.Combine(
|
||||
Path.GetDirectoryName(
|
||||
Path.GetDirectoryName(
|
||||
Path.GetDirectoryName(
|
||||
Path.GetDirectoryName(
|
||||
Path.GetDirectoryName(typeof(Program).Assembly.Location)))))));
|
||||
|
||||
string pluginLocation = Path.GetFullPath(Path.Combine(root, relativePath.Replace('\\', Path.DirectorySeparatorChar)));
|
||||
Console.WriteLine($"Loading commands from: {pluginLocation}");
|
||||
加载插件上下文 loadContext = new 加载插件上下文(pluginLocation);
|
||||
return loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user