windows 平臺、VS2019、x64
當C++編譯的動態庫提供給C#的開發人員時,需要實現一個C#的庫使用委託去呼叫C++動態庫。
當C#開發人員連結使用C#的動態庫時,如果沒有完全複製C++動態庫所依賴的其他動態庫時,就會出現執行報錯。
但是報錯時,不會提示缺少了什麼庫,這裡在C#的中增加一個函式,去檢測環境下缺少了什麼動態庫,便於排查問題。
實現
public class DynamicLibraryDetector
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern uint GetDllDirectory(uint nBufferLength, System.Text.StringBuilder lpBuffer);
private static readonly List<string> RequiredDlls = new List<string>
{
"yourLibrary1.dll",
"yourLibrary2.dll",
"yourLibrary3.dll",
// 新增所有依賴的 DLL 名稱
};
/// <summary>
/// Checks the existence of all required DLLs in the current working directory, DLL directory, and PATH environment variable.
/// Throws a DllNotFoundException if any required DLL is missing.
/// </summary>
/// <exception cref="DllNotFoundException">
/// Thrown if one or more required DLLs are not found.
/// </exception>
public static void Check()
{
List<string> missingDlls = new List<string>();
List<string> foundDlls = new List<string>();
// 獲取當前 DLL 目錄
string currentDllDirectory = GetCurrentDllDirectory();
foreach (var dll in RequiredDlls)
{
// 檢查當前工作目錄
if (File.Exists(dll))
{
foundDlls.Add(dll);
continue;
}
// 檢查當前 DLL 目錄
string fullPathInCurrentDir = Path.Combine(currentDllDirectory, dll);
if (File.Exists(fullPathInCurrentDir))
{
foundDlls.Add(dll);
continue;
}
// 檢查 PATH 環境變數中的所有路徑
string[] paths = Environment.GetEnvironmentVariable("PATH").Split(';');
bool foundInPath = false;
foreach (var path in paths)
{
string fullPath = Path.Combine(path, dll);
if (File.Exists(fullPath))
{
foundInPath = true;
foundDlls.Add(dll);
break;
}
}
if (!foundInPath)
{
missingDlls.Add(dll);
}
}
if (missingDlls.Count > 0)
{
throw new DllNotFoundException($"Missing DLL files: {string.Join(", ", missingDlls)}. Please make sure to copy them to the application directory or set the correct path in PATH. ");
}
}
private static string GetCurrentDllDirectory()
{
const int bufferSize = 1024;
var buffer = new System.Text.StringBuilder(bufferSize);
GetDllDirectory((uint)bufferSize, buffer);
return buffer.ToString();
}
}
使用
DynamicLibraryDetector.Check();