首页 > 编程知识 正文

安卓manifest文件路径(manifest文件添加第三方包)

时间:2023-05-03 12:39:35 阅读:75580 作者:1163

(回之) 3358 hi.Baidu.com/y 97523/blog/item/e F5 a73 f 0339050 a5 a 40 f 5281.html

为了让大家容易理解,我会尽量简单地说明。[现象]

该问题的研究源于jydwt用VC 2005 (或其他. NET )编写程序后,在自己的计算机上可以正常运行,但将此exe文件复制到他人的计算机上时无法运行的现象。 APP应用程序配置不正确,请重新安装程序……或MSVCR80D.dll中不存在大致的错误消息

看到这样的提示,当然还没傻到重装啊。 第一个反应应该是什么配置有问题或缺少什么依赖关系的库文件; 于是我根据以前Windows库文件不足的经验,把所有库文件(.DLL )都复制到当前文件夹中,很乐意运行……@#@#%……还是[分析]

于是我开始上网搜索。 谷歌,我过了; 我们发现这一切都与一个称为*.manifest类型的文件有关。 那么, manifest文件是什么? 他有什么用,以前怎么没做?

后来,费了很大劲,我才知道这一切都是Windows组件管理器搞的鬼。 这个东东的作用是为了解决以前windows上的“Dll地狱”问题而产生的新的Dll管理解决方案。 众所周知,Dll是一个动态负载共享库,同一Dll可能被多个程序使用。 “Dll地狱”是指,即使与程序无关的Dll相同,但如果版本不同,则无法识别系统是哪个,因此会错误地加载并锁定Dll版本。 于是tsdcs吸取了教训,做了汇编清单的东东。 每个程序都需要一个列表。 此列表存储在与您的APP应用程序同名的. manifest文件中,并列出所需的所有依存关系。 此处列出的依存关系不是简单地用文件名区分,而是用称为“强文件名”的东西区分。 那么,什么是强文件名呢? 看看这个. manifest文件。

? XML版本=' 1.0 '编码=' utf-8 '标准版='是'?

assembly xmlns=' urn :方案- Microsoft-com : ASM.v1 ' manifest version=' 1.0 '

从属关系

从属组件

assemblyidentitytype=' win32 ' name=' Microsoft.vc80.CRT ' version='8.0. 50608.0 '处理器架构=' xxitecture

/从属组件

/从属

/assembly

这原本是一个XML格式的文件,表示名为dependency的部分依赖于名为Microsoft.VC80.CRT的库。 但是,assemblyIdentity属性还有其他东东,分别是

type系统类型、版本号、processorArchitecture平台环境、公共密钥令牌公匙……这些加起来就是“强文件名”。 有了这个“强文件名”,可以区分各个版本和差异[探索]

好的,那么我们来具体看看这个机制吧。

首先是强弱文件名的问题。 如上所述,为了区分不同版本或不同供应商生成的同一程序集,必须使用Assembly Manifest程序列表列出名为我的程序集的强文件名。 请等一下。 我来这里不是说“组件管理程序列表是列出依赖程序集的强文件名吗? 为什么这里成为了现在文件的强文件名呢? ”。 实际上,Assembly Manifest程序列表有两个功能。 在上面的示例中,依赖文件之所以具有强文件名,是因为客户端的Assembly Manifest和服务端具有不同的Manifest。

? XML版本=' 1.0 '编码=' utf-8 '标准版='是'?

assembly xmlns=' urn :方案- Microsoft-com : ASM.v1 ' manifest version=' 1.0 '

no不可用/不可用

assemblyidentitytype=' win32 ' name=' Microsoft

.VC80.CRT" version="8.0.50727.42" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
<file name="msvcr80.dll" hash="2a0d797a8c5eac76e54e98db9682e0938c614b45" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>phRUExlAeZ8BwmlD8VlO5udAnRE=</dsig:DigestValue></asmv2:hash></file>
<file name="msvcp80.dll" hash="cc4ca55fb6aa6b7bb8577ab4b649ab77e42f8f91" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>7AY1JqoUvK3u/6bYWbOagGgAFbc=</dsig:DigestValue></asmv2:hash></file>
<file name="msvcm80.dll" hash="55e8e87bbde00d1d96cc119ccd94e0c02c9a2768" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>hWq8crdyg6bnv4hEOw=</dsig:DigestValue></asmv2:hash></file>
</assembly>



这个便是从WINDOWSWinSxSManifests目录下取出来的一个manifest文件,再这个文件夹下有一陀子这种XML格式的manifest文件,其是服务端的程序清单。WinSxs是windows XP以上版本提供的[blue]非托管并行缓存(side-by-side catche)[/blue]里面安装了各种版本的经过强文件名签名的系统库,而上面这个文件<assemblyIdentity>正是标注了系统中Microsoft.VC80.CRT的一个版本的强文件名签名,如果其和客户端。.manifest 清单里面<dependentAssembly>所列出的依赖项对上的话,就会被加载。刚才说的side-by-side 是指各种不同的版本并行运行。
上面这个服务端manifest文件中<file>标签具体指明了当前强文件名签名的到底是哪一个文件,其中还有这个文件的Hash签名,以确保文件的完整性。

好了,有了这一套机制,就可以非常非常安全地进行库文件关联了,但是、但是貌似还有一个一直困扰我们的问题:这套机制安全是安全了,但是却失去了以前良好的前后版本兼容性,即如果你的系统库发生了升级,那么服务端的版本号发生了变化,那岂不是所有服务端程序都不能使用了吗?其实,windows还使用一个policy的策略文件来确认映射关系。


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright ? 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity type="win32-policy" name="policy.8.0.Microsoft.VC80.CRT" version="8.0.50727.42" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<bindingRedirect oldVersion="8.0.41204.256-8.0.50608.0" newVersion="8.0.50727.42"/>

</dependentAssembly>
</dependency>

</assembly>


这便是在WINDOWSWinSxSPolicies目录下的一个Policy文件,其中<bindingRedirect>标签便指定了所有8.0.41204.256-8.0.50608.0变本的客户需求映射到8.0.50727.42这个我现在系统中安装的比较新的版本的库。当然我们也能对别的字段进行映射,这样便能很好解决系统升级带来的问题。

[应用]
经过以上的讲解,大家对整个依赖查找过程都有了一个整体的认识,那么在实际中问题就好解决了。
让我们回到实际问题中,我之前说了,把一个程序编译连接成可执行程序后,在别人的电脑上发现找不到其所依赖的库了,那么怎么办呢?聪明的你自然想到把其所依赖的库相应的版本拷贝到目标计算机上面,可是……jydwt在拼命寻找那个可执行文件的assembly manifests文件的时候,却突然发现找不到了,在执行目录下面明明只有一个exe文件嘛。是不是没有生成呢?显然不会,原来是资源连接器把那个assembly manifests文件连接到了可执行文件里面了;不信,你可以用你的vc++打开一个可执行文件看看,在其资源项里面就有一个叫做RT_MANIFEST的项目。这个里面就是二进制标示的manifests文件。那么根据这里面提供的要求,将相应版本的依赖文件(一般就是CRT运行库)拷贝到系统目录WindowsWinSxS,记住一般会是连带着一个特殊命名的目录一起拷贝到那个文件夹下,比如CRT的运行库就是WinSxSx86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50608.0_x-ww_b7acac55有这样一个目录,其标注了此库的版本号以及签名等信息,以防止多个版本重名时不能复制到同一WinSxS目录下。

这样就搞定了么?如果是以前,那么一切都解决了,系统会在这个目录下面找到这个运行库,可是现在单单这样可不行,系统可是要找到这个运行库的assembly manifests文件,并且对比强文件名之后才能加载,所以所以千万别忘了把相应的manifests文件拷贝到WinSxSManifests目录下面。

当然,这样在目标的系统文件夹下面打动干戈,自然有些过于暴动了,还好,Windows还为我们提供了一种私有查找方式。这种方式会在前面的位置找不到合适库的时候在本地文件夹下面找。所以你只要把之前的库以及那个manifests文件一起拷贝到你的应用程序的路径下面,就可以使用啦。

根据MSDN的说明,在本地查找并加载遵循一下规则:


在应用程序本地文件夹中查找名为 <assemblyName>.manifest 的清单文件。在此示例中,加载程序试图在 appl.exe 所在的文件夹中查找 Microsoft.VC80.CRT.manifest。如果找到该清单,加载程序将从应用程序文件夹中加载 CRT DLL。如果未找到 CRT DLL,加载将失败。

尝试在 appl.exe 本地文件夹中打开文件夹 <assemblyName>,如果存在此文件夹,则从中加载清单文件 <assemblyName>.manifest。如果找到该清单,加载程序将从 <assemblyName> 文件夹中加载 CRT DLL。如果未找到 CRT DLL,加载将失败。



最后,我想补充的一点是,在你的VC++安装目录下面的“Microsoft Visual Studio 8VCredist”目录下,有着所有的提供发布的已经配备相应.manifest的库文件。所以你想要发布一个程序最简单最安全的做法(不用担心用户电脑是否包含你所需要的库)就是把这个目录下面的相应的库的文件夹和你的可执行文件放在一起发布。
比如在X86平台下如果你的可执行文件用到了CRT库(废话么),那么就拷贝Microsoft Visual Studio 8VCredistx86Microsoft.VC80.CRT这个文件夹到你的程序所在的目录,一起发布,就万事大吉啦!

转载于:https://www.cnblogs.com/gamesky/archive/2012/08/13/2636310.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。