我们需要构建某些.EXE以不具有任何外部依赖性 - 不需要安装其他DLL,或者app.config文件等。我们想要一个可以简单地删除的.EXE进入路径中的目录,然后工作。
在.NET中哪个不容易。特别是当这些.EXE依赖于我们自己的共享库时。
在当天,我们已经静态链接了这些应用。这在.NET中是不可能的。
因此,我们正在做的是将依赖的DLL嵌入到.EXE中作为嵌入式资源,并挂钩一个从嵌入式资源加载程序集的ResolveEventHandler:
public class AssemblyResolver
{
static AssemblyResolver()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver);
}
static Assembly Resolver(object sender, ResolveEventArgs args)
{
string prefix = "MyNamespace.DLLs.{0}.dll";
var assemblyName = new AssemblyName(args.Name);
var name = String.Format(prefix, assemblyName.Name);
var a1 = Assembly.GetExecutingAssembly();
var s = a1.GetManifestResourceStream(name);
var block = new byte[s.Length];
s.Read(block, 0, block.Length);
var a2 = Assembly.Load(block);
return a2;
}
}
如果我们可以将DLL的副本放入项目的DLLs文件夹中,那就可以了。对于第三方DLL,这很容易做到。但是对我们自己的DLL这样做更复杂。每次我们构建解决方案时都会重建这些内容,并且我们需要嵌入在.EXE中的最新版本。
我们一直在做的是创建一个在构建项目之前复制DLL的预构建事件。从Visual Studio可以正常工作。但是,通过从命令行运行msbuild来构建项目时,它不起作用。当从命令行运行时,msbuild会在构建任何依赖项目之前触发预构建事件,这太早了 - 我们尝试复制的DLL不存在,爱好。
那么,我该怎么办?