mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-01 14:06:36 +08:00
忘记改啥了*1
This commit is contained in:
53
NodeFlow/Tool/FlowLibraryLoader.cs
Normal file
53
NodeFlow/Tool/FlowLibraryLoader.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Tool
|
||||
{
|
||||
/// <summary>
|
||||
/// 管理加载在流程的程序集
|
||||
/// </summary>
|
||||
public class FlowLibraryLoader : AssemblyLoadContext
|
||||
{
|
||||
private Assembly _pluginAssembly;
|
||||
|
||||
/// <summary>
|
||||
/// 加载程序集
|
||||
/// </summary>
|
||||
/// <param name="pluginPath"></param>
|
||||
public FlowLibraryLoader(string pluginPath) : base(isCollectible: true)
|
||||
{
|
||||
_pluginAssembly = LoadFromAssemblyPath(pluginPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保持默认加载行为
|
||||
/// </summary>
|
||||
/// <param name="assemblyName"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
protected override Assembly Load(AssemblyName assemblyName)
|
||||
{
|
||||
return null; // 保持默认加载行为
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否对程序集的引用
|
||||
/// </summary>
|
||||
public void UnloadPlugin()
|
||||
{
|
||||
_pluginAssembly = null; // 释放对程序集的引用
|
||||
Unload(); // 触发卸载
|
||||
// 强制进行垃圾回收,以便完成卸载
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
182
NodeFlow/Tool/NativeDllHelper.cs
Normal file
182
NodeFlow/Tool/NativeDllHelper.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.NodeFlow.Tool
|
||||
{
|
||||
|
||||
internal class NativeDllHelper
|
||||
{
|
||||
|
||||
// 引入 Windows API 函数
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr LoadLibrary(string lpFileName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool FreeLibrary(IntPtr hModule);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||
|
||||
|
||||
|
||||
// 引入 Unix/Linux 的动态库加载函数
|
||||
[DllImport("libdl.so.2", SetLastError = true)]
|
||||
private static extern IntPtr dlopen(string filename, int flag);
|
||||
|
||||
[DllImport("libdl.so.2", SetLastError = true)]
|
||||
private static extern IntPtr dlsym(IntPtr handle, string symbol);
|
||||
|
||||
[DllImport("libdl.so.2", SetLastError = true)]
|
||||
private static extern int dlclose(IntPtr handle);
|
||||
|
||||
private const int RTLD_NOW = 2;
|
||||
|
||||
// bool LoadDll(string file)
|
||||
// void LoadAllDll(string path, bool isRecurrence = true);
|
||||
|
||||
private static List<IntPtr> Nints = new List<nint>();
|
||||
|
||||
/// <summary>
|
||||
/// 加载单个Dll
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
public static bool LoadDll(string file)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return LoadWindowsLibrarie(file);
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return LoadLinuxLibrarie(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unsupported OS.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadAllDll(string path, bool isRecurrence = true)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(path, "*.dll"))
|
||||
{
|
||||
LoadWindowsLibrarie(file);
|
||||
}
|
||||
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(path, "*.so"))
|
||||
{
|
||||
LoadLinuxLibrarie(file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unsupported OS.");
|
||||
}
|
||||
|
||||
foreach (var dir in Directory.GetDirectories(path))
|
||||
{
|
||||
LoadAllDll(dir, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载Windows类库
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="isRecurrence">是否递归加载</param>
|
||||
private static bool LoadWindowsLibrarie(string file)
|
||||
{
|
||||
IntPtr hModule = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
hModule = LoadLibrary(file);
|
||||
// 加载 DLL
|
||||
if (hModule != IntPtr.Zero)
|
||||
{
|
||||
Nints.Add(hModule);
|
||||
Console.WriteLine($"Loaded: {file}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Failed to load {file}: {Marshal.GetLastWin32Error()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error loading {file}: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载Linux类库
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
private static bool LoadLinuxLibrarie(string file)
|
||||
{
|
||||
|
||||
IntPtr handle = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
handle = dlopen(file, RTLD_NOW);
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
Nints.Add(handle);
|
||||
Console.WriteLine($"Loaded: {file}");
|
||||
return true;
|
||||
// 可以调用共享库中的函数
|
||||
// IntPtr procAddress = dlsym(handle, "my_function");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Failed to load {file}: {Marshal.GetLastWin32Error()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error loading {file}: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 卸载所有已加载DLL
|
||||
/// </summary>
|
||||
public static void FreeLibrarys()
|
||||
{
|
||||
for (int i = 0; i < Nints.Count; i++)
|
||||
{
|
||||
IntPtr hModule = Nints[i];
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
Nints.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,11 +174,11 @@ public static class NodeMethodDetailsHelper
|
||||
ConvertorInstance[key] = (instance, convertMethod);
|
||||
}
|
||||
|
||||
Func<object, object> func = (enumValue) =>
|
||||
object func(object enumValue)
|
||||
{
|
||||
(var obj,var methodInfo) = ConvertorInstance[key];
|
||||
(var obj, var methodInfo) = ConvertorInstance[key];
|
||||
return methodInfo?.Invoke(obj, [enumValue]);
|
||||
};
|
||||
}
|
||||
// 确保实例实现了所需接口
|
||||
ParameterDetails ed = GetExplicitDataOfParameter(it, index, paremType, true, func);
|
||||
|
||||
@@ -206,26 +206,29 @@ public static class NodeMethodDetailsHelper
|
||||
}
|
||||
|
||||
private static ParameterDetails GetExplicitDataOfParameter(ParameterInfo parameterInfo,
|
||||
int index,
|
||||
Type paremType,
|
||||
bool isExplicitData,
|
||||
Func<object, object> func = null)
|
||||
int index,
|
||||
Type paremType,
|
||||
bool isExplicitData,
|
||||
Func<object, object> func = null)
|
||||
{
|
||||
|
||||
bool hasParams = parameterInfo.IsDefined(typeof(ParamArrayAttribute)); // 判断是否为可变参数
|
||||
|
||||
string explicitTypeName = GetExplicitTypeName(paremType);
|
||||
var items = GetExplicitItems(paremType, explicitTypeName);
|
||||
if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型
|
||||
return new ParameterDetails
|
||||
{
|
||||
IsExplicitData = isExplicitData, //attribute is null ? parameterInfo.HasDefaultValue : true,
|
||||
Index = index,
|
||||
ExplicitTypeName = explicitTypeName,
|
||||
ExplicitType = paremType,
|
||||
Convertor = func,
|
||||
DataType = parameterInfo.ParameterType,
|
||||
Index = index, // 索引
|
||||
ExplicitTypeName = explicitTypeName, // Select/Bool/Value
|
||||
ExplicitType = paremType,// 显示的入参类型
|
||||
Convertor = func, // 转换器
|
||||
DataType = parameterInfo.ParameterType, // 实际的入参类型
|
||||
Name = parameterInfo.Name,
|
||||
DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值
|
||||
Items = items.ToArray(), // 如果是枚举值入参,则获取枚举类型的字面量
|
||||
IsParams = hasParams, // 判断是否为可变参数
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user