永发信息网

c#如何把一个main()和若干个dll打包生成单一的exe文件?

答案:4  悬赏:0  手机版
解决时间 2021-04-02 03:35
c#如何把一个main()和若干个dll打包生成单一的exe文件?
最佳答案
开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了。
这里需要用到一款名为Fody.Costura的工具。Fody.Costura是一个Fody框架下的插件,可通过Nuget安装到VS工程中。安装之后,就可以将项目所依赖的DLL(甚至PDB)文件全部打包到EXE文件里。

使用方法
在VS中,通过Nuget为目标EXE工程安装Costura.Fody。
重新构建项目。
构建完成后,到项目的输出目录下找到新生成的EXE文件,你同时会发现输出目录下仍然存在那些DLL。不过不用担心,这个EXE已经能够独立运行了。你可以把这些DLL全部删除后再运行EXE试试。
另外,Fody.Costura还支持一些进阶的特性,例如:
临时程序集文件:在运行EXE前自动,自动将DLL从EXE中解压到文件夹系统中,再通过常规的方式加载该DLL。
合并非托管的DLL:Fody.Costura可以合并非托管的DLL,但是不会自动合。如果你的程序涉及非托管DLL,那么你需要通过修改Fody.Costura的配置文件来显示地告诉它你想合并哪些非托管的DLL。
预加载DLL:Fody.Costura可以帮助你在程序启动时预先加载某些DLL,甚至可以指定这些DLL的加载顺序。
以上这些进阶特性都需要你通过修改Fody.Costura的配置文件来实现,具体的操作步骤可以参考它的官方文档。

实现原理介绍
当CLR试图加载一个程序集但加载失败时,它会引发AppDomain.AssemblyResolve事件。我们的程序可以监听这个事件,并且在这个事件的处理函数中返回这个CLR试图加载的程序集,从而使程序得以继续正常运行。
Fody.Costura在构建项目时会把EXE引用到的DLL全部嵌入到EXE文件中。当程序在运行的过程中用到其中某个DLL的时候(此时由于CLR无法找到该DLL文件,导致AppDomain.AssemblyResolve事件被触发)再从EXE文件的嵌入资源中提取所需的DLL。
下面这两个函数就是Fody.Costura实现这部分逻辑的代码。
public static void Attach()
{
var currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += (s, e) => ResolveAssembly(e.Name);
}
public static Assembly ResolveAssembly(string assemblyName)
{
if (nullCache.ContainsKey(assemblyName))
{
return null;
}

var requestedAssemblyName = new AssemblyName(assemblyName);

var assembly = Common.ReadExistingAssembly(requestedAssemblyName);
if (assembly != null)
{
return assembly;
}

Common.Log("Loading assembly '{0}' into the AppDomain", requestedAssemblyName);

assembly = Common.ReadFromEmbeddedResources(assemblyNames, symbolNames, requestedAssemblyName);
if (assembly == null)
{
nullCache.Add(assemblyName, true);

// Handles retargeted assemblies like PCL
if (requestedAssemblyName.Flags == AssemblyNameFlags.Retargetable)
{
assembly = Assembly.Load(requestedAssemblyName);
}
}
return assembly;
}

可以看到,Attach方法监听了AppDomain.AssemblyResolve事件。当CLR无法成功加载某个程序集时, AssemblyResolve事件处理函数会被执行。AssemblyResolve会尝试通过Common.ReadFromEmbeddedResources方法从已加载的程序集的嵌入资源中获取目标程序集,并返回给CLR。
对于C#语言来说,CLR隐藏了一个大招——CLR可以在每个模块(每个程序集都含有一个或多个模块)加载之前执行一些初始化的代码。但是很遗憾,C#语言无法控制这部分代码。Fody.Costura则是在内部将IL代码直接注入到EXE程序集内部模块的初始化函数中,而这部分IL代码其实就是执行了Attach方法。这样一来,EXE程序集被加载后,Attach方法就能够立即得到调用了。
全部回答
把所有的代码放到一个命名空间中,也就是把所有代码放到一个项目里面。
有一种办法 你能搞到DLL里的代码 然后把代码放到你的程序里
如果不能搞到代码 那就去引用吧
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
长春至济南的铁路线长1375千米,
有真正一亿像素的手机吗
316L不锈钢能防酸吗,有什么补救措施
What is I?有语法错误吗
湖北省公安县南平镇2016到2017高二学年统一考
发现杠杆定律和浮力定律的古希腊著名科学家是
怎样替别人求姻缘
种植柑橘的地形条件
华东南西北中的区域分类
形容“堤岸”的词语有哪些?
手机内存卡格式化后格式为raw,怎么变回FAT格
辩论赛,孩子是生的亲还是养的亲。我们的观点
良好的个人形象对工作有什么作用?
遵义忠庄客运站怎么去啊,有知道地址的么
it happy to the monday什么歌
推荐资讯
经度的最大范围是A.东西经各90°B.东西经各18
新疆酱香炒米粉做法 每次吃阿臻的米粉都好好
大连面积多大,有北京大吗?
在如图所示的四张图中,AB、BC均为轻质杆,各
帮忙用T、H、S、Y四个字母设计一个企业标识
宝丽来拍立得怎么用
说电脑是测试机是什么意思呀
为什么说网站可以靠流量赚钱?谁给他钱?
顺丰与江南嘉捷是一个法律顾问吗
我确诊是阳性,疾控中心打电话让我去疾控中心
买卖公有住房有限制吗
明明不爱学习,请你送他一句有关学习的名言
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?