修改协议加载方法

This commit is contained in:
2025-08-11 17:19:26 +08:00
parent 9085c3003a
commit f1c4100d53
3 changed files with 32 additions and 21 deletions

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -328,7 +328,7 @@ public partial class Form1 : Form
private void LoadProtocol()
{
Log.Info("开始加载协议");
_scriptLoader.LoadAndExecuteScriptsAsync(_config.ProtocolScriptPath);
_scriptLoader.LoadAndExecuteScripts(_config.ProtocolScriptPath);
Log.Succeed("加载协议完成");
CoderLoader.Load();
SetProtocolComboBox();

View File

@@ -1,22 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Threading.Tasks;
using FantasyNetTest;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using NBC;
public class ScriptLoader
{
public void LoadAndExecuteScriptsAsync(string folderPath)
private AssemblyLoadContext _lastContext;
public void LoadAndExecuteScripts(string folderPath)
{
// 1. 读取所有 .cs 文件
// 如果有旧的上下文,卸载它
if (_lastContext != null)
{
_lastContext.Unload();
_lastContext = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
var csFiles = Directory.GetFiles(folderPath, "*.cs", SearchOption.AllDirectories);
if (!csFiles.Any())
@@ -25,20 +29,20 @@ public class ScriptLoader
return;
}
// 2. 创建语法树
var syntaxTrees = csFiles.Select(file =>
CSharpSyntaxTree.ParseText(File.ReadAllText(file))
);
// 3. 引用程序集
var references = AppDomain.CurrentDomain.GetAssemblies()
.Where(a => !a.IsDynamic && !string.IsNullOrWhiteSpace(a.Location))
.Select(a => MetadataReference.CreateFromFile(a.Location))
.Cast<MetadataReference>();
// 4. 编译成内存程序集
// 每次给程序集一个唯一名字
string asmName = $"DynamicScripts_{Guid.NewGuid():N}";
var compilation = CSharpCompilation.Create(
assemblyName: "DynamicScripts",
assemblyName: asmName,
syntaxTrees: syntaxTrees,
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
@@ -54,14 +58,15 @@ public class ScriptLoader
return;
}
// 5. 加载程序集
ms.Seek(0, SeekOrigin.Begin);
var assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
// 6. 调用示例
var type = assembly.GetType("MyNamespace.MyClass"); // 你的类名
var method = type?.GetMethod("Run"); // 你的方法名
method?.Invoke(null, null); // 假设是静态方法无参数
// 用可卸载的 AssemblyLoadContext 加载
var alc = new AssemblyLoadContext(asmName, isCollectible: true);
var assembly = alc.LoadFromStream(ms);
_lastContext = alc;
var type = assembly.GetType("MyNamespace.MyClass");
var method = type?.GetMethod("Run");
method?.Invoke(null, null);
}
}
}