c#项目将dll打包到exe中的步骤
程序员文章站
2022-04-05 12:05:25
意图:想将项目用到的两个dll库文件(cryptende.dll和icsharpcode.sharpziplib.dll)一同编译进exe中,并编译后仅一个exe程序就可以独立运行不再需要其它文件。实...
意图:
想将项目用到的两个dll库文件(cryptende.dll和icsharpcode.sharpziplib.dll)一同编译进exe中,并编译后仅一个exe程序就可以独立运行不再需要其它文件。
实现:
1、将两个dll库文件作为资源文件添加进项目中;
2、添加功能代码
using system; using system.collections.generic; using system.diagnostics; using system.reflection; using system.io; namespace autoupdateserver.core { /// <summary> 载入资源中的动态链接库(dll)文件 /// </summary> static class loadresourcedll { static dictionary<string, assembly> dlls = new dictionary<string, assembly>(); static dictionary<string, object> assemblies = new dictionary<string, object>(); static assembly assemblyresolve(object sender, resolveeventargs args) { //程序集 assembly ass; //获取加载失败的程序集的全名 var assname = new assemblyname(args.name).fullname; //判断dlls集合中是否有已加载的同名程序集 if (dlls.trygetvalue(assname, out ass) && ass != null) { dlls[assname] = null;//如果有则置空并返回 return ass; } else { throw new dllnotfoundexception(assname);//否则抛出加载失败的异常 } } /// <summary> 注册资源中的dll /// </summary> public static void registdll() { //获取调用者的程序集 var ass = new stacktrace(0).getframe(1).getmethod().module.assembly; //判断程序集是否已经处理 if (assemblies.containskey(ass.fullname)) { return; } //程序集加入已处理集合 assemblies.add(ass.fullname, null); //绑定程序集加载失败事件(这里我测试了,就算重复绑也是没关系的) appdomain.currentdomain.assemblyresolve += assemblyresolve; //获取所有资源文件文件名 var res = ass.getmanifestresourcenames(); foreach (var r in res) { //如果是dll,则加载 if (r.endswith(".dll", stringcomparison.ordinalignorecase)) { try { if (r.contains("cryptende.dll") || r.contains("cryptende_d.dll")) { extractresourcetofile(r, pathutils.getupdatedllpath() + @"/" + r.substring(r.indexof('.') + 1)); } var s = ass.getmanifestresourcestream(r); var bts = new byte[s.length]; s.read(bts, 0, (int)s.length); var da = assembly.load(bts); //判断是否已经加载 if (dlls.containskey(da.fullname)) { continue; } dlls[da.fullname] = da; } catch(exception e) { //加载失败就算了... } } } } private static void extractresourcetofile(string resourcename, string filename) { //if (!system.io.file.exists(filename)) { using (system.io.stream s = system.reflection.assembly.getexecutingassembly().getmanifestresourcestream(resourcename)) { using (system.io.filestream fs = new system.io.filestream(filename, system.io.filemode.create, fileaccess.readwrite, fileshare.readwrite)) { byte[] b = new byte[s.length]; s.read(b, 0, b.length); fs.write(b, 0, b.length); } } } } } }
其中pathutils.getupdatedllpath()函数为获取dll释放的路径,根据自己需要指定路径
public static string getupdatedllpath() { string strpath = @"c:/ltshiyi/cache/updatedll"; if (!directory.exists(strpath)) { directory.createdirectory(strpath); } return strpath; }
3、在程序入口program类中调用上面的接口函数
static program() { autoupdateserver.core.loadresourcedll.registdll(); }
4、编译即可。
以上就是c#项目将dll打包到exe中的步骤的详细内容,更多关于c# dll打包到exe的资料请关注其它相关文章!