我遇到过这个问题太多次了,需要这是一个自动化的方法:
我有多个DLL文件,这些DLL文件经常被多个项目使用而构建/更改。
我创建了一个C#应用程序,用于检测DLL文件是否存在,如果不存在则会警告操作员并杀死程序。在这个C#应用程序中,我希望它也检查以确定它是否是“调试”版本 - 换句话说,如果它在最终用户计算机上运行它会崩溃。
现在我一直在寻找高低,并找到了一些可能的解决方案,但它们都落空了。
Assembly.LoadFrom(string)
不适用于非托管代码。我可以使用它来测试托管的DLL文件,而不是C ++文件。
我以为我可以使用Dependency Walker或类似的程序在我的应用程序中运行以向我提供程序集引用的数据,不幸的是,depends.exe
控制台只输出到文件(和那么我必须读入每个文件并解析它以获取我的数据(非常密集加上我必须在我的项目中包含depends.exe
和DLL文件)),此外,它似乎没有输出数据我真的很想(或至少我无法做到)。
还尝试了dumpbin,但我似乎无法让它在我的机器上运行。
我还发现了一些本应该给我Dependency Walker源代码的链接。不幸的是他们都死了。我不认为这是一件难以做到的事情,但无论出于何种原因,我都很难弄清楚如何实现自动化。
一些对我有帮助的源链接,但它们都没有解决非托管程序集数据的问题。
答案 0 :(得分:1)
如果您知道所有DLL的名称(例如,因为您运行了Dependency Walker),您可以使用LoadLibrary来检查非托管DLL。
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
const UInt32 DONT_RESOLVE_DLL_REFERENCES = 0x00000001;
const UInt32 LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
const UInt32 LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
[DllImport("kernel32.dll")]
static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll")]
static extern UInt32 GetLastError();
void CheckUnmanagedDll(string DllName)
{
IntPtr hModule = LoadLibrary(DllName);
if (hModule.Equals(IntPtr.Zero))
MessageBox.Show("Can't find " + DllName);
FreeLibrary(hModule);
}
答案 1 :(得分:1)
使用GetModuleHandle
检查是否存在具有给定名称的DLL。如果您想知道它是否是调试版本,那么您需要将该信息编译到EXE中并以某种方式检查它。 “调试”与“发布”不是PE格式内置的概念;它只是一组编译选项。许多人在版本信息中加上一个标记,表明它是内部还是公开发布。