[新增]第一版

This commit is contained in:
货 二 2023-02-28 12:23:33 +08:00
parent c8b39771a0
commit 49114b711e
6 changed files with 231 additions and 4 deletions

View 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;
}
}
}

View 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>

View File

@ -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
View 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 ();
}
}

View File

@ -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}");
}
}
}
}

View 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)));
}
}
}