问题的提出

公司各个业务线的安装包小则几十兆、大则几百兆,使用自建的升级系统向全国百万级用户下发新版本时,流量耗费相当惊人。有时新版本仅仅改了几个 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. [leetcode]205. Isomorphic Strings同构字符串

    哈希表可以用ASCII码数组来实现,可以更快 public boolean isIsomorphic(String s, String t) { /* 思路是记录下每个字符出现的位置,当有重复时,检查 ...

  2. devops持续集成

    目录 Devops 版本控制系统 Git安装 Git使用 git四种状态 git基础命令 git分支 git合并冲突 git标签 git命令总结 Github使用 创建仓库 HTTP协议 SSH协议 ...

  3. Spring—SSJ集成&声明式事务管理

    1.   课程介绍 1.  SSJ集成;(掌握) 2.  声明式事务管理;(掌握) 什么是三大框架 2.1.  ssh Struts/Struts2 Spring Hibernate 2.2.  ss ...

  4. IdentityServer4 之Client Credentials走起来

    前言 API裸奔是绝对不允许滴,之前专门针对这块分享了jwt的解决方案(WebApi接口裸奔有风险):那如果是微服务,又怎么解决呢?每一个服务都加认证授权也可以解决问题,只是显得认证授权这块冗余,重复 ...

  5. java操作hive和beeline的使用

    一.java操作hive 1.启动服务:hiveserver2,让hive开启与外部连接的服务 nohup hiveserver2 1>/dev/null 2>/dev/null & ...

  6. spark-streaming-连接kafka的两种方式

    推荐系统的在线部分往往使用spark-streaming实现,这是一个很重要的环节. 在线流程的实时数据一般是从kafka获取消息到spark streaming spark连接kafka两种方式在面 ...

  7. 你知道 react-color 的实现原理吗

    一.前言 ReactColor 是一个优秀的 React 颜色选择器组件,官方给了多种布局供开发者选择. 笔者常用的主题为 Sketch,这种主题涵盖了颜色面板.推荐色块.RGB颜色输入等功能,比较完 ...

  8. 【JDBC核心】操作 BLOB 类型字段

    操作 BLOB 类型字段 MySQL BLOB 类型 MySQL 中,BLOB 是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据. 插入 BLOB 类型的数据必须使用 Pre ...

  9. LeetCode234 回文链表

    请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶:你能否用 O(n) 时间复杂 ...

  10. 剑指offer 面试题2:实现Singleton模式

    转自:https://blog.csdn.net/liang19890820/article/details/61615495 Singleton 的头文件(懒汉式/饿汉式公用): // single ...