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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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