使用manifest管理應(yīng)用程序的依賴文件

1. 寫在前面的話

我們在開發(fā)應(yīng)用程序時陡鹃,一般會引入一些第三方庫冀痕,通常情況下台谍,我們是把這些第三方依賴文件放到應(yīng)用程序所處目錄沛励,這樣應(yīng)用程序啟動時就能正確找到相關(guān)依賴文件甩挫。但當依賴文件比較多贴硫,我們希望對依賴的文件進行歸類,放置到不同的目錄下以便管理伊者,這個時候應(yīng)用程序的manifest就派上用場了英遭。

2. 并行程序集(Side-by-Side Assembly)

在介紹應(yīng)用程序的manifest之前,需要了解一下并行程序集(Side-by-Side Assembly)亦渗。什么是并行程序集呢? 并行程序集是微軟為了解決DLL Hell問題而提出的一種解決方案挖诸,它采用manifest文件掃描組件之間的依賴關(guān)系。其工作原理如下圖所求:

簡單說明一下法精,微軟在未提出Side-by-Side Assembly之前多律,應(yīng)用程序啟動時按照一定的規(guī)則加載DLL痴突。通常情況下,應(yīng)用程序會采用動態(tài)鏈接方式共享一些操作系統(tǒng)提供的基礎(chǔ)庫文件狼荞,當Windows更新共享庫且共享庫不能向后兼容時(DLL自身并不能向后兼容辽装,這種情況通常發(fā)生在DLL的內(nèi)存布局發(fā)生了改變),那些依賴于老版本共享庫的應(yīng)用程序就不能正常工作了。為了解決這個問題相味,微軟重寫了DLL動態(tài)加載子系統(tǒng)拾积,提出了并行程序集的解決方案,即允許多個版本的庫共同存在攻走,應(yīng)用程序通過manifest描述自身所依賴的文件殷勘,SxS Manager再通過manifest按照一定的規(guī)則找到應(yīng)用程序的依賴文件,使應(yīng)用程序正確工作昔搂。

3. 程序集查找順序

和DLL加載順序類似玲销,SxS Manager在查找應(yīng)用程序的依賴程序集時也按照一定的規(guī)則進行查找。一般情況下摘符,其查找規(guī)則如下贤斜,如果應(yīng)用程序需要多語言支持,請參考這里逛裤。

  1. Side-by-side searches the WinSxS folder.
  2. \\<appdir>\<assemblyname>.DLL
  3. \\<appdir>\<assemblyname>.manifest
  4. \\<appdir>\<assemblyname>\<assemblyname>.DLL
  5. \\<appdir>\<assemblyname>\<assemblyname>.manifest

SxS Manager首先查找共享程序集, 共享程序集通常在Windows下的WinSxS目錄下瘩绒。如果未找到則會在應(yīng)用程序所處目錄按照上面順序查找相應(yīng)的程序集名。

4. 應(yīng)用程序manifest

上面已經(jīng)講并行程序集的工作原理和并行程序集的查找順序带族,接下來說一下如何用manifest描述應(yīng)用程序的依賴程序集以及如何將manifest嵌入到應(yīng)用程序中锁荔。
關(guān)于應(yīng)用程序的manifest詳細介紹請參考這里, 下面以應(yīng)用程序SampleApp為例,其manifest為SampleApp.exe.manifest, 如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="SampleApp" version="1.0.0.0" processorArchitecture="x86"/>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
      <application> 
          <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
          <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
          <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
          <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
          <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> 
      </application> 
  </compatibility>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="SampleAssembly" version="1.0.0.0" processorArchitecture="x86"/>
    </dependentAssembly>
  </dependency>
</assembly>

這里重點關(guān)注dependency結(jié)點蝙砌,該結(jié)點描述了應(yīng)用程序SampleApp依賴于程序集SampleAssembly阳堕。更多關(guān)于Assembly Manifest的XML描述請參考這里

有了上面的manifest择克,應(yīng)用程序啟動時恬总,為了讓SxS Manager能夠正確查找到依賴文件,還需要將SampleApp.exe.manifest嵌入到應(yīng)用程序中肚邢,有兩種方式可以嵌入:
方法一
如果采用Visual Studio構(gòu)建應(yīng)用程序壹堰,默認情況下,VS會將manifest嵌入到應(yīng)用程序中骡湖。按下面方式設(shè)置應(yīng)用程序的依賴程序集:

Properties > Configuration Properties > Linker > Manifest File > Additional Manifest Dependencies >
type='win32' name='SampleAssembly' version='1.0.0.0' processorArchitecture='x86'

也可以采用comment prama方式:

#pragma comment(linker, "\"/manifestdependency:type='win32' name='SampleAssembly' version='1.0.0.0' processorArchitecture='x86' \"")

設(shè)置好之后贱纠,重新編譯、鏈接响蕴,生成SampleApp.exe并巍。如果想知道上面依賴信息是否已經(jīng)成功嵌入到SampleApp.exe中,也有兩種方式查看:
1. 如果使用Visual Studio, 可以直接在Visual Studio中打開應(yīng)用程序换途,如下:


2. 也可以使用SDK提供的工具mt.exe, 命令如下:

mt.exe -inputresource:SampleApp.exe;#1 -out:SampleApp.exe.manifest

注意這個地方的1是manifest的資源序號懊渡,默認情況下是1。關(guān)于mt.exe的更多命令可以執(zhí)行mt.exe /?或參考這里军拟。

方法二
使用mt.exe工具嵌入剃执,如果采用VS構(gòu)建應(yīng)用程序,使用這種方式需要先關(guān)閉VS默認嵌入manifest的行為:

Properties > Configuration Properties > Linker > Manifest File > Generate Manifest > No (/MANIFEST:NO)

然后在Properties > Configuration Properties > Build Events > Post Build Event中寫入以下命令:

mt.exe -manifest SampleApp.exe.manifest -outputresource:$(OutDir)$(TargetName)$(TargetExt);#1

上面命令的前提是文件SampleApp.exe.manifest在你的工程目錄下懈息。重新編譯肾档,鏈接。想知道m(xù)anifest是否成功寫入SampleApp.exe中辫继,同樣可以采用上面說的兩種方法進行驗證怒见。

5. 實例應(yīng)用

再次回到我們面臨問題,仍然以應(yīng)用程序SampleApp.exe為例姑宽,假設(shè)SampleApp依賴libA.dll遣耍,而libA.dll又依賴于libB.dll。我們希望獎libA.dll和libB.dll放到目錄SampleAssembly下炮车,目錄結(jié)構(gòu)如下:

/AppDir
    |---SampleApp.exe
    |        |
    |---SampleAssembly
             |---SampleAssembly.manifest
             |---libA.dll
             |---libB.dll 

1. 按照第4小節(jié)所述的方法將Sample.exe.manifest嵌入到Sample.exe中
2. 在SampleApp.exe所處目錄下新建一個目錄舵变,目錄名同依賴程序集名(SampleAssembly)
3. 在SampleAssembly目錄下,新建一個manifest文件瘦穆,文件名同程序集名(SampleAssembly),其內(nèi)容如下:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity type="win32" name="SampleAssembly" version="1.0.0.0" processorArchitecture="x86"/>
    <file name="libA.dll"/>
    <file name="libB.dll"/>
</assembly>

4. 將libA.dll, libB.dll放到SampleAssembly目錄下
5. 運行SampleApp.exe纪隙,看是否能正常工作了呢

6. 更多參考

[1]. https://msdn.microsoft.com/en-us/library/windows/desktop/ff951640(v=vs.85).aspx
[2]. https://msdn.microsoft.com/en-us/library/windows/desktop/aa374224(v=vs.85).aspx
[3]. https://msdn.microsoft.com/en-us/library/windows/desktop/aa374219(v=vs.85).aspx
[4]. https://msdn.microsoft.com/en-us/library/windows/desktop/aa374191(v=vs.85).aspx
[5]. https://docs.microsoft.com/zh-cn/cpp/build/manifest-generation-in-visual-studio
[6]. https://docs.microsoft.com/zh-cn/cpp/build/how-to-embed-a-manifest-inside-a-c-cpp-application
[7]. https://docs.microsoft.com/zh-cn/cpp/build/reference/manifestdependency-specify-manifest-dependencies
[8]. https://en.wikipedia.org/wiki/DLL_Hell
[9]. https://msdn.microsoft.com/en-us/library/windows/desktop/aa375649(v=vs.85).aspx

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市扛或,隨后出現(xiàn)的幾起案子绵咱,更是在濱河造成了極大的恐慌,老刑警劉巖熙兔,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悲伶,死亡現(xiàn)場離奇詭異,居然都是意外死亡黔姜,警方通過查閱死者的電腦和手機拢切,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秆吵,“玉大人淮椰,你說我怎么就攤上這事∧杉牛” “怎么了主穗?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長毙芜。 經(jīng)常有香客問我忽媒,道長,這世上最難降的妖魔是什么腋粥? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任晦雨,我火速辦了婚禮架曹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闹瞧。我一直安慰自己绑雄,他們只是感情好,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布奥邮。 她就那樣靜靜地躺著万牺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪洽腺。 梳的紋絲不亂的頭發(fā)上脚粟,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音蘸朋,去河邊找鬼核无。 笑死,一個胖子當著我的面吹牛度液,可吹牛的內(nèi)容都是我干的厕宗。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼堕担,長吁一口氣:“原來是場噩夢啊……” “哼已慢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起霹购,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤佑惠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后齐疙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膜楷,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年贞奋,在試婚紗的時候發(fā)現(xiàn)自己被綠了赌厅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡轿塔,死狀恐怖特愿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情勾缭,我是刑警寧澤揍障,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站俩由,受9級特大地震影響毒嫡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜幻梯,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一兜畸、第九天 我趴在偏房一處隱蔽的房頂上張望努释。 院中可真熱鬧,春花似錦膳叨、人聲如沸洽洁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至汰翠,卻和暖如春龄坪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背复唤。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工健田, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人佛纫。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓妓局,卻偏偏與公主長得像,于是被迫代替她去往敵國和親呈宇。 傳聞我的和親對象是個殘疾皇子好爬,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)甥啄,斷路器存炮,智...
    卡卡羅2017閱讀 134,637評論 18 139
  • 個人學(xué)習(xí)批處理的初衷來源于實際工作;在某個迭代版本有個BS(安卓手游模擬器)大需求蜈漓,從而在測試過程中就重復(fù)涉及到...
    Luckykailiu閱讀 4,702評論 0 11
  • 在職場中我們經(jīng)常會碰到自己費勁了千辛萬苦把任務(wù)完成了穆桂,結(jié)果領(lǐng)導(dǎo)卻并不滿意,接著又對工作提出了這樣那樣的要求融虽,自己一...
    觴詠閱讀 332評論 3 3
  • 高三的每一天我?guī)缀醵紩栕约阂粋€問題 未來要做什么 看到觸目驚心的分數(shù)總會覺得人生無望 高考失利橫跨半個中國從北到...
    懸崖云書閱讀 288評論 10 0
  • 人性是什么享完? 人性,是對人之常情的體諒有额、認同般又;人性,是對人之通性的成全和尊重谆吴;人性倒源,是物傷同類的惻隱和悲憫;人性句狼,...
    靈山閱讀 2,567評論 0 1