将本机dll和其他文件添加到.net exe
本文关键字:添加 net exe 文件 其他 本机 dll | 更新日期: 2023-09-27 18:17:00
我有一个. net应用程序,它依赖于加载了无注册表激活(并排)的COM dll,然后通过p/Invoke访问。COM dll还需要一些数据库文件才能正常工作。
现在我正试图将所有文件合并到一个exe中,但我不知道该怎么做。
ILMerge和类似的将不起作用,因为COM dll是本机(非托管)。
一种可能是将dll及其文件作为嵌入式资源保存,并在启动时将它们写入文件系统。(在这个Stackoverflow问题的答案中)。
但是,我不希望应用程序在启动时这样做。
有人知道如何轻松地将COM dll及其文件添加到应用程序,然后通过无注册表激活加载它吗?
Btw:显然我也可以单独注册COM dll(在注册表中),然后从应用程序中使用它,然而,这不是我的选择。
你不能直接做你想做的,你的dll必须是实际的文件。
但是,您可以将DLL从资源中提取到临时目录中,然后使用以下技术之一来影响DLL搜索:
-
调用
SetDefaultDllDirectories
,至少调用LOAD_LIBRARY_SEARCH_USER_DIRS
或LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
,然后调用AddDllDirectory
将您的临时目录添加到DLL搜索路径 -
如果你不能在
GetProcAddress
中找到以前的函数(例如,win7之前的KB 2533623或SP1),调用SetDllDirectory
将你的临时目录添加到DLL搜索路径 -
如果你不能在
GetProcAddress
中找到前面的功能(例如,winxp SP1之前),要么将当前目录设置为临时目录(我不推荐这个),要么将其添加到PATH
环境变量 中的目录列表中。
我不建议更改当前目录的原因是因为某些DLL初始化可能出于某种原因捕获当前目录,并且它将是临时的DLL目录而不是预期的目录。
如果您还解压缩可执行文件,则将目录添加到PATH
可能会产生其后果。
我包含最后一个选项的原因是因为它适用于有限的环境,您不能调用任意的Win32函数,但您可以更改PATH
环境变量或更改当前目录。
我这样做的方式是将DLL存储在项目内的路径中,并使用SetDllDirectory方法告诉我的应用程序在哪里查找DLL。
下面是我的例子:
PInvoke Signature for SetDllDirectory()
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
包含DllImport的类的构造函数
public ClassName()
{
var currentWorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
string path = Path.Combine(cwd, @"HereGoesYourRelativeFilepath");
SetDllDirectory(path);
}
在我的DLL的属性上,我将"复制到输出目录"属性设置为"始终复制",所以我知道它将始终在构建后的bin目录中的相关文件夹中,所以我的相对文件路径指向那里,一切都很好。
希望能有所帮助