C# 在Windows窗体中嵌入DLL(系统找不到指定的文件。)
我正在尝试将第三方DLL嵌入windows窗体。 可以找到第三方库(Dennis Magno-MetroFramework Modern UI) 如果我从存在MetroFramework DLL的bin文件夹运行应用程序,则一切正常。但是,我无法将它们嵌入到我的exe中 我尝试了很多事情:C# 在Windows窗体中嵌入DLL(系统找不到指定的文件。),c#,winforms,dll,embedded-resource,C#,Winforms,Dll,Embedded Resource,我正在尝试将第三方DLL嵌入windows窗体。 可以找到第三方库(Dennis Magno-MetroFramework Modern UI) 如果我从存在MetroFramework DLL的bin文件夹运行应用程序,则一切正常。但是,我无法将它们嵌入到我的exe中 我尝试了很多事情: 我遵循了以下步骤(手动将DLL设置为embedded 资源+代码处理程序) 我尝试使用Costura.Fodi(从Nuget安装) 我看了一眼 我在启动应用程序时总是遇到相同的错误: 无法加载文件或程序集“M
AppDomain.CurrentDomain.AssemblyResolve += (Object sender, ResolveEventArgs args) =>
{
String thisExe = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
System.Reflection.AssemblyName embeddedAssembly =
new System.Reflection.AssemblyName(args.Name);
String resourceName = thisExe + "." + embeddedAssembly.Name + ".dll";
using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return System.Reflection.Assembly.Load(assemblyData);
}
};
编辑1:
在评论为我指明了正确的方向之后,我将代码更改为如下所示:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
//Embed extra DLLs defined as 'embeddedResources' (MetroFramework)
AppDomain.CurrentDomain.AssemblyResolve += MyResolveEventHandler;
realMain();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void realMain()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
String thisExe = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
System.Reflection.AssemblyName embeddedAssembly =
new System.Reflection.AssemblyName(args.Name);
String resourceName = thisExe + ".libs." + embeddedAssembly.Name + ".dll";
// String resourceName = embeddedAssembly.Name + ".dll";
var debugStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames();
using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return System.Reflection.Assembly.Load(assemblyData);
}
}
}
静态类程序
{
///
///应用程序的主要入口点。
///
[状态线程]
静态void Main()
{
//嵌入定义为“嵌入资源”的额外DLL(MetroFramework)
AppDomain.CurrentDomain.AssemblyResolve+=MyResolveEventHandler;
realMain();
}
[MethodImpl(MethodImplOptions.noInLine)]
私有静态void realMain()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(新Form1());
}
公共静态程序集MyResolveEventHandler(对象发送方、ResolveEventArgs args args)
{
字符串thisExe=System.Reflection.Assembly.GetExecutionGassembly().GetName().Name;
System.Reflection.AssemblyName embeddedAssembly=
新的System.Reflection.AssemblyName(args.Name);
字符串resourceName=thisExe+“.libs.”+embeddedAssembly.Name+“.dll”;
//字符串resourceName=embeddedAssembly.Name+“.dll”;
var debugStream=System.Reflection.Assembly.getExecutionGassembly().GetManifestResourceStream(resourceName);
字符串[]名称=Assembly.getExecutionGassembly().GetManifestResourceNames();
使用(var stream=System.Reflection.Assembly.getExecutionGassembly().GetManifestResourceStream(resourceName))
{
Byte[]assemblyData=新字节[stream.Length];
读取(assemblyData,0,assemblyData.Length);
返回系统.Reflection.Assembly.Load(assemblyData);
}
}
}
先注册AssemblyResolve事件,然后从其他方法(realMain())调用其余代码,解决了这个问题
但是现在Models.Designer.cs抛出了相同的异常(我使用的是.NET3.5和EFV1)。以下代码现在导致异常:
public List<MyObj> selectGalLocation(string num)
{
using (My_Entities db = new My_Entities())
{
//some PCs may be used for more than one stage/station....
return db.MyObj.Include("L_Lookup").Include("P_DB").Where(x => x.no == num).ToList();
}
}
public List selectGalLocation(string num)
{
使用(My_Entities db=新建My_Entities())
{
//某些PC可用于多个阶段/站。。。。
返回db.MyObj.Include(“L_Lookup”).Include(“P_db”).Where(x=>x.no==num.ToList();
}
}
实际引发异常的代码是自动生成的:
public partial class CTRS_Entities : global::System.Data.Objects.ObjectContext
{
/// <summary>
/// Initializes a new My_Entities object using the connection string found in the 'My_Entities ' section of the application configuration file.
/// </summary>
public My_Entities() :
base("name=My_Entities ", "My_Entities ")
{
this.OnContextCreated();
}
公共部分类CTRS_实体:全局::System.Data.Objects.ObjectContext
{
///
///使用应用程序配置文件“My_Entities”部分中的连接字符串初始化新的My_Entities对象。
///
公共My_实体():
基本(“名称=我的实体”,“我的实体”)
{
this.OnContextCreated();
}
我不明白为什么这段代码,据我所知,它与MetroFramework无关,抛出异常。很明显,有些东西我没有正确理解
感谢您的帮助您是否检查了在使用程序集之前是否触发了
AssemblyResolve
事件?很可能您订阅了AssemblyResolve事件太晚了。必须在即时编译器需要程序集之前完成此操作。这是启动窗体使用metro framework时的问题,是的使用了Main()入口点。Chicken and egg。您只需订阅事件并调用添加的另一个方法,比如“RealMain”。为它指定[MethodImpl(MethodImplOptions.NoInLine)]属性,因此它在发布版本中仍然有效。@HansPassant:这应该是公认的答案。vendettamit,@HansPassant感谢您的评论,他们为我指出了正确的方向。只在Main()中订阅事件,并将其余代码放在RealMain()中方法解决了这个问题。但它导致了另一个问题。据我所知,程序集已加载,但当“真实代码”启动时,对EntityFramework的调用遇到了相同的错误,表示它找不到该文件。我可能会为此发布一个单独的问题。。。