You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/UCDraw/GeoSigmaDrawLib/NativeLibraryPathRegistrar.cs

96 lines
3.2 KiB
C#

1 month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace GeoSigmaDrawLib
{
/// <summary>
/// 负责为本应用程序注册本地原生库DLL的搜索路径。
/// 此类不加载任何 DLL仅通过 Windows API 设置系统搜索目录,
/// 确保后续通过 P/Invoke 或 DllImport 加载的库能被正确找到。
///
/// 注意:必须在首次调用任何 GeoSigmaLib 的 P/Invoke 方法前调用此方法。
/// </summary>
public static class NativeLibraryPathRegistrar
{
private const string VtkDirectory = "vtk";
private const string ThirdPartyDirectory = "thirdparty";
private const string EnvPath = "PATH";
/// <summary>
/// 注册三方库目录
/// </summary>
public static void Register()
{
var baseDirectory = GetExecutableDirectory();
AddToEnvironmentPath(Path.Combine(baseDirectory, VtkDirectory));
AddToEnvironmentPath(Path.Combine(baseDirectory, ThirdPartyDirectory));
}
/// <summary>
/// 添加目录到 Path 环境变量中
/// </summary>
/// <param name="directory">要添加的目录名,建议使用绝对路径</param>
public static void AddToEnvironmentPath(string directory)
{
if (string.IsNullOrWhiteSpace(directory))
{
return;
}
string? current = Environment.GetEnvironmentVariable(EnvPath);
string newPath = AppendToPath(current, directory);
Environment.SetEnvironmentVariable(EnvPath, newPath);
}
public static string GetExecutableDirectory()
{
var executablePath = Process.GetCurrentProcess().MainModule?.FileName;
if (string.IsNullOrEmpty(executablePath))
{
throw new InvalidOperationException("无法获取当前进程的可执行文件路径。");
}
if(string.IsNullOrWhiteSpace(executablePath))
{
executablePath = AppDomain.CurrentDomain.BaseDirectory;
return executablePath;
}
return Path.GetDirectoryName(executablePath) ?? throw new InvalidOperationException("可执行文件路径无效。");
}
private static string AppendToPath(string? current, string directory)
{
if (string.IsNullOrWhiteSpace(directory))
{
return current ?? string.Empty;
}
if (string.IsNullOrWhiteSpace(current))
{
return directory;
}
char pathSeparator = Path.PathSeparator;
var pathEntries = current.Split(pathSeparator)
.Where(p => !string.IsNullOrWhiteSpace(p)) // 过滤空项
.ToList();
if (pathEntries.Contains(directory, StringComparer.OrdinalIgnoreCase))
{
return current;
}
pathEntries.Add(directory);
return string.Join(pathSeparator, pathEntries);
}
}
}