1. 程式人生 > >MSI安裝包的修改經歷

MSI安裝包的修改經歷

        最近做了一個MSI程式安裝包的修改,涉及的東西蠻多的,記錄下來以作參考。鑑於程式的私密性,在這裡就不多介紹了,只說技術,扯點別的先。

        一、MSI與EXE的區別

      【EXE】檔案是最常見的可執行應用程式檔案,是一種可在作業系統儲存空間中浮動定位的可執行程式,在MSDOS和MSWINDOWS下可執行檔案的副檔名為EXE。在Windows下二進位制的可執行程式有COM,EXE,DLL等,COM一般用作DOS可執行檔案的副檔名,EXE一般用作Windows下可執行檔案的副檔名,而DLL為動態連結庫檔案。通常使用者在提示行中輸入不帶.exe副檔名的檔名後按 Enter 鍵就能執行可執行程式。

        EXE檔案比較複雜,每個EXE檔案都有一個檔案頭,結構如下:
  EXE 檔案頭資訊 
  EXEHEADER ENDS 程式映象,包含

處理器程式碼和程式的初始資料,緊接在檔案頭之後。它的大小以位元組為單位,等於.EXE檔案的大小減去檔案頭的大小,也等於exHeaderSize的域的值乘以16。MS-DOS通過把該映象直接從檔案拷貝到記憶體載入.EXE程式然後調整定位表中說明的可重定位段地址。而定位表是一個重定位指標陣列,每個指向程式映象中的可重定位段地址。檔案頭中的exRelocItems域說明了陣列中指標的個數,exRelocTable域說明了分配表的起始檔案偏移量。每個重定位指標由兩個16位值組成:偏移量和段值。為載入.EXE程式,MS-DOS首先讀檔案頭以確定.EXE標誌並計算程式映象的大小,然後它試圖申請記憶體。

        首先,它計算程式

映象檔案的大小加上PSP的大小再加上EXEHEADER結構中的exMinAlloc域說明的記憶體大小這三者之和,如果總和超過最大可用記憶體塊的大小,則MS-DOS停止載入程式並返回一個出錯值。否則面,它計算程式映象的大小加上PSP的大小再加上EXEHEADER結構中exMaxAlloc域說明的記憶體大小之和,如果第二個總和小於最大可用記憶體塊的大小,則MS-DOS分配計算得到的記憶體量。否則,它分配最大可用記憶體塊。分配完記憶體後,MS-DOS確定段地址,也稱為起始段地址,MS-DOS從此處載入程式映象,如果exMinAlloc域和exMaxAlloc域中的值都為零,則MS-DOS把映象儘可能地載入到記憶體最高階。否則,它把映象載入到緊挨著PSP域之上。接下來,MS-DOS讀取重定位表中的專案調整所有由可重定位指標說明的段地址。對於重定位表中的每個指標,MS-DOS尋找程式映象中相應的可重定位段地址,並把起始段地址加到它之上。一旦調整完畢,段地址便指向了記憶體中被載入程式的程式碼和資料段。MS-DOS在所分配記憶體的最低部分建造256位元組的PSP,把AL和AH設定為載入.COM程式時所設定的值。MS-DOS使用檔案頭中的值設定SP與SS,調整SS初始值,把起始地址加到它之上。MS-DOS還把ES和DS設定為PSP的段地址.最後,MS-DOS從
程式檔案
頭讀取CS和IP的初始值,把起始段地址加到CS之上,把控制轉移到位於調整後地址處的程式。

        DLL(DynamicLinkable Library)檔案即動態連結庫檔案,是一種可執行檔案,它允許程式共享執行特殊任務所必需的程式碼和其他資源。一般來說,DLL是一種磁碟檔案,以.dll,.DRV,.FON,.SYS 和許多以 .EXE 為副檔名系統檔案都可以是DLL。它由全域性資料、服務函式和資源組成,在執行時被系統載入到呼叫程序的虛擬空間中,成為呼叫程序的一部分。如果與其它 DLL之間沒有衝突,該檔案通常對映到程序虛擬空間的同一地址上。DLL 模組中包含各種匯出函式,用於向外界提供服務。DLL可以有自己的資料段,但沒有自己的堆疊,使用與呼叫它的應用程式相同的堆疊模式;一個 DLL 在記憶體中只有一個例項;DLL實現了程式碼封裝性;DLL 的編制與具體的程式語言編譯器無關。

      【MSI】檔案,不得不先說說Windows Installer,它不只是安裝程式,而是可擴充套件的軟體管理系統。WindowsInstaller的用途包括:管理軟體的安裝、管理軟體元件的新增和刪除、監視檔案的復原以及使用回滾技術維護基本的災難恢復。另外,WindowsInstaller還支援從多個源位置安裝和執行軟體,而且可以由想要安裝自定義程式的開發人員自定義。要想使用這些功能,就必須通過MSI檔案。MSI檔案是WindowsInstaller的資料包,它實際上是一個數據庫,包含安裝一種產品所需要的資訊和在很多安裝情形下安裝(和解除安裝)程式所需的指令和資料。MSI檔案將程式的組成檔案與功能關聯起來。此外,它還包含有關安裝過程本身的資訊:如安裝序列、目標資料夾路徑、系統依賴項、安裝選項和控制安裝過程的屬性。

        WindowsInstaller技術就是合併在一起發揮作用的兩個部分:客戶端安裝程式服務(Msiexec.exe)和Microsoft軟體安裝(MSI)軟體包檔案。 Msiexec.exe 程式是 Windows Installer 的一個元件。當 Msiexec.exe 被安裝程式呼叫時,它將用 Msi.dll 讀取軟體包檔案 (.msi)、應用轉換檔案 (.mst)併合並由安裝程式提供的命令列選項。 Windows Installer執行所有與安裝有關的任務:包括將檔案複製到硬碟、修改登錄檔、建立桌面快捷方式、必要時顯示提示對話方塊以便使用者輸入安裝首選項。

        當雙擊MSI檔案的時候,與之關聯的Windows Installer 的一個檔案Msiexec.exe被呼叫,它將用Msi.dll讀取軟體包檔案(.msi)、應用轉換檔案(.mst)進行進一步處理,然後 WindowsInstaller執行所有與安裝有關的任務:包括將檔案複製到硬碟、修改登錄檔、建立桌面快捷方式,必要時顯示提示對話方塊以便使用者輸入安裝需要的資訊,就這樣,一個程式安裝到了你的電腦上。採用MSI安裝的優勢在於你可以隨時徹底刪除它們,更改安裝選項,即使安裝中途出現意想不到的錯誤,一樣可以安全地恢復到以前的狀態,正是憑著此強大功能,越來越多的軟體開始使用MSI作為發行的方式了。如果你對MSI檔案感興趣,可以用WinRAR等壓縮軟體開啟看一下里面的內容。

       二、製作MSI常用的工具

      【Installshield】

        最常用的工具就是Installshield。Macrovision軟體公司家族成員之一的InstallShield產品,是安裝工具領域事實上的標準。InstallShield軟體是軟體安裝、配置軟體包和升級解決方案領域內公認的標準。 InstallShield已經成為安全安裝軟體的標準解決方案,涉及全球6.9萬多個開發組織和5億臺電腦。主流的MSI應用程式均採用該模式打包釋出。該軟體功能強大,簡單的安裝操作容易,複雜的安裝過程及元件配置需要自己動手寫指令碼,教程可以在網上搜索,能搜出一大堆出來,推薦“海洋女神”的部落格,寫的很好很詳細。

      【Advanced Installer】

         AdvancedInstaller 是一款 Windows Installer 編寫工具。它為建立和維護基於 Windows Installer安裝技術的安裝程式包 (EXE、MSI 等) 提供了一個簡單易用的圖形使用者介面。Advanced Installer 有 4 個版本:免費版、專業版、Java 和企業版。免費版不需要註冊,並且可以免費用於商業和非商業性目的。專業版、Java版和企業版有一個只能被用於評估目的試用期。在試用期結束以後,您必須註冊產品或完全停止使用它。Advanced Installer是一款功能強大、可生成符合 MS Windows 認證的 Windows Installer 的 MSI安裝包製作工具,具有友好的圖形使用者介面,直觀而且非常簡單的介面,建立 MSI檔案包非常方便,使用者只需新增檔案,修改名稱,新增按鈕就可以了,無需任何指令碼方面的知識,並且生成的安裝檔案保證符合 Windows最佳操作建議。

         AdvancedInstaller具有完全安裝、註冊和解除安裝組成你應用程式的檔案、部件及資源的功能;完全自定義 MSI 安裝包 -具有新增、刪除檔案及資料夾功能; 新增或移除內、外部檔案或 URL快捷方式;新增或移除登錄檔鍵或專案;新增或移除環境變數;安裝時可設定檔案屬性 - 只讀、隱藏等;強制安裝完畢系統重啟動;支援使用 64位 CPU 的系統中安裝包製作;Windows 系統下安裝過程完整日誌等特點。

      【MSI_Studio】

        MSIStudio是一個用來建立WindowsInstaller(MSI)檔案,也可以修改現有Windows安裝包(MSI格式安裝檔案)的工具,Desktop AuthorityMSI Studio是為全球系統管理人員,軟體打包人員和開發人員提供的完善的軟體解決方案 。MSIStudio的主要功能有:重新打包–從原有的或者現有的基於MSI的安裝建立定製的MSI;編輯 – 通過影象瀏覽或直接訪問MSI表格修改MSI;管理–通過先進的轉化,合併,確認和提取功能改善你的MSI;建造–使用cab檔案,壓縮的MSI,引導的MSI和證書建立MSI專案;精簡版說明:去除伺服器元件,去除舊的VB/VC執行庫,重新壓縮cab以獲得更小的體積,部分修改安裝對話方塊 ,修改預設安裝目錄為%Programfiles%\ScriptLogicCorporation\MSI Studio(以前後面還要再多一個\MSI Studio)。

      【Orca】

        Orca是一款由微軟提供的用於 Windows Installer 資料庫表編輯器。可用來編輯 Windows Installer 資料庫檔案(.msi) 檔案,合併模組 (.msm) 檔案,補丁 (.msp) 檔案,內部一致性計算程式 (.cub) 檔案和補丁建立屬性(.pcp) 檔案。是修改和本地化 Windows Installer 資料庫的最佳輔助工具。Orca主要特點有:可以任意新增、刪除、匯入、匯出和重新構架資料表;可以任意複製、貼上、新增、刪除、編輯行和單元格;可以用十進位制或十六進位制檢視資料型單元格;可以建立、應用轉換(.mst) 檔案;可以對資料庫進行驗證,合併模組以及對話方塊御覽;可以檢視並修改摘要資訊;

        類似的這些軟體網上應該還有很多,限於能力有限,只找到常用的這幾個。介紹均來自百度百科。

       三、本次修改的經過

        軟體簡介:本次修改的軟體是一個VC++開發的MIS程式,為了簡便,領導想把一個空的資料庫檔案打包進入,技術支援部通常再給客戶安裝完軟體後都會重新把安裝目錄修改,新增一些其他檔案,這樣一來,軟體就顯得很弱智,他們提出的要求也很明確,新增資料庫包,修改安裝後路徑,更改桌面圖示名稱為中文。很不幸的是,我沒有原始碼,手頭上只有一個安裝包(.MSI),更要命的是用Winrar開啟時顯示該資料包已損壞,其實程式仍可以安裝的,而且程式挪動地方一樣可以執行的。我還一度懷疑這是一個“綠色的”軟體呢,如果是那樣的話就重新用IS封裝一個安裝包,加入其他部門所需的檔案即可,但是這樣做下來沒有成功,用IS編輯軟體包也沒有發現其他奇特之處,只是系統一直提示“由於應用程式的配置不正確,應用程式未能啟動,重新安裝應用程式可能會糾正這個問題”,重新安裝是不能解決這種問題的。而這個問題也是很多人一直在問的問題,以前用VC6和VS2003的話,如果缺少庫檔案,是會提示缺少“**.dll”,但是用VS2005卻沒有這樣的提示。用記事本直接開啟MSI檔案,在檔案結尾處可以看到一下內容:

<assemblyxmlns="urn:schemas-microsoft-com:asm.v1"manifestVersion="1.0">
 <dependency>
   <dependentAssembly>
     <assemblyIdentity type="win32"name="Microsoft.VC80.DebugCRT" version="8.0.50608.0"processorArchitecture="x86"publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
   </dependentAssembly>
 </dependency>
 <dependency>
   <dependentAssembly>
     <assemblyIdentity type="win32"name="Microsoft.VC80.DebugMFC" version="8.0.50608.0"processorArchitecture="x86"publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
   </dependentAssembly>
 </dependency>
</assembly>  
        很明顯,軟體缺相關的DLL檔案。根據網上眾多專家的部落格,我做了嘗試。由於不可能重新編譯,我先嚐試了拷貝檔案的方法:在類似C:\ProgramFiles\Microsoft Visual Studio8\VC\redist\Debug_NonRedist\x86\Microsoft.VC80.DebugCRT 下找到了下列檔案:msvcm80d.dll、msvcp80d.dll、msvcr80d.dll、Microsoft.VC80.DebugCRT.manifest;把這幾個檔案拷貝到目標機器上,與執行程式同一資料夾或放到system32下,不能執行;然後我又找到了再分發包vcredist_xxx.exe,想把程式一起捆綁安裝,一樣不行。也許還缺檔案,但是此時IS已經不能發揮作用了,而且IS職能修改部分屬性值,但不能加入新檔案,更不能重新Building,這個給我造成了不小的麻煩。現在要做的是先查明缺失的系統檔案,再做一個移植,重新打包新檔案。一番搜尋後,我找到了Orca。說實話,開啟Orca的介面的時候,我一點心思都沒有了,幾乎全部是表,操作異常麻煩,稍有不慎,就BreakDown了。但是專案在那裡擺著的,而且在我不知情的時候向老闆吹牛皮誇下海口,現在騎虎難下了,硬著頭皮,繼續尋找吧。這次搜到的就是AdvancedInstaller。AdvancedInstaller的介面就清爽很多,和IS很類似,我按照之前的設想,先修改了軟體的屬性,然後新增目錄,編譯,程式BreakDown(我用的破解版的)。我再次開啟重複一遍,仍舊崩潰,我也要崩潰了。我又重新用了其自動搜尋識別功能,這次居然把我之前要查詢的隱藏的系統檔案匯出來了,悲喜交加呀。我把這些匯出的檔案和先前安裝後的程式自身檔案捆綁後打包,依舊不能執行。崩潰!

        查資料到現在,三四天了,每次都像玻璃瓶裡的蒼蠅,以為看到光明瞭,一頭撞上去,血肉模糊啊!我打算放棄了,為了這樣一個功能,不值得。我刪除了之前匯出的那些檔案,草紙上的幾個Action被我一個個劃去,正準備扔掉的時候,我仍舊不死心,再次檢查了一遍,看看是不是哪裡漏掉了,然後再次搜尋工具,最後,找到了一個利器--MSIStudio。我告訴自己,這次不行,堅決放棄。

         MSIStudio雖然是全英文介面,但是難不住我。MSIStudio和IS也很像,操作起來也很類似,最好的就是這個支援重新編譯,我很小心的操作著這個最後的稻草,第一次顯示錯誤,我先新增一個Readme檔案,編譯,成功,安裝測試,成功,竊喜。然後加入新資料夾,新增新檔案,在Features和Components中新增資料夾,注入檔案,編譯,Done,額滴神吶!

        四天的努力,換來了現在這個結果。然後開啟虛擬機器,在一個純淨的作業系統下測試,通過,哦也!