c#反射动态加载EXE程序问题

c#反射动态加载EXE程序问题,第1张

Thunderexe

不是net程序

不能用这种办法加载

真要加载的话

首先要这个文件不是加密的

然后它的接口方法要是开放的

然后你要知道他的入口方法和地址

然后可以使用调用native库的办法调用

您可以使用 Gacutilexe 将强名称程序集添加到全局程序集缓存,并查看全局程序集缓存的内容。

注意Gacutilexe 只用于开发,不应用于将产品程序集安装到全局程序集缓存中。

使用 Microsoft Windows Installer 20。

这是将程序集添加到全局程序集缓存的最常用方法,建议采用。此安装程序可提供全局程序集缓存中程序集的引用计数,还具有其他优点。

使用 NET Framework SDK 提供的名为

程序集缓存查看器 (Shfusiondll)

VS自己有这个功能

新建项目里选"安装和部署",然后把你的EXE文件添加进去,打包就可以了

最后生成安装包,包括Setupexe和你的项目名字msi

安装时候可以自动检测是否有net framework,没有的话它会自动连接微软网站下载

开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了。

这里需要用到一款名为FodyCostura的工具。FodyCostura是一个Fody框架下的插件,可通过Nuget安装到VS工程中。安装之后,就可以将项目所依赖的DLL(甚至PDB)文件全部打包到EXE文件里。

使用方法

在VS中,通过Nuget为目标EXE工程安装CosturaFody。

重新构建项目。

构建完成后,到项目的输出目录下找到新生成的EXE文件,你同时会发现输出目录下仍然存在那些DLL。不过不用担心,这个EXE已经能够独立运行了。你可以把这些DLL全部删除后再运行EXE试试。

另外,FodyCostura还支持一些进阶的特性,例如:

临时程序集文件:在运行EXE前自动,自动将DLL从EXE中解压到文件夹系统中,再通过常规的方式加载该DLL。

合并非托管的DLL:FodyCostura可以合并非托管的DLL,但是不会自动合。如果你的程序涉及非托管DLL,那么你需要通过修改FodyCostura的配置文件来显示地告诉它你想合并哪些非托管的DLL。

预加载DLL:FodyCostura可以帮助你在程序启动时预先加载某些DLL,甚至可以指定这些DLL的加载顺序。

以上这些进阶特性都需要你通过修改FodyCostura的配置文件来实现,具体的 *** 作步骤可以参考它的官方文档。

实现原理介绍

当CLR试图加载一个程序集但加载失败时,它会引发AppDomainAssemblyResolve事件。我们的程序可以监听这个事件,并且在这个事件的处理函数中返回这个CLR试图加载的程序集,从而使程序得以继续正常运行。

FodyCostura在构建项目时会把EXE引用到的DLL全部嵌入到EXE文件中。当程序在运行的过程中用到其中某个DLL的时候(此时由于CLR无法找到该DLL文件,导致AppDomainAssemblyResolve事件被触发)再从EXE文件的嵌入资源中提取所需的DLL。

下面这两个函数就是FodyCostura实现这部分逻辑的代码。

public static void Attach()

{

var currentDomain = AppDomainCurrentDomain;

currentDomainAssemblyResolve += (s, e) => ResolveAssembly(eName);

}

public static Assembly ResolveAssembly(string assemblyName)

{

if (nullCacheContainsKey(assemblyName))

{

return null;

}

var requestedAssemblyName = new AssemblyName(assemblyName);

var assembly = CommonReadExistingAssembly(requestedAssemblyName);

if (assembly != null)

{

return assembly;

}

CommonLog("Loading assembly '{0}' into the AppDomain", requestedAssemblyName);

assembly = CommonReadFromEmbeddedResources(assemblyNames, symbolNames, requestedAssemblyName);

if (assembly == null)

{

nullCacheAdd(assemblyName, true);

// Handles retargeted assemblies like PCL

if (requestedAssemblyNameFlags == AssemblyNameFlagsRetargetable)

{

assembly = AssemblyLoad(requestedAssemblyName);

}

}

return assembly;

}

可以看到,Attach方法监听了AppDomainAssemblyResolve事件。当CLR无法成功加载某个程序集时, AssemblyResolve事件处理函数会被执行。AssemblyResolve会尝试通过CommonReadFromEmbeddedResources方法从已加载的程序集的嵌入资源中获取目标程序集,并返回给CLR。

对于C#语言来说,CLR隐藏了一个大招——CLR可以在每个模块(每个程序集都含有一个或多个模块)加载之前执行一些初始化的代码。但是很遗憾,C#语言无法控制这部分代码。FodyCostura则是在内部将IL代码直接注入到EXE程序集内部模块的初始化函数中,而这部分IL代码其实就是执行了Attach方法。这样一来,EXE程序集被加载后,Attach方法就能够立即得到调用了。

那个dll大概不是程序集,应该是c++的东西,不能被Reflector解析的一般都不是程序集;

exe、dll都是程序集,只不过exe有入口而已,exe也可以被添加引用。dll不一定是程序集(VC写的dll就不是程序集),程序集不一定是dll(net写的EXE也是程序集)。()托管(Managed)代码(MSIL)。非托管。

一个模块就是一个标准的让CLR执行的32位(PE32)或者64(PE64)位的windows的可执行文件。然而CLR事实上并不是模块打交道,而是直接和程序集打交道。程序集是个抽象的概念,一个程序集是由一个或者多个模块或者资源文件在逻辑上组合而成的文件,程序集对CLR来说是最小的可重用的单元。

以上就是关于c#反射动态加载EXE程序问题全部的内容,包括:c#反射动态加载EXE程序问题、如何将程序集安装到全局程序集缓存中、.net做的程序如何将程序集和.net框架打包成一个exe程序,执行exe时就能自动判断是否安装.net框架等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10073201.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存