文件系统干翻了 MSBuild

发布于:07/27/2025 03:56:09

首先,MSBuild 是微软的构建系统,从名字上也能看出来,Microsoft Build. 其实它可以干的东西很多,但是主要的为什么我会用它,因为我在写 .NET 和 CSharp。用它就理所当然了。

其次,我们需要了解一下三大桌面操作系统的文件系统,Windows 和 macOS 的路径是不分大小写的,你怎么写都能找得到的对应的目录。然后 Linux 就很高级了,是区分大小写的,连自动补全都会,导致在用 +DE 的 Linux 时每次去自动创建的 Desktop, Document 什么的都特别费劲。但是,这也只能算是不方便而已。

但是,当 MSBuild + Linux 会发生什么呢?好问题。


首先,Solar Network 的构建都是在 GitHub Actions 上完成打包 Docker Image 推送到我的服务器,整个 Prod 都是 Linux,只有我的开发环境是不分大小写的 macOS。

然后,.NET 有一个还不错用的本地化框架,用的是资源文件来存储数据的,也就是 .resx,不同的资源在开发情况下是在同一个文件夹,只不过是可能像 .zh-Hans.resx 之类的。不过不知道是有的框架特殊配置还是默认的发布行为,这些到生产环境都会变成独立的文件夹,比如说:/zh-Hans/DysonNetwork.dll;诶对,传统,全部都是动态链接库。

这是蛮早期的,刚刚加上服务端本地化的时候,但是还没有配置自动构建,不清楚是哪一次提交造成错误的,当我觉得没什么问题决定发 v3 的时候,GHA 全是红的。这就很有意思了,用二分法扒了全部 100+ Commits 才确定一个提交之后整个都坏了。但是原因呢?我不到啊。

于是发动一技能,ChatGPT 启动!这是我第一次用 ChatGPT 的 Deep Research。默认的 Chat 一直给我倒车轱辘话,所有模型什么 Gemini,Claude 都这样(但是没有 Gork)只能说人还是要思考,模型也是,思考一下直接跟我讲我有一个大小写有问题,MSBuild 创建的文件路径是 zh-Hans,我代码里写的是 zh-hans,然后导致一直找不到要拷贝的东西。

行吧,这就算是我与 MSBuild 结下的第一个梁子。


时间快转到最近,我给一些微服务加了自己的前端页面,然后不知道为什么就突发奇想把 Vite(前端的打包工具)给加的随机文件名后缀([源文件名].[不知道怎么生成的后缀].[文件扩展名])给禁用掉了,可能我当时想着做微前段吧,要固定的 index.js 路径。但很明显我没有这么干,最终。但是这个配置没有取消,给后来留下了隐患。

昨天,我重构了一下人机验证,因为前端的注册也要用人机验证的组件。所以原本只有 views/captcha.vue 的,现在多了个 components/Captcha.vue。其他没什么区别,本地测试也过(开发环境也是有 Timestamp 做加载请求时的额外文件名)。

然后丢上 GHA,4/5,身份服务的构建这么突然失败了。报的错又是 error MSB3021: Unable to copy file,这是怎么回事呢。我当时看文件路径,直接简单粗暴 Remove 了一个文件不要让他 Include。构建是好了,然后人机验证干废了。因为 Captcha.js 直接没包进去,对应页面要东西直接 404 这可不报废吗。

晚些时候有用户说人机验证有问题,我查了一下,发现脚本不见了。思索一下,又是 MSBuild 在搞。还记得之前这个页面的文件名和组件的文件名吗?是 captcha.vue 和 Captcha.vue。一般情况下,他们在 Linux 上算两个文件,是没什么问题的。但是 MSBuild 就是把它们一起算。然后之前拷贝了小写的 JS 文件就认为大写的重复了,直接给我 Unable to copy file。假如说 MSBuild 不这么干的话顶多是我发现我本地的人机验证有点问题,但依我的性格,最多把这个当成十大世界未解之谜吧(

虽然这个应该是 Vite 的锅,但是在我的据理力争下,还是记这一点到 MSBuild 头上。


所以微软写的东西怎么总是这么多问题,能不能好好修一修呀大哥。