在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1 Mono 项目中有一个工具,mono的一个附属工具mkbundle。(在Xamarin未被收购开源前,它是加密的商业软件。http://www.cnblogs.com/binsys/archive/2012/11/29/2793903.html) 2 DNGuard 一款商业加密的工具
3 Fody 麻雀(马尔加什语言)项目以下是摘自院子里的文章。。把C#程序(含多个Dll)合并成一个Exe的超简单方法开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了。 但是,很多时候我们本想开发一款只需要一个exe就能完美运行的小工具。那该怎么办呢? 下文介绍一种超简单的方法,不用写一行代码就可轻松实现。 这里我们需要用到一款名为Fody.Costura的工具。Fody.Costura是一个Fody框架下的插件,可通过Nuget安装到VS工程中。安装之后,就可以将项目所依赖的DLL(甚至PDB)文件全部打包到EXE文件里。 使用方法
构建完成后,到项目的输出目录下找到新生成的EXE文件,你同时会发现输出目录下仍然存在那些DLL。不过不用担心,这个EXE已经能够独立运行了。你可以把这些DLL全部删除后再运行EXE试试。 另外,Fody.Costura还支持一些进阶的特性,例如:
以上这些进阶特性都需要你通过修改Fody.Costura的配置文件来实现,具体的操作步骤可以参考它的官方文档。 好了,Fody.Costura的使用方式已经介绍完了。如果你对Fody.Costura的实现原理感到好奇,可以接着往下看。
实现原理介绍当CLR试图加载一个程序集但加载失败时,它会引发AppDomain.AssemblyResolve事件。我们的程序可以监听这个事件,并且在这个事件的处理函数中返回这个CLR试图加载的程序集,从而使程序得以继续正常运行。 Fody.Costura在构建项目时会把EXE引用到的DLL全部嵌入到EXE文件中。当程序在运行的过程中用到其中某个DLL的时候(此时由于CLR无法找到该DLL文件,导致AppDomain.AssemblyResolve事件被触发)再从EXE文件的嵌入资源中提取所需的DLL。 下面这两个函数就是Fody.Costura实现这部分逻辑的代码。 1 public static void Attach() 2 { 3 var currentDomain = AppDomain.CurrentDomain; 4 currentDomain.AssemblyResolve += (s, e) => ResolveAssembly(e.Name); 5 } 6 public static Assembly ResolveAssembly(string assemblyName) 7 { 8 if (nullCache.ContainsKey(assemblyName)) 9 { 10 return null; 11 } 12 13 var requestedAssemblyName = new AssemblyName(assemblyName); 14 15 var assembly = Common.ReadExistingAssembly(requestedAssemblyName); 16 if (assembly != null) 17 { 18 return assembly; 19 } 20 21 Common.Log("Loading assembly '{0}' into the AppDomain", requestedAssemblyName); 22 23 assembly = Common.ReadFromEmbeddedResources(assemblyNames, symbolNames, requestedAssemblyName); 24 if (assembly == null) 25 { 26 nullCache.Add(assemblyName, true); 27 28 // Handles retargeted assemblies like PCL 29 if (requestedAssemblyName.Flags == AssemblyNameFlags.Retargetable) 30 { 31 assembly = Assembly.Load(requestedAssemblyName); 32 } 33 } 34 return assembly; 35 } 可以看到,Attach方法监听了AppDomain.AssemblyResolve事件。当CLR无法成功加载某个程序集时, AssemblyResolve事件处理函数会被执行。AssemblyResolve会尝试通过Common.ReadFromEmbeddedResources方法从已加载的程序集的嵌入资源中获取目标程序集,并返回给CLR。 看到这里,你可能会问,Attach方法是在什么时候执行的呢? 其实是这样的,对于C#语言来说,CLR隐藏了一个大招——CLR可以在每个模块(每个程序集都含有一个或多个模块)加载之前执行一些初始化的代码。但是很遗憾,C#语言无法控制这部分代码。Fody.Costura则是在内部将IL代码直接注入到EXE程序集内部模块的初始化函数中,而这部分IL代码其实就是执行了Attach方法。这样一来,EXE程序集被加载后,Attach方法就能够立即得到调用了。 以上就是Fody.Costura实现原理的简单介绍。 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了。 但是,很多时候我们本想开发一款只需要一个exe就能完美运行的小工具。那该怎么办呢? 下文介绍一种超简单的方法,不用写一行代码就可轻松实现。 这里我们需要用到一款名为Fody.Costura的工具。Fody.Costura是一个Fody框架下的插件,可通过Nuget安装到VS工程中。安装之后,就可以将项目所依赖的DLL(甚至PDB)文件全部打包到EXE文件里。 使用方法
构建完成后,到项目的输出目录下找到新生成的EXE文件,你同时会发现输出目录下仍然存在那些DLL。不过不用担心,这个EXE已经能够独立运行了。你可以把这些DLL全部删除后再运行EXE试试。 另外,Fody.Costura还支持一些进阶的特性,例如:
以上这些进阶特性都需要你通过修改Fody.Costura的配置文件来实现,具体的操作步骤可以参考它的官方文档。 好了,Fody.Costura的使用方式已经介绍完了。如果你对Fody.Costura的实现原理感到好奇,可以接着往下看。
实现原理介绍当CLR试图加载一个程序集但加载失败时,它会引发AppDomain.AssemblyResolve事件。我们的程序可以监听这个事件,并且在这个事件的处理函数中返回这个CLR试图加载的程序集,从而使程序得以继续正常运行。 Fody.Costura在构建项目时会把EXE引用到的DLL全部嵌入到EXE文件中。当程序在运行的过程中用到其中某个DLL的时候(此时由于CLR无法找到该DLL文件,导致AppDomain.AssemblyResolve事件被触发)再从EXE文件的嵌入资源中提取所需的DLL。 下面这两个函数就是Fody.Costura实现这部分逻辑的代码。 1 public static void Attach() 2 { 3 var currentDomain = AppDomain.CurrentDomain; 4 currentDomain.AssemblyResolve += (s, e) => ResolveAssembly(e.Name); 5 } 6 public static Assembly ResolveAssembly(string assemblyName) 7 { 8 if (nullCache.ContainsKey(assemblyName)) 9 { 10 return null; 11 } 12 13 var requestedAssemblyName = new AssemblyName(assemblyName); 14 15 var assembly = Common.ReadExistingAssembly(requestedAssemblyName); 16 if (assembly != null) 17 { 18 return assembly; 19 } 20 21 Common.Log("Loading assembly '{0}' into the AppDomain", requestedAssemblyName); 22 23 assembly = Common.ReadFromEmbeddedResources(assemblyNames, symbolNames, requestedAssemblyName); 24 if (assembly == null) 25 { 26 nullCache.Add(assemblyName, true); 27 28 // Handles retargeted assemblies like PCL 29 if (requestedAssemblyName.Flags == AssemblyNameFlags.Retargetable) 30 { 31 assembly = Assembly.Load(requestedAssemblyName); 32 } 33 } 34 return assembly; 35 } 可以看到,Attach方法监听了AppDomain.AssemblyResolve事件。当CLR无法成功加载某个程序集时, AssemblyResolve事件处理函数会被执行。AssemblyResolve会尝试通过Common.ReadFromEmbeddedResources方法从已加载的程序集的嵌入资源中获取目标程序集,并返回给CLR。 看到这里,你可能会问,Attach方法是在什么时候执行的呢? 其实是这样的,对于C#语言来说,CLR隐藏了一个大招——CLR可以在每个模块(每个程序集都含有一个或多个模块)加载之前执行一些初始化的代码。但是很遗憾,C#语言无法控制这部分代码。Fody.Costura则是在内部将IL代码直接注入到EXE程序集内部模块的初始化函数中,而这部分IL代码其实就是执行了Attach方法。这样一来,EXE程序集被加载后,Attach方法就能够立即得到调用了。 以上就是Fody.Costura实现原理的简单介绍。 |
请发表评论