我有一个.NET应用程序,它依赖于一个COM dll,它加载了Registry-Free激活(Side Side),然后通过P / Invoke访问。 COM DLL还需要一些数据库文件才能正常工作。
现在我正在尝试将所有文件合并到一个exe中,我不知道如何。
ILMerge和类似版本无法正常工作,因为COM dll是本机(非托管)。
可能的方法是将dll及其文件保存为嵌入式资源,并在启动时将它们写入文件系统。 (如对this Stackoverflow问题的答案)。
但是,我宁愿没有应用程序在启动时执行此操作。
有人知道如何轻松地将COM dll及其文件添加到应用程序中,然后通过免注册激活加载吗?
顺便说一下:显然我也可以单独注册COM dll(在注册表中),然后在应用程序中使用它,但是,这不是我的选择。答案 0 :(得分:1)
我这样做的方法是将DLL存储在项目中的路径中,并使用SetDllDirectory方法告诉我的应用程序在哪里查找DLL。
以下是我的例子:
PInvoke 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目录中的相关文件夹中,因此我的相对文件路径指向到那里,一切都很好。
希望这有帮助
答案 1 :(得分:1)
你不能直接做你想做的事,你的DLL必须是实际文件。
但是,您可以将资源中的DLL提取到临时目录中,然后使用以下某种方法来影响DLL search:
至少使用LOAD_LIBRARY_SEARCH_USER_DIRS
或LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
致电SetDefaultDllDirectories
,然后致电AddDllDirectory
将您的临时目录添加到DLL搜索路径
如果使用GetProcAddress
找不到以前的功能(例如,使用KB 2533623或SP1预Win7),请调用SetDllDirectory
将您的临时目录添加到DLL搜索路径< / p>
如果使用GetProcAddress
找不到上一个函数(例如pre-WinXP SP1),请将当前目录设置为临时目录(我不推荐这个目录)或者预先设置它到PATH
环境变量
我不建议更改当前目录的原因是因为某些DLL初始化可能由于某种原因捕获当前目录,并且它将是临时DLL目录而不是预期目录。
如果您还提取可执行文件,则将目录添加到PATH
可能会产生影响。
我之所以包含这个最后一个选项,是因为它适用于无法调用任意Win32函数的有限环境,但您可以更改PATH
环境变量或更改当前目录。