[英]Embedding C# class libraries into an assembly and loading them dynamically
下午好,
我已经成功将C#类dll文件嵌入到我的应用程序中,可以通过以下方式将其打印出来:
Console.WriteLine(Assembly.GetExecutingAssembly()
.GetManifestResourceInfo("TestReferenceLib.dll").ResourceLocation);
但是,即使我这样加载它:
public static void Main(string[] args)
{
Console.WriteLine(Assembly.GetExecutingAssembly().GetManifestResourceInfo("TestReferenceLib.dll").ResourceLocation);
//This doesn't even fire
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler((o, e) =>
{
Console.WriteLine("Resolving?");
var memory = new MemoryStream();
Assembly.GetExecutingAssembly().GetManifestResourceStream(e.Name + ".dll").CopyTo(memory);
if(memory.Length > 0)
return Assembly.Load(memory.ToArray());
return null;
});
Console.WriteLine("Test assembly compiled and ran succesfully!");
//Pops errors
TestReferenceLib.TestReferenceLibrary.PrintOut();
}
标有注释“错误提示”的行显示:
FileNotFoundException:无法加载文件或程序集'TestReferenceLib,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其依赖项之一。 该系统找不到指定的文件。
我知道我可以通过使用Assembly.Load()返回的程序集来解决它。 并运行GetType(),GetMethod()和Invoke()使其运行-或使用ILMerge之类的工具或类似工具使其运行-但无需过多深入,对我来说至关重要的是不要使用任何外部工具。
通过“使用TestReferenceLib”的引用可以工作。
预先感谢您提供任何提示。
通过这小段代码,我设法将其列出在已加载的程序集中,但是执行仍然不起作用:
var memory = new MemoryStream();
Assembly.GetExecutingAssembly().GetManifestResourceStream("TestReferenceLib.dll").CopyTo(memory);
var assembly = AppDomain.CurrentDomain.Load(memory.ToArray());
foreach (var a in Assembly.GetExecutingAssembly().GetReferencedAssemblies())
{
Console.WriteLine(a.FullName);
}
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
Console.WriteLine(a.FullName);
}
您如何通过编译器将该调用推送到TestReferenceLib.TestReferenceLibrary
? 您未显示的地方是否有界面?
除此之外,有关解析程序集加载的MSDN文档指出,仅当您尝试按名称加载程序集时才调用AssemblyResolve
。
您没有在任何地方进行此操作,因此听起来像在调用TestReferenceLib
之前需要AppDomain.Load() , AppDomain.CreateInstance()或类似的TestReferenceLib
我找到了一个令人满意的解决方案,所以如果有人撞墙,就在这里。
如果要动态编译代码-需要引用类库的代码,这些类库又应作为资源嵌入到程序集中,请确保禁用GenerateInMemory并不要通过调用立即执行文件。
如果要(像我一样)编译一个程序集,然后立即执行它,将其生成为一个文件,创建一个AppDomain并在其中执行它,如下所示:
var assembly = Compiler.Create(files, references, resources, "TestAssembly.TestEntryPoint");
var domain = AppDomain.CreateDomain("ScriptDOM");
domain.ExecuteAssembly(assembly.Location);
这是编译器参数:
var parameters = new CompilerParameters();
parameters.ReferencedAssemblies.AddRange(references);
parameters.EmbeddedResources.AddRange(resources);
parameters.GenerateExecutable = true;
parameters.GenerateInMemory = false;
parameters.IncludeDebugInformation = true;
parameters.CompilerOptions = "/optimize";
parameters.MainClass = entryPoint;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.