最近在多人合作开发项目时遇到一个场景,是关于 Visual Studio 生成事件在不同环境出现的问题。比如大部分人的发布目录不一样,这就导致了在执行生成事件时的报错(通常是:已退出,代码为4),所以决定使用代码来统一这个场景,让代码尽可能在每台电脑上都能顺利的运行。
需求分析
需求1:只操作一次发布,同时将 DLL 和 XML 更新,不需要单独更新 XML 文件;
需求2:希望每次在上传待发布文件时,不需要手动排除配置文件(小心翼翼的排除);
针对需求,一边搜索 BAT 命令,一边学习写出了下面的第一版,下面逐行将代码逻辑分析一遍:
1.代码开始声明 path 变量,值为发布目录路径;
2.判断发布路径是否存在;
3.复制$(TargetDir)目录下所有 xml 文件至发布目录;
4.删除发布目录下 appsettings.*.json 文件;
5.删除发布目录下 appsettings.json 文件;
6.如果路径不存在;
7.创建发布目录;
set path = "D:\Website\xXx\API\"
if exist path
{
Copy /y $(TargetDir)*.XML path
DEL /f /q path appsettings.*.json
DEL /f /q path appsettings.json
}
else
{
md path
}
第一次写出这么长的 CMD 命令,在最开始个人版本中的只有一句:Copy /y $(TargetDir)*.XML D:\Website\xXx\API\,用得好好的也没见出过问题。直到在团队成员中出现了文件夹不存在的报错。才引起重视。
正是因为对 CMD 的不熟悉,这段代码才漏洞百出,直到写出正确的版本。感觉就像是写了个 Hello Word 错误警告一大堆一样让人沮丧。沮丧归沮丧,但是决不放弃,这是原则。
又经过一番搜索,根据错误提示慢慢的定位到问题。开篇提到最长遇到的错误是"已退出,代码为4",这次的错误是“已退出,代码为1”,就将这个错误信息当作突破点一直搜索。慢慢的找出了真相。下面来说说这段代码中都有哪些错误。
错误1: | 变量使用时需要待百分号(%path%) |
错误2: | 声明变量时,等号左边不能出现空格(右边可以有多个空格); |
错误3: | CMD 中的判断使用的是小括号“()”; |
错误4: | 并且小括号必须和 if else 写在同一行; |
加上大括号一共11行的代码,可以出 4 个错误,真的是无比心碎。下面是修正错误并优化后的代码:
set path="D:\Website\xXx\API\"
if not exist %path% (
md %path%
)
Copy /y $(TargetDir)*.XML %path%
DEL /f /q %path%appsettings.*.json
DEL /f /q %path%appsettings.json
中间还发现 CMD 和部分脚本语言的特性一样,会尝试尽可能的运行代码,有错的部分跳过并报错。正确的代码依然会执行。这与 C# 的语言特性区别有点大,还疑惑了半天,为什么在报错,但 XML 文件正确的复制了,JSON 文件也正确的删除了。现在谜底已解开,豁然开朗。
最后还有一点意外,就是 DEL 语句会在发布完成前先执行,然后 Visual Studio 会再次把文件复制一份过来。导致始终不能达到需求二的效果。最开始是希望通过延时执行 CMD 的方式解决,结果延时命令会阻塞发布操作,并且也不能成功。最终通过各种搜索找到微软的发布配置文件找到排除文件的方法。
在发布项目的 .csproj 中找一个或创建一个 ItemGroup,实现效果如下:
<ItemGroup>
<Content Update="**\*.json" CopyToPublishDirectory="Never" />
</ItemGroup>
这样那前面 CMD 中的 DEL 也失去意义,索性去掉。至此两个需求完成了。