当前位置: 首页 > news >正文

.NET Core工程编译事件$(TargetDir)变量为空引发的思考

  • 前言

最近客户反馈,为啥不用xcopy命令代替我自己写的命令来完成插件编译复制:

我的:

<PostBuildEvent>call "$(SolutionDir)tools\tools\Magicodes.CmdTools.exe" copy -s "$(SolutionDir)plus\Jxy.WeChat\Jxy.WeChat.Core\bin\Debug\net461\Jxy.WeChat.Core.dll" -t "$(SolutionDir)src\Magicodes.Admin.Web.Mvc\wwwroot\PlugIns"</PostBuildEvent>

<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>

 

推荐的:

call xcopy /s /y "$(TargetPath)" "$(SolutionDir)src\ Magicodes.Admin.Web.Mvc \wwwroot\PlugIns\"

 

我深以为然,xcopy是我之前经常用来做编译复制的命令,为啥我后面自己整了一个工具来复制呢?太久了,记不起来了,索性鼓捣鼓捣。

 

  • $(TargetPath)变量为空

很快,我就发现了问题。在.NET Core的工程中,很多变量是获取不到值的,如下命令:

<PropertyGroup>

<PostBuildEvent>

echo 准备复制"$(TargetPath)"

call xcopy /s /y "$(TargetPath)" "$(SolutionDir)src\Magicodes.Cloud.Admin\wwwroot\PlugIns\"

</PostBuildEvent>

 

</PropertyGroup>

输出:

但是在VS的命令行编辑工具里面,这些变量应该都是有值的:

于是我回想起来了,之前似乎就是遇到这个问题,因为时间紧迫,自己写了一个命令行工具代替了之前的命令。今天再次碰到,于是决心深挖一下,从理论上来讲,VS不应该犯这么低级的错误。

 

  • 寻找原因,解决问题

我想,这个问题已经出现许久了,也许老外会给我一些启发。找过了stackoverflow,没发现有用的信息,不过最终在Github找到了一些有用的内容。

比如说这篇:

https://github.com/dotnet/sdk/issues/1055

$(TargetPath) or $(TargetDir) are empty on PostBuild event on netstandard project

从下面的答复中,我们看到了这条关键内容:

大意似乎是,编译事件被target元素代替了。但是大哥,都这么久了,为啥通过项目工程的界面编辑,生成的元素还是PostBuildEvent,你们这不是坑人么。。。

说明一点,VS界面的调整跟不上相关API和规则的调整。。。

问题似乎解决了:

我们再进一步完善:

看起来需求已经实现了,理论上就可以就此结束了。但是Target是什么鬼?

 

  • 进阶

来来来,我们直接去看官方文档:

https://msdn.microsoft.com/zh-cn/library/t50z2hka.aspx

突然发现这是一个很有意思的元素。文档很简单,但是我发现基于此,可以有很多玩法。

比如你看看这篇:https://msdn.microsoft.com/zh-CN/library/3e54c37h.aspx

那么,我们可以将上述命令进行改进:

<Target Name="PostBuild" AfterTargets="PostBuildEvent">

<Message Text="将插件复制到插件目录" Importance="high" />

<Copy DestinationFolder="$(SolutionDir)src\Magicodes.Cloud.Admin\wwwroot\PlugIns\" SourceFiles="$(TargetPath)" SkipUnchangedFiles="true" />

</Target>

是否看起来又更进了一步。

Import是什么鬼?请看大屏幕,哦,看链接:

https://msdn.microsoft.com/zh-cn/library/ms171464.aspx

copyplus.props定义如下:

<Project>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">

<Message Text="将插件复制到插件目录" Importance="high" />

<Copy DestinationFolder="$(SolutionDir)src\Magicodes.Cloud.Admin\wwwroot\PlugIns\" SourceFiles="$(TargetPath)" SkipUnchangedFiles="true" />

</Target>

</Project>

至此,本篇完成。

希望本篇内容,能够给大家更多启发,并且开发出更多玩法。

相关文章:

  • 菜鸟学Linux 第065篇笔记 nfs
  • 更改INSM地址的操作
  • centos 7 yum安装kubernetes cluster 1.0
  • C++字符串string类常用操作详解(一)【初始化、遍历、连接】
  • Java设计模式圣经连载(03)-抽象工厂模式
  • Centos中文乱码问题的解决。
  • Python函数知识汇总-课堂笔记
  • AD与DNS集成,且有备份AD与DNS,主AD与DNS坏,备份DNS如何成为主
  • SubSonic3.0使用外连接查询时查询不出数据的问题修改
  • 海量文件拷贝(Windows/Linux)
  • VS.net和Reflector 图标解释
  • EPEL源
  • centos7 修改mac地址
  • c# 4.0新特性一览
  • 荣光医院医道会比赛策略
  • 【mysql】环境安装、服务启动、密码设置
  • 【前端学习】-粗谈选择器
  • Android优雅地处理按钮重复点击
  • bearychat的java client
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • JavaScript类型识别
  • js正则,这点儿就够用了
  • Node项目之评分系统(二)- 数据库设计
  • Vue学习第二天
  • 工作中总结前端开发流程--vue项目
  • 收藏好这篇,别再只说“数据劫持”了
  • 手写一个CommonJS打包工具(一)
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 温故知新之javascript面向对象
  • 写代码的正确姿势
  • 优秀架构师必须掌握的架构思维
  • 自制字幕遮挡器
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #考研#计算机文化知识1(局域网及网络互联)
  • (C++20) consteval立即函数
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (超详细)语音信号处理之特征提取
  • (二)hibernate配置管理
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (理论篇)httpmoudle和httphandler一览
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (一)插入排序
  • (转)linux下的时间函数使用
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .gitignore文件设置了忽略但不生效
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET下ASPX编程的几个小问题
  • ::