将本机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和其他文件添加到.net exe

你不能直接做你想做的,你的dll必须是实际的文件。

但是,您可以将DLL从资源中提取到临时目录中,然后使用以下技术之一来影响DLL搜索:

  • 调用SetDefaultDllDirectories,至少调用LOAD_LIBRARY_SEARCH_USER_DIRSLOAD_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目录中的相关文件夹中,所以我的相对文件路径指向那里,一切都很好。

希望能有所帮助