上一篇文中,咱们已经实现出了本身的存档包格式处理类,但估计你也像我同样,不想直接发布集成该格式的 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 又能和平共处,因此这是个迷。