问题的提出

公司各个业务线的安装包小则几十兆、大则几百兆,使用自建的升级系统向全国百万级用户下发新版本时,流量耗费相当惊人。有时新版本仅仅改了几个 dll ,总变更量不过几十 K 而已,也要发布一个完整版本。为了降低流量费用,我们推出了补丁升级的方式:产品组将修改的 dll 单独挑选出来,加上一个配置文件压缩成包,上传到自建的升级后台;在客户端,识别到补丁包类型后,手动解压并替换各个 dll 完成安装(之前是直接启动下载好的安装包)。这种方式一经推出,受到了业务线的追捧。然而在使用过程中,也发现一些问题,就是在修改完一个源文件后,受影响的往往不止一个 dll,如果仅把其中一两个 dll 替换了,没替换的 dll 很可能就会和新的 dll 产生接口不兼容,从而引发崩溃。而有的安装包包含了几十个、上百个 dll,如果一一对比,非常费时费力。特别是一些 dll 仅仅是编译时间不一样,通过普通的文件对比工具,根本无法判断这个 dll  的源码有没有改过,这让开发人员非常头大。

问题的解决

其实这个问题用 c++ 写个程序是可以解决的,但是一想到要遍历目录、构造文件名 map、对比两个目录中的文件名、对比相同文件名的内容、复制文件到目标目录、压缩目标目录…这一系列操作时,我觉得还是算了 —— 都得从头开始写,工作量不小。而 msys2 或 windows 中就有不少现成的命令可以用,例如对比目录可以用 diff -r 命令、对比 win32 可执行文件可以用 dumpbin /disasm 命令反编译然后再用 diff 命令对比、压缩文件夹可以使用 7z 命令等等,完全不用重复造轮子,直接用 shell 将它们粘合起来就完事了!下面就来看看我是怎么用 shell 脚本来写这个小工具吧。

处理命令行参数

这个脚本一开始先处理输入的命令行参数:

  1 # return code:
2 # 0 : success
3 # 1 : no difference
4 # 2 : compress failure
5 # 3 : create file/dir failure (privilege ?)
6 # 126 : file/dir existent
7 # 127 : invalid arguments
8
9 function usage ()
10 {
11 echo "Usage: diffpacker.sh -o oldversionfolder -n newversionfolder -r relativepath -x exportfolder -v version [-s sp] [-t (verbose)] [-e (exactmode)]"
12
13 exit 127
14 }
15
16 srcdir=
17 dstdir=
18 reldir=
19 outdir=
20 version=
21 sp=0
22 verbose=0
23 exactmode=0
24 setupdir="setup"
25 # pure windows utilities subdir
26 win32="win32"
27
28 if [ "${$*/-t//}" != "$*" ]; then
29 # dump parameters when verbose on
30 echo "total $# param(s):"
31 for var in $*; do
32 echo "$var"
33 done
34 fi
35
36
37 while getopts "o:n:r:x:v:s:te" arg
38 do
39 case $arg in
40 o)
41 srcdir=$OPTARG
42 ;;
43 n)
44 dstdir=$OPTARG
45 ;;
46 r)
47 reldir=$OPTARG
48 ;;
49 x)
50 outdir=$OPTARG
51 ;;
52 v)
53 version=$OPTARG
54 ;;
55 s)
56 sp=$OPTARG
57 ;;
58 t)
59 verbose=1
60 ;;
61 e)
62 exactmode=1
63 ;;
64 ?)
65 echo "unkonw argument: $arg"
66 usage
67 exit 127
68 ;;
69 esac
70 done
71
72 # reldir can be empty
73 if [ -z "$srcdir" -o -z "$dstdir" -o -z "$outdir" -o -z "$version" ]; then
74 echo "empty parameter found: $srcdir, $dstdir, $outdir, $version"
75 usage
76 exit 127
77 fi
78
79 #replace all \ to / to avoid shell string choked on \
80 srcdir=${srcdir//\\/\/}
81 dstdir=${dstdir//\\/\/}
82 reldir=${reldir//\\/\/}
83 outdir=${outdir//\\/\/}
84
85 echo "srcdir=$srcdir"
86 echo "dstdir=$dstdir"
87 echo "reldir=$reldir"
88 echo "outdir=$outdir"
89 echo "version=$version"
90 echo "sp=$sp"
91 echo "verbose=$verbose"
92 echo "exactmode=$exactmode"
93 echo ""
94
95 if [ ! -d "$srcdir" ]; then
96 echo "not a directory : $srcdir"
97 exit 126
98 fi
99
100 if [ ! -d "$dstdir" ]; then
101 echo "not a directory : $dstdir"
102 exit 126
103 fi
104
105 #if [ -e "$outdir" ]; then
106 resp=$(ls -A "$outdir")
107 if [ "$resp" != "" ]; then
108 echo "out directory not empty: $outdir, fatal error!"
109 exit 126
110 fi
111
112 if [ "${outdir:$((${#outdir}-1))}" == "/" ]; then
113 # remove tailing /
114 outdir=${outdir%?}
115 fi
116
117 if [ ! -z "$reldir" ] && [ "${reldir:$((${#reldir}-1))}" == "/" ]; then
118 # remove tailing /
119 reldir=${reldir%?}
120 fi
121
122 srcasm="src.asm"
123 dstasm="dst.asm"
124 dirdiff="dir.diff"
125 patdiff="diffpattern.txt"
126 itemcnt=0
127 jsonhead=\
128 "{\n"\
129 " \"version\": \"$version\",\n"\
130 " \"sp\": \"$sp\",\n"\
131 " \"actions\": \n"\
132 " [\n"
133
134 json=
135 jsontail=\
136 "\n ]\n"\
137 "}\n"
138
139 echo "exclude patterns: "
140 while read line
141 do
142 echo $line
143 done < "$patdiff"
144
145 # to avoid user not end file with \n
146 if [ ! -z "$line" ]; then
147 echo "$line"
148 fi
149 echo ""

简单解说一下:

  • 16-26:声明用到的变量;
  • 28-34:如果命令行中含有 -t (verbose) 选项,则打印命令行各个参数;
  • 37-70:使用 getopts 命令解析命令行,这个脚本接收以下选项:
    • -o (old) 用于对比的旧目录;
    • -n (new) 用于对比的新目录;
    • -r (relative) 补丁包根目录相对于安装目录的位置,有时可能只针对安装目录的某个子目录进行 patch;
    • -x (output) 输出补丁包的目录;
    • -v (version) 补丁包版本号,写入配置文件用;
    • -s (serial pack) 补丁号,写入配置文件用;
    • -t (verbose) 详细输出;
    • -e (exact mode) 配置文件中增加和替换文件项将按每项对应一段 json 的方式精确设置,否则按整个目录递归覆盖设置。
  • 72-77:空路径校验;
  • 79-83:替换路径中的反斜杠为斜杠,因 shell 会将反斜杠识别为转义字符的开始;
  • 85-93:打印识别后的各选项,方便出问题时排错;
  • 95-120:路径校验,包括:
    • 对比目录不得为普通文件;
    • 输出目录不得含有文件(防止将中间对比结果和上一次或其它对比结果放在一起打包);
    • 剔除输出目录与相对目录的结尾斜杠(方便后续处理)。
  • 122-137:中间变量的定义,包含反编译中间文件、目录对比中间文件、忽略文件模式的中间文件以及生成配置文件的 json 头和尾;
  • 139-149:在对比目录时,用户可以提供一个要忽略的文件模式(pattern)列表,例如不对比 [Dd]ebug、[Ss]ymbol、*.pdb 这些编译中间目录或文件,可以使用正则表达式,每行一个。这里打印这些 pattern 用于排错。

对比目录

经过前期的铺垫,进入第一个重头戏:

 1 if [ -f "$patdiff" ]; then
2 diff -qr "$srcdir" "$dstdir" -X "$patdiff" > "$dirdiff"
3 else
4 diff -qr "$srcdir" "$dstdir" > "$dirdiff"
5 fi
6
7 while read line
8 do
9 if [ $verbose != 0 ]; then
10 echo $line
11 fi
12
13 tmp=$(echo $line | sed -n 's/Files \(.*\) and \(.*\) differ$/\1\\n\2/p')
14 if [ ! -z "$tmp" ]; then
15 left=$(echo -e $tmp | sed -n 1p)
16 right=$(echo -e $tmp | sed -n 2p)
17 if [ $verbose != 0 ]; then
18 echo -e "left =$left, \nright=$right"
19 fi
20 ……
21 else
22 tmp=$(echo $line | sed -n 's/Only in \(.*\): \(.*\)/\1\\n\2/p')
23 if [ ! -z "$tmp" ]; then
24 isdir=0
25 dir=$(echo -e $tmp | sed -n 1p)
26 file=$(echo -e $tmp | sed -n 2p)
27 if [ -d "$dir/$file" ]; then
28 isdir=1
29 fi
30
31 if [ $verbose != 0 ]; then
32 echo "dir=$dir, file=$file, isdir=$isdir"
33 fi
34 ……
35 else
36 echo "unrecognized diff output: $line"
37 fi
38 fi
39 echo ""
40 done < "$dirdiff"

这段代码省略了一些与对比目录无关的内容,便于看清整个大的流程:

  • 1-5:根据是否有忽略模式文件来调用 diff,当存在这种文件时(上文中的 139-149),增加 -X 选项来添加忽略模式文件到对比目录过程(diff);否则使用简单输出模式(-q)递归(-r)对比目录及其子目录,输出内容保存在 dir.diff 文件中;
  • 7,8,40:遍历 dir.diff 文件内容,根据输出格式的不同,细分为以下几类场景:
    • 两侧都有但文件内容不一致:“Files C:/compare/BIMMAKE.old/BmIGMS/TypeRule4Bimface.json and C:/compare/BIMMAKE/BmIGMS/TypeRule4Bimface.json differ”,通过 sed 匹配例子中高亮部分关键字,就可以分别提取出旧文件与新文件的完整路径(分别为 sed 输出的第一二行,line 13-16);
    • 仅有旧目录有的内容:“Only in C:/compare/BIMMAKE.old/sdk: ViewerConfig.ini”;
    • 仅有新目录有的内容:“Only in C:/compare/BIMMAKE/sdk: Mesh.dll”, 以上两种场景相似,通过 sed 匹配例子中高亮部分关键字,就可以分别提取出目录与文件了(line 22-26),至于是新目录还是旧目录,与新旧根目录做个对比就晓得了,这个后面再说;
    • 两边文件一致:不会有任何输出(这里必需为 diff 命令使用 -q 选项,不然会将文件内容差异也展示出来,那就非常乱了)。下面是一段完整的对比输出(内容超长、展开慎重):
      Files C:/compare/BIMMAKE.old/AppBimmake.exe and C:/compare/BIMMAKE/AppBimmake.exe differ
      Files C:/compare/BIMMAKE.old/AppBimmakeImpl.dll and C:/compare/BIMMAKE/AppBimmakeImpl.dll differ
      Files C:/compare/BIMMAKE.old/AppComponentEditor.exe and C:/compare/BIMMAKE/AppComponentEditor.exe differ
      Files C:/compare/BIMMAKE.old/AppComponentEditorImpl.dll and C:/compare/BIMMAKE/AppComponentEditorImpl.dll differ
      Only in C:/compare/BIMMAKE: AppSocketPortConfig.exe
      Only in C:/compare/BIMMAKE: AppSocketPortConfigImpl.dll
      Files C:/compare/BIMMAKE.old/BIMMAKE/Templates/bmDefaultTemplate.gbp and C:/compare/BIMMAKE/BIMMAKE/Templates/bmDefaultTemplate.gbp differ
      Files C:/compare/BIMMAKE.old/BmAnimation.dll and C:/compare/BIMMAKE/BmAnimation.dll differ
      Files C:/compare/BIMMAKE.old/BmAnimationScript.dll and C:/compare/BIMMAKE/BmAnimationScript.dll differ
      Only in C:/compare/BIMMAKE: BmAppSetting.xml
      Files C:/compare/BIMMAKE.old/BmCommonDraw.dll and C:/compare/BIMMAKE/BmCommonDraw.dll differ
      Files C:/compare/BIMMAKE.old/BmCommonEdit.dll and C:/compare/BIMMAKE/BmCommonEdit.dll differ
      Files C:/compare/BIMMAKE.old/BmDataExchange.dll and C:/compare/BIMMAKE/BmDataExchange.dll differ
      Files C:/compare/BIMMAKE.old/BmDrawingExport.dll and C:/compare/BIMMAKE/BmDrawingExport.dll differ
      Files C:/compare/BIMMAKE.old/BmFalcon.dll and C:/compare/BIMMAKE/BmFalcon.dll differ
      Files C:/compare/BIMMAKE.old/BmFamilyBridge.dll and C:/compare/BIMMAKE/BmFamilyBridge.dll differ
      Files C:/compare/BIMMAKE.old/BmGbmpModel.dll and C:/compare/BIMMAKE/BmGbmpModel.dll differ
      Files C:/compare/BIMMAKE.old/BmGbmpUiPlatform.dll and C:/compare/BIMMAKE/BmGbmpUiPlatform.dll differ
      Files C:/compare/BIMMAKE.old/BmGgpUtility.dll and C:/compare/BIMMAKE/BmGgpUtility.dll differ
      Files C:/compare/BIMMAKE.old/BmGuxActionConfig.json and C:/compare/BIMMAKE/BmGuxActionConfig.json differ
      Files C:/compare/BIMMAKE.old/BmHotKeyConfig.xml and C:/compare/BIMMAKE/BmHotKeyConfig.xml differ
      Files C:/compare/BIMMAKE.old/BmIGMS/TypeRule.json and C:/compare/BIMMAKE/BmIGMS/TypeRule.json differ
      Files C:/compare/BIMMAKE.old/BmIGMS/TypeRule4Bimface.json and C:/compare/BIMMAKE/BmIGMS/TypeRule4Bimface.json differ
      Files C:/compare/BIMMAKE.old/BmIGMSExport.dll and C:/compare/BIMMAKE/BmIGMSExport.dll differ
      Files C:/compare/BIMMAKE.old/BmImportGfc.dll and C:/compare/BIMMAKE/BmImportGfc.dll differ
      Files C:/compare/BIMMAKE.old/BmImportIfc.dll and C:/compare/BIMMAKE/BmImportIfc.dll differ
      Files C:/compare/BIMMAKE.old/BmInterOpRevitProject.dll and C:/compare/BIMMAKE/BmInterOpRevitProject.dll differ
      Files C:/compare/BIMMAKE.old/BmInteraction.dll and C:/compare/BIMMAKE/BmInteraction.dll differ
      Files C:/compare/BIMMAKE.old/BmLicense.dll and C:/compare/BIMMAKE/BmLicense.dll differ
      Files C:/compare/BIMMAKE.old/BmModel.dll and C:/compare/BIMMAKE/BmModel.dll differ
      Files C:/compare/BIMMAKE.old/BmMultiThreadNetwork.dll and C:/compare/BIMMAKE/BmMultiThreadNetwork.dll differ
      Files C:/compare/BIMMAKE.old/BmPositioningElements.dll and C:/compare/BIMMAKE/BmPositioningElements.dll differ
      Files C:/compare/BIMMAKE.old/BmRebar.dll and C:/compare/BIMMAKE/BmRebar.dll differ
      Only in C:/compare/BIMMAKE.old: BmRecentDocumentPathRecord.xml
      Files C:/compare/BIMMAKE.old/BmSiteLayout.dll and C:/compare/BIMMAKE/BmSiteLayout.dll differ
      Files C:/compare/BIMMAKE.old/BmSiteLayoutFamily.dll and C:/compare/BIMMAKE/BmSiteLayoutFamily.dll differ
      Files C:/compare/BIMMAKE.old/BmSiteLayoutUi.dll and C:/compare/BIMMAKE/BmSiteLayoutUi.dll differ
      Files C:/compare/BIMMAKE.old/BmStructure.dll and C:/compare/BIMMAKE/BmStructure.dll differ
      Files C:/compare/BIMMAKE.old/BmStructureFamily.dll and C:/compare/BIMMAKE/BmStructureFamily.dll differ
      Files C:/compare/BIMMAKE.old/BmSurfaceSystem.dll and C:/compare/BIMMAKE/BmSurfaceSystem.dll differ
      Files C:/compare/BIMMAKE.old/BmTeighaUtility.dll and C:/compare/BIMMAKE/BmTeighaUtility.dll differ
      Files C:/compare/BIMMAKE.old/BmTest.dll and C:/compare/BIMMAKE/BmTest.dll differ
      Files C:/compare/BIMMAKE.old/BmThirdPartyUpdate.dll and C:/compare/BIMMAKE/BmThirdPartyUpdate.dll differ
      Files C:/compare/BIMMAKE.old/BmUiAnimation.dll and C:/compare/BIMMAKE/BmUiAnimation.dll differ
      Files C:/compare/BIMMAKE.old/BmUiAnimationWidget.dll and C:/compare/BIMMAKE/BmUiAnimationWidget.dll differ
      Files C:/compare/BIMMAKE.old/BmUiCommonComponent.dll and C:/compare/BIMMAKE/BmUiCommonComponent.dll differ
      Files C:/compare/BIMMAKE.old/BmUiDataExchange.dll and C:/compare/BIMMAKE/BmUiDataExchange.dll differ
      Files C:/compare/BIMMAKE.old/BmUiInplaceEdit.dll and C:/compare/BIMMAKE/BmUiInplaceEdit.dll differ
      Files C:/compare/BIMMAKE.old/BmUiPlatform.dll and C:/compare/BIMMAKE/BmUiPlatform.dll differ
      Files C:/compare/BIMMAKE.old/BmUiReBar.dll and C:/compare/BIMMAKE/BmUiReBar.dll differ
      Files C:/compare/BIMMAKE.old/BmUiStructure.dll and C:/compare/BIMMAKE/BmUiStructure.dll differ
      Files C:/compare/BIMMAKE.old/BmUiVisual.dll and C:/compare/BIMMAKE/BmUiVisual.dll differ
      Files C:/compare/BIMMAKE.old/BmVisualModel.dll and C:/compare/BIMMAKE/BmVisualModel.dll differ
      Files C:/compare/BIMMAKE.old/BmWelcomeTemplateFile/MjTemplateFile.xml and C:/compare/BIMMAKE/BmWelcomeTemplateFile/MjTemplateFile.xml differ
      Files C:/compare/BIMMAKE.old/BmWelcomeTemplateFile/二次结构砌体.gbp and C:/compare/BIMMAKE/BmWelcomeTemplateFile/二次结构砌体.gbp differ
      Files C:/compare/BIMMAKE.old/BmWelcomeTemplateFile/二次结构砌体.png and C:/compare/BIMMAKE/BmWelcomeTemplateFile/二次结构砌体.png differ
      Only in C:/compare/BIMMAKE.old/BmWelcomeTemplateFile: 小别墅.gbp
      Only in C:/compare/BIMMAKE.old/BmWelcomeTemplateFile: 小别墅.png
      Files C:/compare/BIMMAKE.old/BmWelcomeTemplateFile/施工场地布置.gbp and C:/compare/BIMMAKE/BmWelcomeTemplateFile/施工场地布置.gbp differ
      Files C:/compare/BIMMAKE.old/BmWelcomeTemplateFile/施工场地布置.png and C:/compare/BIMMAKE/BmWelcomeTemplateFile/施工场地布置.png differ
      Only in C:/compare/BIMMAKE/BmWelcomeTemplateFile: 木模板配模.gbp
      Only in C:/compare/BIMMAKE/BmWelcomeTemplateFile: 木模板配模.png
      Only in C:/compare/BIMMAKE.old/BmWelcomeTemplateFile: 老虎窗屋顶.gbp
      Only in C:/compare/BIMMAKE.old/BmWelcomeTemplateFile: 老虎窗屋顶.png
      Only in C:/compare/BIMMAKE/BmWelcomeTemplateFile: 钢筋节点深化.gbp
      Only in C:/compare/BIMMAKE/BmWelcomeTemplateFile: 钢筋节点深化.png
      Files C:/compare/BIMMAKE.old/CadIdentifier/ArchiAlgo.dll and C:/compare/BIMMAKE/CadIdentifier/ArchiAlgo.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/BarInfo.GDB and C:/compare/BIMMAKE/CadIdentifier/BarInfo.GDB differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/BarInfo.GDB.back and C:/compare/BIMMAKE/CadIdentifier/BarInfo.GDB.back differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/CadIdentifier2018.exe and C:/compare/BIMMAKE/CadIdentifier/CadIdentifier2018.exe differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/CmdCore.dll and C:/compare/BIMMAKE/CadIdentifier/CmdCore.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/Common.dll and C:/compare/BIMMAKE/CadIdentifier/Common.dll differ
      Only in C:/compare/BIMMAKE.old/CadIdentifier: DBErrorReport.txt
      Files C:/compare/BIMMAKE.old/CadIdentifier/DBOperations.dll and C:/compare/BIMMAKE/CadIdentifier/DBOperations.dll differ
      Only in C:/compare/BIMMAKE/CadIdentifier: Fonts
      Files C:/compare/BIMMAKE.old/CadIdentifier/GCADIdentification.dll and C:/compare/BIMMAKE/CadIdentifier/GCADIdentification.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GCADModel.dll and C:/compare/BIMMAKE/CadIdentifier/GCADModel.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GCLDataService.dll and C:/compare/BIMMAKE/CadIdentifier/GCLDataService.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GCLProjectDataHelper.dll and C:/compare/BIMMAKE/CadIdentifier/GCLProjectDataHelper.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GCPPMProjDataHelper.dll and C:/compare/BIMMAKE/CadIdentifier/GCPPMProjDataHelper.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GEPEngine.dll and C:/compare/BIMMAKE/CadIdentifier/GEPEngine.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GFCCommon.dll and C:/compare/BIMMAKE/CadIdentifier/GFCCommon.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GGDB.dll and C:/compare/BIMMAKE/CadIdentifier/GGDB.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GGDBDataAwareCtrl.dll and C:/compare/BIMMAKE/CadIdentifier/GGDBDataAwareCtrl.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GGJProjectDataHelper.dll and C:/compare/BIMMAKE/CadIdentifier/GGJProjectDataHelper.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GGJSectionBarEditor.dll and C:/compare/BIMMAKE/CadIdentifier/GGJSectionBarEditor.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GGPViewerProxy.dll and C:/compare/BIMMAKE/CadIdentifier/GGPViewerProxy.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDCommon.dll and C:/compare/BIMMAKE/CadIdentifier/GLDCommon.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDCrypt.dll and C:/compare/BIMMAKE/CadIdentifier/GLDCrypt.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDPrivateCalledPlatform.dll and C:/compare/BIMMAKE/CadIdentifier/GLDPrivateCalledPlatform.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDStyles.dll and C:/compare/BIMMAKE/CadIdentifier/GLDStyles.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDTableView.dll and C:/compare/BIMMAKE/CadIdentifier/GLDTableView.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDThemeEngine.dll and C:/compare/BIMMAKE/CadIdentifier/GLDThemeEngine.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDWidget.dll and C:/compare/BIMMAKE/CadIdentifier/GLDWidget.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDXML.dll and C:/compare/BIMMAKE/CadIdentifier/GLDXML.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GLDZip.dll and C:/compare/BIMMAKE/CadIdentifier/GLDZip.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GMCommon.dll and C:/compare/BIMMAKE/CadIdentifier/GMCommon.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GMJ.dll and C:/compare/BIMMAKE/CadIdentifier/GMJ.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GMModel.dll and C:/compare/BIMMAKE/CadIdentifier/GMModel.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GMPControls.dll and C:/compare/BIMMAKE/CadIdentifier/GMPControls.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GMPCore.dll and C:/compare/BIMMAKE/CadIdentifier/GMPCore.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GMPRibbonStyle.dll and C:/compare/BIMMAKE/CadIdentifier/GMPRibbonStyle.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GMPUIExtends.dll and C:/compare/BIMMAKE/CadIdentifier/GMPUIExtends.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GMath.dll and C:/compare/BIMMAKE/CadIdentifier/GMath.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GP.dll and C:/compare/BIMMAKE/CadIdentifier/GP.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GRPCommon.dll and C:/compare/BIMMAKE/CadIdentifier/GRPCommon.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GRPEngine.dll and C:/compare/BIMMAKE/CadIdentifier/GRPEngine.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GSP.dll and C:/compare/BIMMAKE/CadIdentifier/GSP.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GSPEngine.dll and C:/compare/BIMMAKE/CadIdentifier/GSPEngine.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTCADImporter.dll and C:/compare/BIMMAKE/CadIdentifier/GTCADImporter.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJBodyBuilder.dll and C:/compare/BIMMAKE/CadIdentifier/GTJBodyBuilder.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJCADBeamIdentifier.dll and C:/compare/BIMMAKE/CadIdentifier/GTJCADBeamIdentifier.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJCADCmdState.dll and C:/compare/BIMMAKE/CadIdentifier/GTJCADCmdState.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJCADColumnDetailIdentifier.dll and C:/compare/BIMMAKE/CadIdentifier/GTJCADColumnDetailIdentifier.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJCADCommonAlgorithm.dll and C:/compare/BIMMAKE/CadIdentifier/GTJCADCommonAlgorithm.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJCADIdentifier.dll and C:/compare/BIMMAKE/CadIdentifier/GTJCADIdentifier.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJCADPlugin.dll and C:/compare/BIMMAKE/CadIdentifier/GTJCADPlugin.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJCalcDomainModel.dll and C:/compare/BIMMAKE/CadIdentifier/GTJCalcDomainModel.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJCalcExtension.dll and C:/compare/BIMMAKE/CadIdentifier/GTJCalcExtension.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJDomainModel.dll and C:/compare/BIMMAKE/CadIdentifier/GTJDomainModel.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJGeneralAlgorithm.dll and C:/compare/BIMMAKE/CadIdentifier/GTJGeneralAlgorithm.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJGeneralUtility.dll and C:/compare/BIMMAKE/CadIdentifier/GTJGeneralUtility.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJModelCmdState.dll and C:/compare/BIMMAKE/CadIdentifier/GTJModelCmdState.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJModelDAO.dll and C:/compare/BIMMAKE/CadIdentifier/GTJModelDAO.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJModelExtension.dll and C:/compare/BIMMAKE/CadIdentifier/GTJModelExtension.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJModelPlugin.dll and C:/compare/BIMMAKE/CadIdentifier/GTJModelPlugin.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJProjectDataHelper.dll and C:/compare/BIMMAKE/CadIdentifier/GTJProjectDataHelper.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTJUIModule.dll and C:/compare/BIMMAKE/CadIdentifier/GTJUIModule.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GTTchEntity_4.00_10.tx and C:/compare/BIMMAKE/CadIdentifier/GTTchEntity_4.00_10.tx differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GUC.dll and C:/compare/BIMMAKE/CadIdentifier/GUC.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/Geometry.dll and C:/compare/BIMMAKE/CadIdentifier/Geometry.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/GfcClasses.dll and C:/compare/BIMMAKE/CadIdentifier/GfcClasses.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/Layout and C:/compare/BIMMAKE/CadIdentifier/Layout differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/MDCache.dll and C:/compare/BIMMAKE/CadIdentifier/MDCache.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/MDCmdLog.dll and C:/compare/BIMMAKE/CadIdentifier/MDCmdLog.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/MDCommon.dll and C:/compare/BIMMAKE/CadIdentifier/MDCommon.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/MDScript.dll and C:/compare/BIMMAKE/CadIdentifier/MDScript.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/MaterialCore.dll and C:/compare/BIMMAKE/CadIdentifier/MaterialCore.dll differ
      Only in C:/compare/BIMMAKE/CadIdentifier: Microsoft.DTfW.DHL.manifest
      Files C:/compare/BIMMAKE.old/CadIdentifier/RenderSystemAngle.dll and C:/compare/BIMMAKE/CadIdentifier/RenderSystemAngle.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/RenderSystemGL.dll and C:/compare/BIMMAKE/CadIdentifier/RenderSystemGL.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/Ubc.dll and C:/compare/BIMMAKE/CadIdentifier/Ubc.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/UserInfo.GDB and C:/compare/BIMMAKE/CadIdentifier/UserInfo.GDB differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/UserInfo.GDB.ggdblog.dat and C:/compare/BIMMAKE/CadIdentifier/UserInfo.GDB.ggdblog.dat differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/VDECore.dll and C:/compare/BIMMAKE/CadIdentifier/VDECore.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/VectorDrawing.dll and C:/compare/BIMMAKE/CadIdentifier/VectorDrawing.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/ViewCore.dll and C:/compare/BIMMAKE/CadIdentifier/ViewCore.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/ViewManager.dll and C:/compare/BIMMAKE/CadIdentifier/ViewManager.dll differ
      Only in C:/compare/BIMMAKE/CadIdentifier: filedialog.ini
      Files C:/compare/BIMMAKE.old/CadIdentifier/gsolver.dll and C:/compare/BIMMAKE/CadIdentifier/gsolver.dll differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/skin/CoolDark.rcc and C:/compare/BIMMAKE/CadIdentifier/skin/CoolDark.rcc differ
      Files C:/compare/BIMMAKE.old/CadIdentifier/skin/SilveryWhite.rcc and C:/compare/BIMMAKE/CadIdentifier/skin/SilveryWhite.rcc differ
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 倒棱台独立基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 偏心二阶独立基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 双台双杯口独立基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 四棱锥台形独立基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 四棱锥台形独立基础带柱.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 带短柱杯口独立基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 底偏心矩形独立基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 杯形基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 独立基础三台.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 独立基础三台有杯口.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 独立基础双层带坡.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 等高砖大放脚独立基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 锥台杯形独立基础.gac
      Only in C:/compare/BIMMAKE/ComponentEditor/Templates/GFCFamily: 顶偏心矩形独立基础.gac
      Files C:/compare/BIMMAKE.old/ComponentEditorUiConfiguration.dll and C:/compare/BIMMAKE/ComponentEditorUiConfiguration.dll differ
      Files C:/compare/BIMMAKE.old/ComponentEditorUiPlatform.dll and C:/compare/BIMMAKE/ComponentEditorUiPlatform.dll differ
      Only in C:/compare/BIMMAKE: CopyLibraries.bat
      Files C:/compare/BIMMAKE.old/CopyTemplates.bat and C:/compare/BIMMAKE/CopyTemplates.bat differ
      Only in C:/compare/BIMMAKE: Crx.dll
      Only in C:/compare/BIMMAKE: CrxDb.dll
      Only in C:/compare/BIMMAKE: CrxGe.dll
      Only in C:/compare/BIMMAKE: CrxSpt.dll
      Only in C:/compare/BIMMAKE: DbAnnotate.dll
      Only in C:/compare/BIMMAKE: DbBase.dll
      Only in C:/compare/BIMMAKE: DbBom.dll
      Only in C:/compare/BIMMAKE: DbCurve.dll
      Only in C:/compare/BIMMAKE: DbEntity.dll
      Only in C:/compare/BIMMAKE: DbStandard.dll
      Only in C:/compare/BIMMAKE: DbStyle.dll
      Only in C:/compare/BIMMAKE: DbText.dll
      Only in C:/compare/BIMMAKE: Debug.ini
      Only in C:/compare/BIMMAKE: DeleteLibraries.bat
      Only in C:/compare/BIMMAKE: DftConfig.dll
      Only in C:/compare/BIMMAKE: DftDb.dll
      Files C:/compare/BIMMAKE.old/FamilyCategories.xml and C:/compare/BIMMAKE/FamilyCategories.xml differ
      Files C:/compare/BIMMAKE.old/FamilyDialogLauout.xml and C:/compare/BIMMAKE/FamilyDialogLauout.xml differ
      Only in C:/compare/BIMMAKE: FillPatternFileApiTestData
      Files C:/compare/BIMMAKE.old/GGPMaterialService.dll and C:/compare/BIMMAKE/GGPMaterialService.dll differ
      Files C:/compare/BIMMAKE.old/GGPMaterialUI.dll and C:/compare/BIMMAKE/GGPMaterialUI.dll differ
      Only in C:/compare/BIMMAKE.old: GPUDriverConfig.ini
      Files C:/compare/BIMMAKE.old/GVideoFFmpeg.dll and C:/compare/BIMMAKE/GVideoFFmpeg.dll differ
      Only in C:/compare/BIMMAKE: GbmpModel.dll
      Files C:/compare/BIMMAKE.old/Gcmp3ds.dll and C:/compare/BIMMAKE/Gcmp3ds.dll differ
      Files C:/compare/BIMMAKE.old/GcmpApplication.dll and C:/compare/BIMMAKE/GcmpApplication.dll differ
      Files C:/compare/BIMMAKE.old/GcmpApplicationImpl.dll and C:/compare/BIMMAKE/GcmpApplicationImpl.dll differ
      Files C:/compare/BIMMAKE.old/GcmpApplicationInterface.dll and C:/compare/BIMMAKE/GcmpApplicationInterface.dll differ
      Files C:/compare/BIMMAKE.old/GcmpCommandAction.dll and C:/compare/BIMMAKE/GcmpCommandAction.dll differ
      Files C:/compare/BIMMAKE.old/GcmpCommonDraw.dll and C:/compare/BIMMAKE/GcmpCommonDraw.dll differ
      Files C:/compare/BIMMAKE.old/GcmpCommonEdit.dll and C:/compare/BIMMAKE/GcmpCommonEdit.dll differ
      Files C:/compare/BIMMAKE.old/GcmpDebug.dll and C:/compare/BIMMAKE/GcmpDebug.dll differ
      Only in C:/compare/BIMMAKE: GcmpDrawingEdit.dll
      Only in C:/compare/BIMMAKE: GcmpDrawingText.dll
      Files C:/compare/BIMMAKE.old/GcmpDwgDxf.dll and C:/compare/BIMMAKE/GcmpDwgDxf.dll differ
      Files C:/compare/BIMMAKE.old/GcmpGuiInterface.dll and C:/compare/BIMMAKE/GcmpGuiInterface.dll differ
      Only in C:/compare/BIMMAKE: GcmpGuiMainFrame.dll
      Files C:/compare/BIMMAKE.old/GcmpGuiQt.dll and C:/compare/BIMMAKE/GcmpGuiQt.dll differ
      Files C:/compare/BIMMAKE.old/GcmpIntrinsicGuids.json and C:/compare/BIMMAKE/GcmpIntrinsicGuids.json differ
      Files C:/compare/BIMMAKE.old/GcmpJournal.dll and C:/compare/BIMMAKE/GcmpJournal.dll differ
      Files C:/compare/BIMMAKE.old/GcmpLocatorCommands.dll and C:/compare/BIMMAKE/GcmpLocatorCommands.dll differ
      Files C:/compare/BIMMAKE.old/GcmpSkpGGP.dll and C:/compare/BIMMAKE/GcmpSkpGGP.dll differ
      Files C:/compare/BIMMAKE.old/GcmpSkpInterface.dll and C:/compare/BIMMAKE/GcmpSkpInterface.dll differ
      Only in C:/compare/BIMMAKE: GcmpSocketPortConfigData.dll
      Files C:/compare/BIMMAKE.old/GcmpTestFamily.dll and C:/compare/BIMMAKE/GcmpTestFamily.dll differ
      Files C:/compare/BIMMAKE.old/GcmpThirdPartyUpdate.dll and C:/compare/BIMMAKE/GcmpThirdPartyUpdate.dll differ
      Only in C:/compare/BIMMAKE: GcmpUiCommandAction.dll
      Files C:/compare/BIMMAKE.old/GcmpUiDrawingExportFamily.dll and C:/compare/BIMMAKE/GcmpUiDrawingExportFamily.dll differ
      Files C:/compare/BIMMAKE.old/GcmpUiPlatform.dll and C:/compare/BIMMAKE/GcmpUiPlatform.dll differ
      Files C:/compare/BIMMAKE.old/GcmpUiPlatformFamily.dll and C:/compare/BIMMAKE/GcmpUiPlatformFamily.dll differ
      Only in C:/compare/BIMMAKE: GcmpUiView.dll
      Only in C:/compare/BIMMAKE: GcmpUiViewInterface.dll
      Files C:/compare/BIMMAKE.old/GcmpViewCommands.dll and C:/compare/BIMMAKE/GcmpViewCommands.dll differ
      Files C:/compare/BIMMAKE.old/GmAPITest.dll and C:/compare/BIMMAKE/GmAPITest.dll differ
      Files C:/compare/BIMMAKE.old/GmCloudStorage.dll and C:/compare/BIMMAKE/GmCloudStorage.dll differ
      Files C:/compare/BIMMAKE.old/GmCloudStorageQtImp.dll and C:/compare/BIMMAKE/GmCloudStorageQtImp.dll differ
      Files C:/compare/BIMMAKE.old/GmConstruction.dll and C:/compare/BIMMAKE/GmConstruction.dll differ
      Files C:/compare/BIMMAKE.old/GmDataSynchronization.dll and C:/compare/BIMMAKE/GmDataSynchronization.dll differ
      Files C:/compare/BIMMAKE.old/GmInplaceEdit.dll and C:/compare/BIMMAKE/GmInplaceEdit.dll differ
      Only in C:/compare/BIMMAKE: GmPositioningElements.dll
      Files C:/compare/BIMMAKE.old/GmUiCommonComponent.dll and C:/compare/BIMMAKE/GmUiCommonComponent.dll differ
      Files C:/compare/BIMMAKE.old/GmUiInplaceEditCommon.dll and C:/compare/BIMMAKE/GmUiInplaceEditCommon.dll differ
      Files C:/compare/BIMMAKE.old/GmUiInplaceEditFamily.dll and C:/compare/BIMMAKE/GmUiInplaceEditFamily.dll differ
      Files C:/compare/BIMMAKE.old/GmUiModelFamily.dll and C:/compare/BIMMAKE/GmUiModelFamily.dll differ
      Only in C:/compare/BIMMAKE: GmUiPlatform.dll
      Files C:/compare/BIMMAKE.old/GuxClient.dll and C:/compare/BIMMAKE/GuxClient.dll differ
      Files C:/compare/BIMMAKE.old/HardWareInfo.dll and C:/compare/BIMMAKE/HardWareInfo.dll differ
      Files C:/compare/BIMMAKE.old/InstallGbmpAddin.exe and C:/compare/BIMMAKE/InstallGbmpAddin.exe differ
      Files C:/compare/BIMMAKE.old/InterOpGBMP2014.dll and C:/compare/BIMMAKE/InterOpGBMP2014.dll differ
      Files C:/compare/BIMMAKE.old/InterOpGBMP2015.dll and C:/compare/BIMMAKE/InterOpGBMP2015.dll differ
      Files C:/compare/BIMMAKE.old/InterOpGBMP2016.dll and C:/compare/BIMMAKE/InterOpGBMP2016.dll differ
      Files C:/compare/BIMMAKE.old/InterOpGBMP2017.dll and C:/compare/BIMMAKE/InterOpGBMP2017.dll differ
      Files C:/compare/BIMMAKE.old/InterOpGBMP2018.dll and C:/compare/BIMMAKE/InterOpGBMP2018.dll differ
      Files C:/compare/BIMMAKE.old/InterOpGBMP2019.dll and C:/compare/BIMMAKE/InterOpGBMP2019.dll differ
      Files C:/compare/BIMMAKE.old/InterOpGBMP2020.dll and C:/compare/BIMMAKE/InterOpGBMP2020.dll differ
      Files C:/compare/BIMMAKE.old/InterOpGBMPHelper.exe and C:/compare/BIMMAKE/InterOpGBMPHelper.exe differ
      Files C:/compare/BIMMAKE.old/InterOpRevitConfig.xml and C:/compare/BIMMAKE/InterOpRevitConfig.xml differ
      Files C:/compare/BIMMAKE.old/InterOpRevitFamily.dll and C:/compare/BIMMAKE/InterOpRevitFamily.dll differ
      Files C:/compare/BIMMAKE.old/KillProcess.bat and C:/compare/BIMMAKE/KillProcess.bat differ
      Only in C:/compare/BIMMAKE: KnlAPIBase.dll
      Only in C:/compare/BIMMAKE: KnlModuleManager.dll
      Only in C:/compare/BIMMAKE: KnlProfile.dll
      Only in C:/compare/BIMMAKE: KnlXmlParser.dll
      Only in C:/compare/BIMMAKE: Libraries
      Only in C:/compare/BIMMAKE: MDLMechanical.dll
      Files C:/compare/BIMMAKE.old/MaterialLibraryApplication.dll and C:/compare/BIMMAKE/MaterialLibraryApplication.dll differ
      Files C:/compare/BIMMAKE.old/MaterialUI.dll and C:/compare/BIMMAKE/MaterialUI.dll differ
      Files C:/compare/BIMMAKE.old/MjArithmetic.dll and C:/compare/BIMMAKE/MjArithmetic.dll differ
      Files C:/compare/BIMMAKE.old/MjCaculateModel.dll and C:/compare/BIMMAKE/MjCaculateModel.dll differ
      Files C:/compare/BIMMAKE.old/MjCommon.dll and C:/compare/BIMMAKE/MjCommon.dll differ
      Files C:/compare/BIMMAKE.old/MjDeliverables.dll and C:/compare/BIMMAKE/MjDeliverables.dll differ
      Files C:/compare/BIMMAKE.old/MjGeometryGGP.dll and C:/compare/BIMMAKE/MjGeometryGGP.dll differ
      Only in C:/compare/BIMMAKE.old: MjLicense.dll
      Files C:/compare/BIMMAKE.old/MjOperationScaffoldModel.dll and C:/compare/BIMMAKE/MjOperationScaffoldModel.dll differ
      Files C:/compare/BIMMAKE.old/MjPracticeModel.dll and C:/compare/BIMMAKE/MjPracticeModel.dll differ
      Files C:/compare/BIMMAKE.old/MjQtGuiImplementation.dll and C:/compare/BIMMAKE/MjQtGuiImplementation.dll differ
      Only in C:/compare/BIMMAKE.old: MjRichTextEditor.dll
      Files C:/compare/BIMMAKE.old/MjScaffoldModel.dll and C:/compare/BIMMAKE/MjScaffoldModel.dll differ
      Files C:/compare/BIMMAKE.old/MjShoringScaffoldModel.dll and C:/compare/BIMMAKE/MjShoringScaffoldModel.dll differ
      Files C:/compare/BIMMAKE.old/MjStructureComponent.dll and C:/compare/BIMMAKE/MjStructureComponent.dll differ
      Only in C:/compare/BIMMAKE.old: MjUIArchitecture.dll
      Files C:/compare/BIMMAKE.old/MjUIPlatform.dll and C:/compare/BIMMAKE/MjUIPlatform.dll differ
      Files C:/compare/BIMMAKE.old/MjUIScaffoldArrangement.dll and C:/compare/BIMMAKE/MjUIScaffoldArrangement.dll differ
      Files C:/compare/BIMMAKE.old/MjUITool.dll and C:/compare/BIMMAKE/MjUITool.dll differ
      Only in C:/compare/BIMMAKE.old: Packing4Rendering.dll
      Only in C:/compare/BIMMAKE: Peimo.exe
      Files C:/compare/BIMMAKE.old/QCefView.dll and C:/compare/BIMMAKE/QCefView.dll differ
      Only in C:/compare/BIMMAKE.old: QProfile.txt
      Files C:/compare/BIMMAKE.old/QtCommonWidget.dll and C:/compare/BIMMAKE/QtCommonWidget.dll differ
      Only in C:/compare/BIMMAKE.old: RecentDocumentPathRecord.xml
      Files C:/compare/BIMMAKE.old/RecordInstall.bat and C:/compare/BIMMAKE/RecordInstall.bat differ
      Files C:/compare/BIMMAKE.old/RecordUninstall.bat and C:/compare/BIMMAKE/RecordUninstall.bat differ
      Files C:/compare/BIMMAKE.old/RemoveFiles.bat and C:/compare/BIMMAKE/RemoveFiles.bat differ
      Files C:/compare/BIMMAKE.old/Revision.txt and C:/compare/BIMMAKE/Revision.txt differ
      Files C:/compare/BIMMAKE.old/ServiceView.dll and C:/compare/BIMMAKE/ServiceView.dll differ
      Only in C:/compare/BIMMAKE/Share/ViewCoreResources/MaterialLibrary/textures: rainTextures
      Only in C:/compare/BIMMAKE/Share/ViewCoreResources/MaterialLibrary/textures: rainTexturesAmbient
      Only in C:/compare/BIMMAKE/Share/ViewCoreResources/Shaders: DoubleSideShader
      Only in C:/compare/BIMMAKE/Share/ViewCoreResources/Shaders: Particle
      Only in C:/compare/BIMMAKE/Share/ViewCoreResources/Shaders: Rain
      Only in C:/compare/BIMMAKE: SptCx.dll
      Only in C:/compare/BIMMAKE: SptCxGe.dll
      Only in C:/compare/BIMMAKE: SptCxMath.dll
      Only in C:/compare/BIMMAKE: SptGe.dll
      Only in C:/compare/BIMMAKE: SptGi.dll
      Only in C:/compare/BIMMAKE: SptMath.dll
      Only in C:/compare/BIMMAKE: SptNLS.dll
      Only in C:/compare/BIMMAKE: SysFactory.dll
      Files C:/compare/BIMMAKE.old/Teigha/ACCAMERA_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/ACCAMERA_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/ATEXT_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/ATEXT_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/AcMPolygonObj15_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/AcMPolygonObj15_20.8src_14.tx differ
      Only in C:/compare/BIMMAKE/Teigha: GripPoints_20.8src_14.tx
      Files C:/compare/BIMMAKE.old/Teigha/ISM_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/ISM_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/PDFiumModule_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/PDFiumModule_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/RText_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/RText_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/RxRasterServices_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/RxRasterServices_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/SCENEOE_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/SCENEOE_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_Alloc_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_Alloc_20.8src_14.dll differ
      Only in C:/compare/BIMMAKE/Teigha: TD_Ave_20.8src_14.tx
      Files C:/compare/BIMMAKE.old/Teigha/TD_DbCore_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_DbCore_20.8src_14.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_DbEntities_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/TD_DbEntities_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_DbIO_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/TD_DbIO_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_DbRoot_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_DbRoot_20.8src_14.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_Db_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_Db_20.8src_14.dll differ
      Only in C:/compare/BIMMAKE/Teigha: TD_DynBlocks_20.8src_14.tx
      Files C:/compare/BIMMAKE.old/Teigha/TD_Ge_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_Ge_20.8src_14.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_Gi_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_Gi_20.8src_14.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_Gs_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_Gs_20.8src_14.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_PdfImport_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/TD_PdfImport_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_Pdfium.dll and C:/compare/BIMMAKE/Teigha/TD_Pdfium.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_Root_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_Root_20.8src_14.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_SpatialIndex_20.8src_14.dll and C:/compare/BIMMAKE/Teigha/TD_SpatialIndex_20.8src_14.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/TD_Zlib.dll and C:/compare/BIMMAKE/Teigha/TD_Zlib.dll differ
      Files C:/compare/BIMMAKE.old/Teigha/WipeOut_20.8src_14.tx and C:/compare/BIMMAKE/Teigha/WipeOut_20.8src_14.tx differ
      Files C:/compare/BIMMAKE.old/TeighaUtility.dll and C:/compare/BIMMAKE/TeighaUtility.dll differ
      Files C:/compare/BIMMAKE.old/UE4JsonExporter.dll and C:/compare/BIMMAKE/UE4JsonExporter.dll differ
      Only in C:/compare/BIMMAKE.old: ViewerConfig.ini
      Files C:/compare/BIMMAKE.old/ViewerTileMerger.exe and C:/compare/BIMMAKE/ViewerTileMerger.exe differ
      Only in C:/compare/BIMMAKE.old: algorithmLog.ini
      Files C:/compare/BIMMAKE.old/bimmake_ver.txt and C:/compare/BIMMAKE/bimmake_ver.txt differ
      Files C:/compare/BIMMAKE.old/bm_category_and_style_config/BIMMAKECategories.xml and C:/compare/BIMMAKE/bm_category_and_style_config/BIMMAKECategories.xml differ
      Files C:/compare/BIMMAKE.old/bm_category_and_style_config/SiteLayoutCategories.xml and C:/compare/BIMMAKE/bm_category_and_style_config/SiteLayoutCategories.xml differ
      Only in C:/compare/BIMMAKE/bm_plugin_config/DB: MjOperationScaffoldModel.addin
      Only in C:/compare/BIMMAKE/bm_plugin_config: MjUIPlatform.addin
      Only in C:/compare/BIMMAKE: en-US
      Files C:/compare/BIMMAKE.old/gbmp_gcmp_behavior_config.xml and C:/compare/BIMMAKE/gbmp_gcmp_behavior_config.xml differ
      Only in C:/compare/BIMMAKE/gbmp_plugin_config: GcmpInternalTest.addin
      Only in C:/compare/BIMMAKE/gbmp_plugin_config: GcmpTest.addin
      Only in C:/compare/BIMMAKE.old: gdpcore.1.txt
      Only in C:/compare/BIMMAKE.old: gdpcore.txt
      Files C:/compare/BIMMAKE.old/journal_config.json and C:/compare/BIMMAKE/journal_config.json differ
      Files C:/compare/BIMMAKE.old/qtcefwing.exe and C:/compare/BIMMAKE/qtcefwing.exe differ
      Files C:/compare/BIMMAKE.old/sdk/AppFamilyServiceProvider.exe and C:/compare/BIMMAKE/sdk/AppFamilyServiceProvider.exe differ
      Files C:/compare/BIMMAKE.old/sdk/AppFamilyServiceProviderImpl.dll and C:/compare/BIMMAKE/sdk/AppFamilyServiceProviderImpl.dll differ
      Files C:/compare/BIMMAKE.old/sdk/ArchiAlgo.dll and C:/compare/BIMMAKE/sdk/ArchiAlgo.dll differ
      Files C:/compare/BIMMAKE.old/sdk/BmFamilyCustomData.dll and C:/compare/BIMMAKE/sdk/BmFamilyCustomData.dll differ
      Only in C:/compare/BIMMAKE/sdk: CGBase.dll
      Files C:/compare/BIMMAKE.old/sdk/CategoryAndStyleDataDataBase/GCMPCategories.xml and C:/compare/BIMMAKE/sdk/CategoryAndStyleDataDataBase/GCMPCategories.xml differ
      Files C:/compare/BIMMAKE.old/sdk/CmdCore.dll and C:/compare/BIMMAKE/sdk/CmdCore.dll differ
      Files C:/compare/BIMMAKE.old/sdk/Common.dll and C:/compare/BIMMAKE/sdk/Common.dll differ
      Files C:/compare/BIMMAKE.old/sdk/ExprEngine.dll and C:/compare/BIMMAKE/sdk/ExprEngine.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GMath.dll and C:/compare/BIMMAKE/sdk/GMath.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GSolver.dll and C:/compare/BIMMAKE/sdk/GSolver.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpActionInterface.dll and C:/compare/BIMMAKE/sdk/GcmpActionInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpAddin.dll and C:/compare/BIMMAKE/sdk/GcmpAddin.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpCollaborationInterface.dll and C:/compare/BIMMAKE/sdk/GcmpCollaborationInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpCommandInterface.dll and C:/compare/BIMMAKE/sdk/GcmpCommandInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpDatabase.dll and C:/compare/BIMMAKE/sdk/GcmpDatabase.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpDatabaseInterface.dll and C:/compare/BIMMAKE/sdk/GcmpDatabaseInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpDbCommonEdit.dll and C:/compare/BIMMAKE/sdk/GcmpDbCommonEdit.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpDevService.dll and C:/compare/BIMMAKE/sdk/GcmpDevService.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpDwgDxfInterface.dll and C:/compare/BIMMAKE/sdk/GcmpDwgDxfInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpFoundation.dll and C:/compare/BIMMAKE/sdk/GcmpFoundation.dll differ
      Only in C:/compare/BIMMAKE/sdk: GcmpGUiBaseImpl.dll
      Only in C:/compare/BIMMAKE/sdk: GcmpGUiBaseInterface.dll
      Files C:/compare/BIMMAKE.old/sdk/GcmpGdcModel.dll and C:/compare/BIMMAKE/sdk/GcmpGdcModel.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpGeometryACIS.dll and C:/compare/BIMMAKE/sdk/GcmpGeometryACIS.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpGeometryGGP.dll and C:/compare/BIMMAKE/sdk/GcmpGeometryGGP.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpGeometryInterface.dll and C:/compare/BIMMAKE/sdk/GcmpGeometryInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpGraphicsNode.dll and C:/compare/BIMMAKE/sdk/GcmpGraphicsNode.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpGraphicsNodeInterface.dll and C:/compare/BIMMAKE/sdk/GcmpGraphicsNodeInterface.dll differ
      Only in C:/compare/BIMMAKE/sdk: GcmpGuiMainFrameInterface.dll
      Files C:/compare/BIMMAKE.old/sdk/GcmpGuiResourceQt.dll and C:/compare/BIMMAKE/sdk/GcmpGuiResourceQt.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpJournalInterface.dll and C:/compare/BIMMAKE/sdk/GcmpJournalInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpMathInterface.dll and C:/compare/BIMMAKE/sdk/GcmpMathInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpModel.dll and C:/compare/BIMMAKE/sdk/GcmpModel.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpModelInterface.dll and C:/compare/BIMMAKE/sdk/GcmpModelInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpPick.dll and C:/compare/BIMMAKE/sdk/GcmpPick.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpPickInterface.dll and C:/compare/BIMMAKE/sdk/GcmpPickInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpRenderingGGP.dll and C:/compare/BIMMAKE/sdk/GcmpRenderingGGP.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpRenderingInterface.dll and C:/compare/BIMMAKE/sdk/GcmpRenderingInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpSnap.dll and C:/compare/BIMMAKE/sdk/GcmpSnap.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpSnapInterface.dll and C:/compare/BIMMAKE/sdk/GcmpSnapInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpTypeCastGGP.dll and C:/compare/BIMMAKE/sdk/GcmpTypeCastGGP.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpUiInterface.dll and C:/compare/BIMMAKE/sdk/GcmpUiInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GcmpUiQtImpl.dll and C:/compare/BIMMAKE/sdk/GcmpUiQtImpl.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GdcCommon.dll and C:/compare/BIMMAKE/sdk/GdcCommon.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GdcCore.dll and C:/compare/BIMMAKE/sdk/GdcCore.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GdcDataStandard.dll and C:/compare/BIMMAKE/sdk/GdcDataStandard.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GdcEngine.dll and C:/compare/BIMMAKE/sdk/GdcEngine.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GdcJsonSerializer.dll and C:/compare/BIMMAKE/sdk/GdcJsonSerializer.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GdcLocalDatabase.dll and C:/compare/BIMMAKE/sdk/GdcLocalDatabase.dll differ
      Only in C:/compare/BIMMAKE/sdk: GdcLogging.dll
      Files C:/compare/BIMMAKE.old/sdk/GdcNetwork.dll and C:/compare/BIMMAKE/sdk/GdcNetwork.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GdcProjectManager.dll and C:/compare/BIMMAKE/sdk/GdcProjectManager.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GdcUserManager.dll and C:/compare/BIMMAKE/sdk/GdcUserManager.dll differ
      Files C:/compare/BIMMAKE.old/sdk/Geometry.dll and C:/compare/BIMMAKE/sdk/Geometry.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmArchitectureFamily.dll and C:/compare/BIMMAKE/sdk/GmArchitectureFamily.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmCompress.dll and C:/compare/BIMMAKE/sdk/GmCompress.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmCrossDomainMessager.dll and C:/compare/BIMMAKE/sdk/GmCrossDomainMessager.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmFamilyCustomData.dll and C:/compare/BIMMAKE/sdk/GmFamilyCustomData.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmFamilyService.dll and C:/compare/BIMMAKE/sdk/GmFamilyService.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmFamilyServiceInterface.dll and C:/compare/BIMMAKE/sdk/GmFamilyServiceInterface.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmFamilyUpdate.dll and C:/compare/BIMMAKE/sdk/GmFamilyUpdate.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmModelFamily.dll and C:/compare/BIMMAKE/sdk/GmModelFamily.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmProcess.dll and C:/compare/BIMMAKE/sdk/GmProcess.dll differ
      Files C:/compare/BIMMAKE.old/sdk/GmValueValidator.dll and C:/compare/BIMMAKE/sdk/GmValueValidator.dll differ
      Files C:/compare/BIMMAKE.old/sdk/Hatch.dll and C:/compare/BIMMAKE/sdk/Hatch.dll differ
      Files C:/compare/BIMMAKE.old/sdk/LineType.dll and C:/compare/BIMMAKE/sdk/LineType.dll differ
      Files C:/compare/BIMMAKE.old/sdk/MaterialCore.dll and C:/compare/BIMMAKE/sdk/MaterialCore.dll differ
      Files C:/compare/BIMMAKE.old/sdk/MemoryChunkPager.dll and C:/compare/BIMMAKE/sdk/MemoryChunkPager.dll differ
      Only in C:/compare/BIMMAKE/sdk: Mesh.dll
      Only in C:/compare/BIMMAKE.old/sdk: QProfile.txt
      Files C:/compare/BIMMAKE.old/sdk/RegenCore.dll and C:/compare/BIMMAKE/sdk/RegenCore.dll differ
      Files C:/compare/BIMMAKE.old/sdk/RenderSystemAngle.dll and C:/compare/BIMMAKE/sdk/RenderSystemAngle.dll differ
      Files C:/compare/BIMMAKE.old/sdk/RenderSystemGL.dll and C:/compare/BIMMAKE/sdk/RenderSystemGL.dll differ
      Files C:/compare/BIMMAKE.old/sdk/RichText.dll and C:/compare/BIMMAKE/sdk/RichText.dll differ
      Files C:/compare/BIMMAKE.old/sdk/TopoEncoding.dll and C:/compare/BIMMAKE/sdk/TopoEncoding.dll differ
      Files C:/compare/BIMMAKE.old/sdk/ViewCore.dll and C:/compare/BIMMAKE/sdk/ViewCore.dll differ
      Files C:/compare/BIMMAKE.old/sdk/ViewManager.dll and C:/compare/BIMMAKE/sdk/ViewManager.dll differ
      Only in C:/compare/BIMMAKE.old/sdk: ViewerConfig.ini
      Only in C:/compare/BIMMAKE.old/sdk: algorithmLog.ini
      Only in C:/compare/BIMMAKE/sdk: boost_date_time-vc140-mt-x64-1_72.dll
      Files C:/compare/BIMMAKE.old/sdk/bson.dll and C:/compare/BIMMAKE/sdk/bson.dll differ
      Files C:/compare/BIMMAKE.old/sdk/common_utilities.dll and C:/compare/BIMMAKE/sdk/common_utilities.dll differ
      Only in C:/compare/BIMMAKE/sdk: cpprest140_2_10.dll
      Only in C:/compare/BIMMAKE/sdk: datacodes.json
      Only in C:/compare/BIMMAKE/sdk: enumcodes.json
      Files C:/compare/BIMMAKE.old/sdk/gdc_config.xml and C:/compare/BIMMAKE/sdk/gdc_config.xml differ
      Files C:/compare/BIMMAKE.old/sdk/jsoncpp.dll and C:/compare/BIMMAKE/sdk/jsoncpp.dll differ
      Files C:/compare/BIMMAKE.old/sdk/libcrypto-1_1-x64.dll and C:/compare/BIMMAKE/sdk/libcrypto-1_1-x64.dll differ
      Files C:/compare/BIMMAKE.old/sdk/libssl-1_1-x64.dll and C:/compare/BIMMAKE/sdk/libssl-1_1-x64.dll differ
      Only in C:/compare/BIMMAKE/sdk: propertycodes.json
      Files C:/compare/BIMMAKE.old/sdk/pugixml.dll and C:/compare/BIMMAKE/sdk/pugixml.dll differ
      Files C:/compare/BIMMAKE.old/sdk/zlib1.dll and C:/compare/BIMMAKE/sdk/zlib1.dll differ
      Only in C:/compare/BIMMAKE: sky_image
      Only in C:/compare/BIMMAKE: zh-CN
      Only in C:/compare/BIMMAKE: zh-TW

文件内容对比

在上面目录对比过程中,如果两边文件都存在而只是内容不同,进入文件内容对比逻辑:

 1 # for windows command, parameter seperator is /
2 # and bash will autoexpand to DRIVE:/
3 # here use // to avoid expanding.
4 $win32/dumpbin //disasm "$left" | sed '5d' > "$srcasm"
5
6 # use sed '5d' to remove a line like :
7 # Dump of file Bin1334\Release\GSUPService.exe
8 # which disturb the diff result by writing dir name
9 # remove it !!
10 $win32/dumpbin //disasm "$right" | sed '5d' > "$dstasm"
11
12 if [ $(cat "$srcasm" | wc -l) -gt 10 ] && [ $(cat "$dstasm" | wc -l) -gt 10 ]; then
13 # left & right are all valid PE format
14 resp=$(diff -q "$srcasm" "$dstasm")
15 if [ $verbose != 0 ]; then
16 echo "resp=$resp"
17 fi
18 else
19 resp="non PE format differs"
20 echo "$resp"
21 fi
22
23 if [ -z "$resp" ]; then
24 echo -e " $left \n== $right in asm, skip"
25 else
26 # need to replace
27 echo -e " $left \n!= $right"
28 relpath=$(get_relative_path "$srcdir" "$left")
29 if [ -z "$relpath" ]; then
30 echo "find relative path by source dir failed, try dest"
31 relpath=$(get_relative_path "$dstdir" "$right")
32 if [ -z "$relpath" ]; then
33 echo "find relative path by dest dir failed, skip"
34 continue;
35 fi
36 fi
37
38 if [ $verbose != 0 ]; then
39 echo "relpath: $relpath"
40 fi
41
42 tarpath="$outdir/$setupdir$relpath"
43 copy_file "$right" "$tarpath"
44 itemcnt=$(($itemcnt+1))
45 if [ $exactmode != 0 ]; then
46 # 1st argument represent zip folder
47 # 2nd argument represent install folder
48 # differs with copy order !
49 replace_item "$setupdir$relpath" "$relpath"
50 fi
51 fi

这里需要考虑二进制可执行文件不能直接对比(同样的代码编译两次得到的可执行文件也不一样,这是因为 PE 文件中包含了生成时间、唯一 ID 等与代码无关的内容),因此需要将其先反编译为汇编文本,再对汇编语句进行对比。这里没有通过文件后缀(dll / exe)来判断是否为可执行文件,这是因为产品中总有一些 dll 有奇奇怪怪的后缀。这里统一采用 dumpbin 进行反汇编,如果成功就是可执行文件;反之就是普通的文本或二进制文件。

  • 1-10:尝试使用 dumpbin 进行反汇编(注意使用 //disasm 来传递 win32 命令选项,因为 msys2 会将单独的 / 认为是根目录从而自动进行扩展、是我们不想要的)。下面是反汇编成功后的输出:

    Microsoft (R) COFF/PE Dumper Version 12.00.40629.0
    Copyright (C) Microsoft Corporation. All rights reserved. File Type: DLL 0000000180001000: 45 8B C0 mov r8d,r8d
    ……
    000000018000E202: CC int 3 Summary 1000 .data
    1000 .pdata
    7000 .rdata
    1000 .reloc
    1000 .rsrc
    E000 .text

    可见 dumpbin 会输出一个占 5 行的头部信息,为了防止这个信息干扰后续的对比,这里使用 sed 删除前 5 行;

  • 12-21:如果旧文件与新文件反汇编结果行数都大于10,说明两者都是可执行文件,去除前 5 行后进行反汇编内容的对比;否则是普通文件,不再进行对比(diff 已告诉我们它们不同)。下面是反汇编失败时的输出:
    $ win32/dumpbin //disasm  C:/compare/BIMMAKE/FillPatternFileApiTestData/right.pat
    Microsoft (R) COFF/PE Dumper Version 12.00.40629.0
    Copyright (C) Microsoft Corporation. All rights reserved. Dump of file C:/compare/BIMMAKE/FillPatternFileApiTestData/right.pat
    C:/compare/BIMMAKE/FillPatternFileApiTestData/right.pat : warning LNK4048: Invalid format file; ignored Summary

    可以看到一共只有 9 行输出,而一般成功的反汇编输出少则上百行、多则上万行,再少也不可能少于 10 行输出;

  • 23-36:如果文件内容一样,跳过此文件;否则需要确定当前文件在对比目录中的相对路径。先尝试使用旧目录去获取,如果失败再尝试使用新目录去获取。这里获取相对目录的工作交由 get_relative_path 这个函数来完成,出于对整体的把握,这里不对这些细节展开介绍了;
  • 42-50:通过上面获得的相对路径,就可以在输出目录构建目标文件全路径啦。复制文件的工作交由 copy_file 函数来完成,在内部它先创建对应的目录,然后调用 cp 完成文件复制。如果用户选择了 exact 模式,则将为每项在配置文件中添加一条 json 格式的替换记录 (通过 replace_item 函数),格式类似于下面这样:
    {
    "type": "replace",
    "target": "/Teigha/ACCAMERA_20.8src_14.tx",
    "source": "setup/Teigha/ACCAMERA_20.8src_14.tx"
    },

    对于非 exact 模式可以直接将整个目录递归覆盖到目标区域,因而不需要一条条的添加 json 配置。

单个文件处理

在上面的目录对比过程中,如果两边只有一个文件/目录存在,进入单个文件/目录处理逻辑:

 1 relpath=$(get_relative_path "$srcdir" "$dir")
2 if [ ! -z "$relpath" ]; then
3 # need to remove
4 echo -e "only in $srcdir: (old)\n $dir/$file, \nrelpath: $relpath/$file"
5 itemcnt=$(($itemcnt+1))
6 # 1st argument represent install folder
7 # differs with copy order !
8 delete_item "$relpath/$file" $isdir
9 else
10 relpath=$(get_relative_path "$dstdir" "$dir")
11 if [ ! -z "$relpath" ]; then
12 # need to add
13 echo -e "only in $dstdir: (new)\n $dir/$file, \nrelpath: $relpath/$file"
14 copy_file "$dir/$file" "$outdir/$setupdir$relpath/$file"
15 itemcnt=$(($itemcnt+1))
16 if [ $exactmode != 0 ]; then
17 # 1st argument represent zip folder
18 # 2nd argument represent install folder
19 # differs with copy order !
20 add_item "$setupdir$relpath/$file" "$relpath/$file" $isdir
21 fi
22 else
23 echo "unknown single file: $dir/$file"
24 fi
25 fi

如果单个文件项位于新目录,则新增文件项;如果位于旧目录,则删除:

  • 1-8:计算单个文件项在旧目录的相对路径,如果结果不为空,表示文件项位于旧目录,否则位于新目录。删除文件的工作交由 delete_item 函数完成,其实就是在配置文件中加入一条删除记录:

    {
    "type": "delete",
    "target": "/sdk/QProfile.txt"
    },

    如果是单独的目录,则递归删除整个目录:

    {
    "type": "delete_dir",
    "target": "/Share/ViewCoreResources/MaterialLibrary/textures/rainTextures"
    },

    删除项是否添加是和 exact 模式无关的,因为目录的递归覆盖只能添加或替换文件,不能删除。

  • 10-21:计算单个文件项在新目录的相对路径,此时结果一般是不为空的,调用 copy_file 函数复制新文件项到输出目录。当用户选择 exact 模式时,在配置文件中加入一条增加记录 (通过 add_item):

    {
    "type": "add",
    "target": "/Teigha/GripPoints_20.8src_14.tx",
    "source": "setup/Teigha/GripPoints_20.8src_14.tx"
    },

    如果是单独的目录,则递归增加整个目录:

    {
    "type": "add_dir",
    "target": "//Libraries",
    "source": "setup//Libraries"
    },

    copy_file 通过给 cp 传递 -r 选项,可以很好的支持目录的递归拷贝。

生成配置文件

处理完各个文件和子目录以后,就可以生成升级需要的配置文件啦:

 1 # remove temporary files
2 if [ $verbose -eq 0 ]; then
3 # only remove temporary files
4 # when not in verbose mode
5 rm "$srcasm"
6 rm "$dstasm"
7 rm "$dirdiff"
8 fi
9
10 if [ $itemcnt -eq 0 ]; then
11 echo "no item add/replace/delete found, stop generating..."
12 exit 1
13 fi
14
15 if [ $exactmode -eq 0 ]; then
16 # not exact mode
17 # add setup dir totally
18 if [ -z "$reldir" ]; then
19 jsonitem=$(echo " {\n"\
20 " \"type\": \"add_dir\",\n"\
21 " \"target\": \".\",\n"\
22 " \"source\": \"$setupdir\"\n"\
23 " }")
24 else
25 jsonitem=$(echo " {\n"\
26 " \"type\": \"add_dir\",\n"\
27 " \"target\": \"$reldir\",\n"\
28 " \"source\": \"$setupdir\"\n"\
29 " }")
30 fi
31
32 if [ $verbose != 0 ]; then
33 echo -e "$jsonitem"
34 fi
35
36 if [ -z "$json" ]; then
37 json="$jsonitem"
38 else
39 json="$json,\n$jsonitem"
40 fi
41 fi
42
43 json="$jsonhead$json$jsontail"
44 echo -e "$json" > "$outdir/upgrade.json"
45 echo "upgrade.json created, $itemcnt items generated"
46 echo -e "$json"

由于之前在处理文件过程中已经将必要的配置信息生成好了,这里的工作其实很简单:

  • 2-8:如果指定 verbose 选项,则保留中间文件用于排错,否则删除;
  • 10-13:如果经过对比,没有任何差异,或两个目录都是空的,导致输出内容为空,则中止并退出整个打包脚本;
  • 15-41:非 exact 模式下,需要添加一条 add_dir 配置来将输出目录中的所有文件递归覆盖到安装目录。如果用户指定了只替换安装目录中的某个子目录,这里需要调整一下目标路径(line 24-30);
  • 43-46:将各个 json 组装成完整内容并生成到输出目录,名称固定为 "upgrade.json"。

生成压缩包

所有内容就绪后就可以压缩成包上传到后台啦:

 1 tarpath="$outdir/*"
2 if [ "${tarpath/:/}" == "$tarpath" ]; then
3 # not contain ':', a relative path
4 # prefix ./ to avoid generate root dir in 7z
5 tarpath="./$tarpath"
6 fi
7
8 $win32/7z a "$setupdir.7z" "$tarpath"
9 resp=$?
10 if [ -z "$setupdir.7z" ]; then
11 echo "compressing failed: $resp"
12 exit 2
13 fi
14
15 mv "$setupdir.7z" "$outdir/$setupdir-$version-$sp.7z"
16 #echo "create 7zip compress packet OK"
17 exit 0

这里没有使用 tar cvzf 来生成 setup.tar.gz 文件,因为升级客户端只能接收 7z 格式的压缩包,这里使用 win32 版本的 7z 命令执行压缩过程。从另外的角度来讲,7z 压缩算法也是目前压缩率最高的算法,可以有效的降低网络传输的流量(7z 压缩率亲测高于 zip 及 gz)。这段代码比较简单,就不展开讲解了,最后会生成下面这样的文件结构:

$ ls -lhrt
total 348M
drwxr-xr-x 1 yunh 1049089 0 11月 17 19:18 setup/
-rw-r--r-- 1 yunh 1049089 147K 11月 17 19:19 upgrade.json
-rw-r--r-- 1 yunh 1049089 348M 11月 17 19:19 setup-1.8.0.0-0.7z

所有需要添加和替换的文件都会被放在 setup 目录下,这样在递归替换时就可以避免将无关文件(例如 upgrade.json)替换到安装目录。生成的压缩包命名方式为:setup-version-sp.7z。非 exact 模式生成的配置文件内容如下:

{
"version": "1.8.0.0",
"sp": "0",
"actions":
[
{
"type": "delete",
"target": "//BmRecentDocumentPathRecord.xml"
},
{
"type": "delete",
"target": "/BmWelcomeTemplateFile/小别墅.gbp"
},
{
"type": "delete",
"target": "/BmWelcomeTemplateFile/小别墅.png"
},
{
"type": "delete",
"target": "/BmWelcomeTemplateFile/老虎窗屋顶.gbp"
},
{
"type": "delete",
"target": "/BmWelcomeTemplateFile/老虎窗屋顶.png"
},
{
"type": "delete",
"target": "/CadIdentifier/DBErrorReport.txt"
},
{
"type": "delete",
"target": "//GPUDriverConfig.ini"
},
{
"type": "delete",
"target": "//MjLicense.dll"
},
{
"type": "delete",
"target": "//MjRichTextEditor.dll"
},
{
"type": "delete",
"target": "//MjUIArchitecture.dll"
},
{
"type": "delete",
"target": "//Packing4Rendering.dll"
},
{
"type": "delete",
"target": "//QProfile.txt"
},
{
"type": "delete",
"target": "//RecentDocumentPathRecord.xml"
},
{
"type": "delete",
"target": "//ViewerConfig.ini"
},
{
"type": "delete",
"target": "//algorithmLog.ini"
},
{
"type": "delete",
"target": "//gdpcore.1.txt"
},
{
"type": "delete",
"target": "//gdpcore.txt"
},
{
"type": "delete",
"target": "/sdk/QProfile.txt"
},
{
"type": "delete",
"target": "/sdk/ViewerConfig.ini"
},
{
"type": "delete",
"target": "/sdk/algorithmLog.ini"
},
{
"type": "add_dir",
"target": ".",
"source": "setup"
}
]
}

所有新增及替换操作,全在最后一条 add_dir 配置项了。如果是 exact 模式的话,配置文件就会大很多了,它会针对每个新增、替换项生成一个类似上面删除项的条目,这里就不多做演示了。

用户图形界面

上面的脚本只能通过命令行界面 (CUI) 调用,那能不能将它嵌入到用户图形界面 (GUI) 呢?答案是可以的。

上面这个程序是真的只做了界面。在获取用户完整输入后,它创建了一个匿名管道 (CreatePipe),并将管道的一端作为新进程的标准输出 (stdout)、同时用参数构造新进程的命令行 (上面的脚本 diffpacker.sh 作为第一参数) 来启动 bash.exe 进程。当脚本在运行中产生输出时,程序通过匿名管道读取这些输出,并将它们重定向到 UI 底部的输出框,达到实时查看脚本输出的效果。

下载

由于不涉及到后台接口,这个小工具中的脚本、调用到的命令及图形界面源码和可执行程序都是可以完整下载的:https://files.cnblogs.com/files/goodcitizen/diffpacker.zip

有类似需求的同学,改改脚本就可以用啦。其中用到了 msys2,它是一个运行在 windows 上的 bash,我们常用的 git 就使用它作为 git bash 的技术支撑。之前我的不少文章也都涉及过它:

查看博客园积分与排名趋势图的工具》、《用 shell 脚本做 restful api 接口监控》、《用 shell 脚本做日志清洗》,感兴趣的可以参考一下。

下面是 msys2 的主页,可以从这里获取 Windows 上的安装包:https://www.msys2.org/

后记

这个小工具后来在业务线得到了广泛使用,在某个大产品使用过程中还引发了一次血案,关于该案,我现在给大家梳理一下:

产品组有两个 dll 分别封装了基类 (base.dll) 和派生类 (derived.dll);有一次产品组为基类添加了两个成员作为补丁版本,在 diff 过程中成功的识别出了 base.dll 被修改,但是没有将 derived.dll 识别出来,然后就这样没有经由本地验证就向外发布了;结果导致打过补丁的版本一启动就崩溃了,原因是 derived.dll 中旧的派生类和 base.dll 中新的基类二进制不兼容了。

后来他们通过紧急补丁修复了上述问题,在后面复盘问题的过程中,我手动检查了脚本的运行日志,发现确实没有识别出新旧 derived.dll —— 脚本认为它们是二进制相同的。后来查询了一些相关资料,了解到我的 dumpbin /disasm 只是反编译了可执行文件中的代码段,而其它一些段 (例如数据段) 则被遗漏了。上面这个例子中,父类的成员变化后,肯定会有相应的 section 会做出调整,但是我通过调整 dumpbin 的选项也没有对比出这个段在哪里。后来尝试使用 msys2 自带的 objdump 命令去反编译,它确实可以得到更丰富的内容,从而判断出新旧 derived.dll 是不同的,但验证同一段相同代码编译两次生成的 dll 进行对比时,它仍然会告诉我两个 dll 不同!所以我不能简单的使用 objdump 替换 dumpbin,因为如果它报告所有 dll 都不同的话,这实际上就没有意义了。最后,这段代码还是带着 bug 继续“上岗”了,产品组现在多了一个心眼儿,每次生成 patch 后都会亲自做一下验证。

这个故事从侧面说明之前产品组对我的工具的信任程度 —— 那是毫无保留信任啊,哈哈。然而我做这个小工具花了多长时间呢?其实也就一周左右,而且有很多时间是花费在调试 windows 与 shell 的一些不兼容之处,真正写业务代码也就不到一周。如果换作用 c++ 来写呢,我恐怕没有一个月是搞不定的了,这就是使用现成组件“搭积木”带来的效率优势。而 shell 作为各个命令之间的粘合剂,为实现这种装配式的开发提供了必要的支撑。现在回头来看 linux 的设计哲学 —— “有众多单一目的的小程序,一个程序只实现一个功能,多个程序组合完成复杂任务” —— 的的确确是一个法宝啊。

使用 shell 脚本自动对比两个安装目录并生成差异补丁包的更多相关文章

  1. 使用 shell 脚本自动获取发版指标数据

    问题背景 大一点的公司都会建立一套规章流程来避免低级错误,例如合入代码前必需经过同行评审:上线前必需提测且通过 QA 验证:全量前必需经过 1%.5%.10%.20%.50% 的灰度过程.尤其是最后一 ...

  2. CentOS/Linux内存占用大,用Shell脚本自动定时清除/释放内存

    CentOS/Linux内存占用大,用Shell脚本自动定时清除/释放内存来自:互联网 时间:2020-03-22 阅读:114以下情况可能造成Linux内存占用过高服务配置存在直接分配错误,或隐性分 ...

  3. shell脚本自动清理服务器日志、图片等信息

    在做性能测试的时候,linux服务器时常会产生大量数据,如日志信息,图片信息,文件信息等,压测一段时间后,导致服务器磁盘空间暂满而崩溃,每天手动清理比较麻烦, 利用shell脚本自动清理,脚本如下 1 ...

  4. shell 脚本自动插入文件头

    vim编辑shell脚本自动插入文件头部信息,将下面的代码写入home目录xia .vimrc 文件即可. shell 文件头: 1 autocmd BufNewFile *.sh exec &quo ...

  5. javascript对比两个数组,打印出差异值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Git学习-->如何通过Shell脚本自动定时将Gitlab备份文件复制到远程服务器?

    一.背景 在我之前的博客 git学习--> Gitlab如何进行备份恢复与迁移? (地址:http://blog.csdn.net/ouyang_peng/article/details/770 ...

  7. shell脚本自动拉起启动程序

    一.我们先看看编写的shell脚本的内容,该shell的作用主要是实现监控某个程序崩溃之后就自动重启该进程. while true do procnum=` ps -ef|grep "tes ...

  8. iOS开发进阶 - 使用shell脚本自动打包上传到fir.im上-b

    用fir.im测试已经好长时间了,感觉每次打包上传都很麻烦,想着是不是可以用脚本自动打包,在网上搜了一下确实有,下面总结一下如何使用脚本自动打包上传到fir.im,以及打包过程中遇到的问题和解决办法 ...

  9. Shell脚本自动重启Java服务

    话不多说直接上代码: cd /home/javaProduct/if [ -d '/home/javaProduct/lib_new/' ]; thenecho 'Has New Lib!'echo ...

随机推荐

  1. offset()与position()的区别

    jQuery中有两个获取元素位置的方法offset()和position(),两者的定义如下: offset(): 获取匹配元素在当前视口的相对偏移. 返回的对象包含两个整形属性:top 和 left ...

  2. Jquery UI Autocomplete 在mvc中应用

    首先添加引用 <link href="~/Content/themes/base/jquery-ui.css" rel="stylesheet" type ...

  3. linux系统修改不成功无法修改密码

    一.问题描述 新上架的浪潮服务器使用装机平台进行统一安装,安装完成后修改用户密码时统一无法修改,使用root账户无法修改其他用户密码,自身根密码也无法修改成功,报错如下 Changing passwo ...

  4. Mac安装Go语言

    正文 安装 安装我们使用 HomeBrew ,其使用方法详见我的上一篇博文 brew install go 配置环境变量 Go1.3及以后版本跳过以下步骤 进入变量文件 cd ~ vim .bash_ ...

  5. MyBatis初级实战之一:Spring Boot集成

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. js 中const 定义的值是否能更改

    const定义的基本类型不能改变,但是定义的对象是可以通过修改对象属性等方法来改变的. 1. const aa=trueaa=falseconsole.log(aa)VM1089:2 Uncaught ...

  7. 【SpringBoot1.x】SpringBoot1.x 缓存

    SpringBoot1.x 缓存 文章源码 JSR107 Java Caching 定义了 5 个核心接口,分别为: CachingProvider 定义了创建.配置.获取.管理和控制多个 Cache ...

  8. 一文搞懂MySQL前缀索引

    引入 通常在开发中我们需要定义字符串类型的字段,例如用户名或者用户邮箱等. 假设我们在维护一个用户登录系统,用户表的定义: create table User( ID bigint unsigned ...

  9. redis之集群二:哨兵

    回顾 上一篇介绍了Redis的主从集群模式,这个集群模式配置很简单,只需要在Slave的节点上进行配置,Master主节点的配置不需要做任何更改.但是,我们发现这种集群模式当主节点宕机,主从无法自动切 ...

  10. Azure App object和Service Principal

    为了把Identity(身份)和Access Management function(访问管理功能)委派给Azure AD,必须向Azure AD tenant注册应用程序.使用Azure AD注册应 ...