[轉]MSI安裝程式中的檔案替換

來源:互聯網
上載者:User

標籤:http   使用   os   檔案   資料   io   

原文連結:http://teach.hanzify.org/article/652-1233562028.html

 

前言

最近有漢化朋友問起如何不重新製作MSI檔案,而直接用漢化好的檔案替換MSI安裝程式中的檔案。為此,將本人的實踐經驗作個總結,供各位漢化人蔘考。有錯誤的地方煩請指正。
※說明:
目前可以用於MSI編輯的軟體很多,但是有些軟體在儲存時會在MSI檔案中寫入一些自己的表或內容,有些會另外嵌入一個CAB檔案,使得MSI檔案增大。而這裡提供的方法保證不會寫入任何不必要的內容和檔案。
※關鍵點:
1、CAB中的檔案順序要和MSI的檔案表中的檔案順序保持一致。
2、有些CAB中的檔案使用了Windows不支援的檔案名稱。

軟體準備

1、Orca,微軟提供的MSI編輯器。漢化版(版本為 4.5.6001.22192):
http://www.hanzify.org/index.php?Go=Show::List&ID=11122 或
http://www.wanfutrade.com/software/hanhua/Orca45chs.msi
2、MsiDb,微軟提供的MSI中CAB檔案提取和替換工具。本人的漢化版(版本為4.5.6001.22192):
http://www.wanfutrade.com/software/hanhua/MsiDb.exe
3、IExpress,微軟提供的CAB檔案打包使用者介面工具。本人的漢化版(版本為6.0.3790.0):
http://www.wanfutrade.com/software/hanhua/iexpress20.exe
4、Excel,相信這個大家都有吧。什麼版本都可以。

基礎知識

1、MSI檔案的格式
MSI檔案實際上一個安裝資料庫,裡面有很多表,這些表都是由 TAB 格式寫成的文本,就像EXCEL一樣由列和行組成。可以從MSI中匯出每個表。匯出的表可以用文字編輯器和EXCEL開啟。至於每個表和表中每個欄位的作用就不在這裡講述了。請參考微軟提供的相關資料。
2、MSI安裝檔案存在形式
MSI 安裝程式中,需要安裝的檔案的存在形式許多種,常見的有以下幾種:
(1)安裝檔案被打包為CAB檔案,並嵌入在MSI檔案中
(2)安裝檔案被打包為CAB檔案,但CAB獨立於MSI存在
(3)安裝檔案未被打包為CAB檔案,而是以原來的狀態存在於各個檔案夾中
對於以(1)、(2)形式存在的CAB檔案,可以採用本文介紹的方法替換,而對於以(3)形式存在的檔案檔案直接替換即可。
3、MSI安裝檔案清單
在MSI檔案中有二個表是用來表達CAB中的檔案清單和CAB檔案的名稱和檔案數以及其他資訊的,這就是 File 表和 Media 表,其中File表儲存了CAB中存在的檔案名稱以及每個檔案所屬的組件、安裝後的實際檔案名稱、檔案大小、版本、語言、屬性和檔案順序等資訊,Media表儲存了CAB檔案的磁碟ID、檔案數、磁碟描述、CAB檔案名稱以及卷標等資訊。
先來看一下MSI檔案中這二個表:
(1)File表

上面就是File表,對涉及到本主題的列說明如下:
File列,表示 CAB中的檔案名稱列表,有的是我們常見的檔案名稱格式,有的則在常見檔案名稱後加上許多像類別識別碼那樣的編號,有的乾脆就是一個編號。對為什麼不用常見的檔案名稱,我想是由於有的MSI製作軟體為了某種目的故意這樣命名的。特別是InstallShield製作的MSI檔案。
Compoent_ 列,表示該檔案屬於哪個組件。
FileName 列,表示安裝後的檔案名稱。其中 | 前面的為短檔案名稱,後面的為長檔名。
FileSize 列,表示檔案的大小。一般不需要更改它,即使替換後的檔案與其不一致。
Language 列,表示檔案所用的語言。一般也不需要更改它,即使替換後的檔案語言與其不一致。
Attributes 列,表示檔案的屬性,比如隱藏、系統、存檔等等。一般也不需要更改它,除非您有特別的用途,如想在安裝後隱藏某個檔案。
Sequenec 列,表示檔案的序號,這裡的需要不允許重複,並且始終是從1開始的。
(2)Media表

Media表中,DiskID、DiskPrompt、VolumeLable、Source列一般不需要去考慮,這裡主要介紹以下其他二個列。
LastSequence 列,表示CAB中的檔案數,也就是上述File表中Sequenec 列中的最大數,這二個數一定要一致。
Cabinet 列,表示 CAB檔案名稱。注意:檔案名稱前的“#”不是真本文件名的一部分。

開始實踐

1、首先提取嵌入在MSI中的CAB檔案。如果是CAB檔案獨立於MSI,跳過該操作。
  在DOS下或MsiDb.exe捷徑下,使用“MsiDb.exe –x CAB檔案名稱 -d MSI檔案名稱”命令提取。
其中:(1)CAB檔案名稱就是Media表中的Cabinet 列中的CAB檔案名稱。注意忽略前置的“#”。
(2)CAB 和 MSI 檔案名稱均要帶尾碼副檔名。
2、直接用Windows 資源管理員或RAR或其他壓縮軟體提取CAB檔案中的檔案到一個單獨的檔案夾。
3、使用CMD命令,轉入DOS介面,在釋放CAB中的檔案的單獨檔案夾下,使用“dir /b > CabFileList.xls”命令提取該檔案夾中的檔案名稱列表。這裡的CabFileList.xls檔案名稱您可以用其他檔案名稱代替,自由命名。
4、用MsiDb.exe或Orca開啟MSI檔案,匯出MSI檔案中的File表。匯出後的檔案名稱為File.idt。
5、用EXCEL開啟File.idt檔案,並按 Sequenec 列對整個表進行排序備用。如。

6、比較從CAB中提取的檔案數量是否與MSI檔案中的File表中所列的檔案數量相等。可以直接在MSI檔案和解開的檔案夾中判斷,也可以用EXCEL分別開啟前面產生的CabFileList.xls和File.idt進行判斷。
(1)如果相等,一般情況下說明檔案名稱都是相同的。
(2)如果不等,說明CAB中的某些檔案有Windows 系統不認可的檔案名稱存在,比如CAB中有XXX.(注意XXX後面的 . )這樣的檔案名稱。
在不相等的情況下,用EXCEL分別開啟前面產生的CabFileList.xls和File.idt二個檔案,分別對檔案名稱列進行排序,並將File.idt檔案的檔案名稱所在列整列複製到CabFileList.xls中的一個新列中,並用IF函數判斷二者是否有差異。(注意Msi_FileTable_FileList列中後面帶 . 的檔案)。

7、在提取的檔案夾中,將在有差異的檔案的檔案名稱後添加一個數字或其他什麼,將其改名,然後再從CAB檔案中提取有差異的檔案的另一個檔案。
8、在CabFileList.xls中插入一個工作表,將第5步中已排序的File.idt 檔案的File列和Sequenec 列分別複製到新的工作表中,並在其他列中添加“FILE”、“"”、“=”等列,然後用CONCATENATE文本合并函數,將這些列中的資料合併成IExpress所需的指令碼格式。。

9、用漢化好的檔案替換已解開的檔案(注意:第6、7步中有差異的檔案)。
※推薦直接漢化已解開的檔案,以免重新命名等麻煩。
10、運行IExpress,選擇“僅建立壓縮檔”選項(),將已用漢化替換的檔案全部或部分添加到要打包的檔案中,然後選擇“在軟體包中使用長檔名儲存檔案”選項,最後儲存好.SED副檔名的IExpress指令檔。



11、修改IExpress指令檔。用文字編輯器開啟剛才儲存的IExpress指令檔(.sed),並從第8步的EXCEL表中複製SED[Strings] 列到IExpress指令檔的 [Strings] 節中,同理,複製SED[SourceFiles0] 列到 [SourceFiles0] 節。
※重要提示:
如果第6、7步中有差異檔案存在,請在IExpress指令檔的 [Strings] 節中,將有差異的檔案按MSI檔案中的檔案名稱命名(在第8步中已經採用了MSI中的檔案名稱列表,所以這裡一般不需要修改)。並將IExpress指令檔的 [SourceFiles0] 節中的檔案名稱全部改為在資源管理員中存在的實際檔案名稱。
※備忘:
(1)在一般的IExpress指令檔(.sed)的[SourceFiles0] 節中的“=”號後是沒有檔案名稱的。因為有差異檔案名存在,所以這裡需要特別處理。
(2)建立CAB時,程式會自動刪除[SourceFiles0]節中的所有檔案名稱。請注意儲存備份,並在下次建立時複製回去。
12、再次運行IExpress,開啟剛才修改好的IExpress指令檔,一路下一步,一個已用漢化後檔案替換的符合MSI檔案中的File表的檔案順序的新CAB檔案產生了。
13、將新的CAB檔案插入到MSI檔案中。如果是CAB檔案獨立於MSI,跳過該操作。
  首先,在DOS下或MsiDb.exe捷徑下,使用“MsiDb.exe -k CAB檔案名稱 -d MSI檔案名稱”命令刪除MSI檔案中的CAB檔案(其實只是清除關聯)。然後使用“MsiDb.exe -a CAB檔案名稱 -d MSI檔案名稱”命令插入新的CAB檔案到MSI檔案中。
其中:(1)CAB檔案名稱就是Media表中的Cabinet 列中的CAB檔案名稱。注意忽略前置的“#”。
(2)CAB 和 MSI 檔案名稱均要帶尾碼副檔名。
如果提示不成功,請先用“MsiDb.exe -k CAB檔案名稱 -d MSI檔案名稱”命令清除流,然後再用“MsiDb.exe -a CAB檔案名稱 -d MSI檔案名稱”添加新的CAB檔案。
注意:MsiDb.exe 對某些長檔案夾名不支援,會提示錯誤。建議盡量用短檔案夾名。
14、安裝測試。運行一下安裝程式,看看是否會在安裝過程中出現類似“檔案不存在”等錯誤,如果沒有,則大功告成。

備忘

1、謝謝您閱讀,如果本文對您有些協助,將十分榮幸。
2、本文著作權屬wanfu所有,歡迎在保持完整和不修改的條件下轉載本文。
3、聯絡郵件:[email protected]

關於壓縮率

1、預設情況下,用IEPress製作的CAB檔案壓縮率相對較低。經初步測試,IEpress的指令碼支援Makecab.exe的所有參數,只要在[Options]節中添加CompressionType=lzx一行,就可以實現 lzx 壓縮率。
2、根據 zhfi 網友的提示,查了一下有關資料,用 cabarc.exe -m LZX:21 -r N CAB檔案名稱 "檔案所在目錄\*" 命令確實可以獲得比 IEpress 更高的壓縮率,而且不存在順序問題。但是如果有MSI 中有 XXX. 這樣的檔案,而實際解壓後沒有了 XXX. 這樣的檔案,就無法打包成和原始CAB一樣的新CAB檔案,只能通過修改MSI檔案中的File表中的File列中的相關檔案名稱以及在其他表中所關聯的檔案名稱才能解決。
3、根據漢化好友"魚“的方法,可以在要壓縮的檔案所在的檔案夾下,用以下命令列實現:
makecab /f <完整路徑>MsiFileList.txt /d compressiontype=lzx /d compressionmemory=21 /d maxdisksize=1024000000 /d diskdirectorytemplate=data* /d cabinetnametemplate=data*.cab
這裡:MsiFileList.txt 是指MSI檔案中File表中的File列的檔案名稱列表(請按Sequenec 列從小到大排列),
diskdirectorytemplate=data* 中的 data*,即分卷壓縮的情況下,在要壓縮的檔案所在的檔案夾下產生 data1/data2/data3……檔案夾,不分卷壓縮的情況下,只產生一個檔案夾。
cabinetnametemplate=data*.cab 中的 data*.cab,即分卷壓縮的情況下,data1/data2/data3……檔案夾中產生data1.cab/data2.cab/data3.cab......等CAB檔案名稱。
但是,如果有原CAB中有XXX. 和XXX二個解壓後檔案名稱相同的檔案,那麼該方法就不適用了。
4、如果你已經刪除了CAB中的一些檔案,並對相關的MSI表進行了修改(如不修改會出現安裝錯誤!),需要縮小MSI檔案的話,請使用Orca開啟清流後的MSI,然後另存新檔一個MSI檔案,然後用MsiDb.exe插入新的CAB即可。2008-12-07注

整個檔案下載:MSI安裝程式中的檔案替換.mht

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.