上一篇文中,咱們已經實現出了本身的存檔包格式處理類,但估計你也像我同樣,不想直接發佈集成該格式的 7-Zip 安裝包,畢竟用戶電腦上可能已經裝了 7-Zip,再裝一個就重複了。再加上若是這樣發佈的話,咱們就要跟隨 7z 官方的更新,每次 7z 更新,咱們也要更新本身的代碼,這多麻煩。git
有沒有一勞永逸的方法呢?實際上是有的,就是編譯爲外部插件。7-Zip 用官方安裝包就行,只要加載咱們的插件就能增長新的格式支持。插件編譯出來後,基本上是能夠一直用下去的,官方接口應該不會隨意改動。github
事實上,官方安裝包中的 7z.exe
、7zFM.exe
就是基於 7z.dll
這個外部插件的,不信你能夠把 7z.dll
文件刪掉,會發現 7z 已經不支持任何格式,徹底就是一個空殼程序。app
雖然官方文檔中什麼都沒有說,但從源碼中能夠知道,7z 支持 2 種類型的插件:Codecs 和 Formats。繼續分析源碼,會發現這兩種插件其實沒有任何差異,甚至代碼中對它們的加載方式都是一致的,只不過保存的目錄不一樣。函數
注意:下面說的全部內容,官方都沒有寫入文檔,徹底是我分析源碼得出的結論,將來隨時可能被修改oop
默認狀況下,7z 會從下面 3 個位置加載插件:編碼
第一個位置已經被官方佔用了,咱們能夠把本身的插件放入後面二者中的任意一個。除了目錄名不一樣,插件的工做方式沒有任何區別。spa
上面說了,官方安裝包中的 7z.dll
就是一個插件,它的項目目錄在 CPP/7zip/Bundles/Format7zF
,咱們能夠從這個項目入手,找到插件接口。插件
打開項目,會發現接口其實很好找,官方已經建立了分類目錄,就是項目中的 Spec
目錄。code
注意,這裏的 Archive2.def
、DllExports2.cpp
,文件名中都帶個 2,其實還有不帶 2 的這倆文件,它們的區別是:帶後綴 2 的支持導出編解碼器,而不帶後綴的只能導出存檔包格式處理器。orm
咱們並無實現編解碼器,因此選擇不帶後綴的這組就好了,同時刪去 CodecExports.cpp
。
因爲有編碼潔癖,我選擇從頭開始建立項目。
打開 VS,新建一個 dll 空項目,把上面說的 Archive.def
、ArchiveExports.cpp
、DllExports.cpp
加入項目。其中 DllExports.cpp
文件中已經實現了 DllMain
函數,咱們不用重複實現。
而後。。編譯一下?哈哈,確定編譯不過,哪有這麼簡單。
經過幾回嘗試,我把依賴關係理清了,把下面這些文件都加入項目:
好了,這就是插件項目的最小依賴關係。
再編譯一下?哈哈,不出意外仍是不行的,須要改一改 stdafx.h
,把裏面已有的內容刪掉,寫入這些內容:
#pragma once // 按你項目的實際放置位置,修改這裏的路徑 #include "../../../Common/Common.h"
如今編譯就 OK 了。
把編譯出的 dll 放入上面說的插件目錄中,從新打開 7z,應該就能用了。
經過 7z i
命令,能夠看到:
Libs: 0 D:\scoop\home\apps\7zip\current\7z.dll 1 D:\scoop\home\apps\7zip\current\Formats\FormatZzz_x64.dll Formats: ... 1 Zzz zzz
咱們的插件已經被加載進來了,支持的格式裏也有了咱們添加的格式。
最後,相關源碼在 https://github.com/wzv5/7z-formatzzz
再說點不相關的,7-Zip 的開源協議是 LGPL,使用請謹慎。我不知道若是實現爲外部插件,而且把上面說的那些依賴文件所有本身重寫,也就是本身實現這套插件接口,還受不受 LGPL 協議限制,使用私有 API 接口算不算侵權呢?你還記得甲骨文是怎麼告 Google 的 Android 侵權的麼?可是微軟和 Wine、Mono 又能和平共處,因此這是個迷。