将库嵌入我的应用程序并使其使用该库
Embed an library into my application and make it use that library
我希望我的可执行文件是我的程序运行所需的唯一东西,但它依赖于一个库,更具体地说 MySql.Data.dll。我如何将这个库合并到我的可执行文件中?
我已将 DLL 拖到我的项目资源管理器中。此外,我后来选择了它并将其 Build Action
设置为 Embedded Resource
然而,当我在我的应用程序中尝试打开一个新文件时,我仍然面临 FileNotFound 异常 window:
'System.IO.FileNotFoundException' 类型的未处理异常发生在 PresentationFramework.dll
附加信息:无法加载文件或程序集 'MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d' 或其依赖项之一。系统找不到指定的文件。
编辑:
这与使用 WinForms 时有什么不同吗?我之前一直在使用 WinForms 应用程序进行此操作,其中我使用了 ioniczip 和 json 库,我将其作为嵌入式资源包含在内。这样我就不需要在应用程序中包含这两个 DLL 文件。
通常您需要将所有依赖项复制到您的 PATH 环境变量中指定的文件夹或将它们放在您的可执行文件的同一文件夹中。您可能会发现这篇文章很有帮助 Search Path Used by Windows to Locate a DLL
如果你想捆绑 dll,你可以查看 "ILMerge"。
至于像'System.IO.FileNotFoundException'或'System.IO.BadImageException'这样的一般错误,您可以尝试使用"Dependency Walker"找出缺少的dll。
您不能使用嵌入式资源来分发库。你需要像 ILMerge 这样的东西。
参见 http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx
我找到了另一个解决方案。将 DLL 文件作为资源添加到项目中,然后我将其添加到 App.xaml.cs
public App()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");
dllName = dllName.Replace(".", "_");
if (dllName.EndsWith("_resources"))
return null;
System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
byte[] bytes = (byte[])rm.GetObject(dllName);
return System.Reflection.Assembly.Load(bytes);
}
这似乎对我有用。我在一个旧项目中找到了它,我在那里需要同样的东西(只是忘了它)
我希望我的可执行文件是我的程序运行所需的唯一东西,但它依赖于一个库,更具体地说 MySql.Data.dll。我如何将这个库合并到我的可执行文件中?
我已将 DLL 拖到我的项目资源管理器中。此外,我后来选择了它并将其 Build Action
设置为 Embedded Resource
然而,当我在我的应用程序中尝试打开一个新文件时,我仍然面临 FileNotFound 异常 window:
'System.IO.FileNotFoundException' 类型的未处理异常发生在 PresentationFramework.dll
附加信息:无法加载文件或程序集 'MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d' 或其依赖项之一。系统找不到指定的文件。
编辑:
这与使用 WinForms 时有什么不同吗?我之前一直在使用 WinForms 应用程序进行此操作,其中我使用了 ioniczip 和 json 库,我将其作为嵌入式资源包含在内。这样我就不需要在应用程序中包含这两个 DLL 文件。
通常您需要将所有依赖项复制到您的 PATH 环境变量中指定的文件夹或将它们放在您的可执行文件的同一文件夹中。您可能会发现这篇文章很有帮助 Search Path Used by Windows to Locate a DLL
如果你想捆绑 dll,你可以查看 "ILMerge"。
至于像'System.IO.FileNotFoundException'或'System.IO.BadImageException'这样的一般错误,您可以尝试使用"Dependency Walker"找出缺少的dll。
您不能使用嵌入式资源来分发库。你需要像 ILMerge 这样的东西。 参见 http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx
我找到了另一个解决方案。将 DLL 文件作为资源添加到项目中,然后我将其添加到 App.xaml.cs
public App()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");
dllName = dllName.Replace(".", "_");
if (dllName.EndsWith("_resources"))
return null;
System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
byte[] bytes = (byte[])rm.GetObject(dllName);
return System.Reflection.Assembly.Load(bytes);
}
这似乎对我有用。我在一个旧项目中找到了它,我在那里需要同样的东西(只是忘了它)