diff --git a/你好插件/你好命令.cs b/你好插件/你好命令.cs
new file mode 100644
index 0000000..add96e1
--- /dev/null
+++ b/你好插件/你好命令.cs
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/你好插件/你好插件.csproj b/你好插件/你好插件.csproj
new file mode 100644
index 0000000..f210ad1
--- /dev/null
+++ b/你好插件/你好插件.csproj
@@ -0,0 +1,16 @@
+
+
+
+ net6.0
+ enable
+ enable
+ true
+
+
+
+
+ False
+ runtime
+
+
+
diff --git a/加载dll.sln b/加载dll.sln
index e147808..530a927 100644
--- a/加载dll.sln
+++ b/加载dll.sln
@@ -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
diff --git a/加载dll/PluginBase.cs b/加载dll/PluginBase.cs
new file mode 100644
index 0000000..a478671
--- /dev/null
+++ b/加载dll/PluginBase.cs
@@ -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 执行();
+ }
+}
diff --git a/加载dll/Program.cs b/加载dll/Program.cs
index 636b8de..acbb35c 100644
--- a/加载dll/Program.cs
+++ b/加载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 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 创建命令(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}");
+ }
+ }
+
+
}
}
\ No newline at end of file
diff --git a/加载dll/加载插件上下文.cs b/加载dll/加载插件上下文.cs
new file mode 100644
index 0000000..3c6977d
--- /dev/null
+++ b/加载dll/加载插件上下文.cs
@@ -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)));
+ }
+ }
+
+}