天天看點

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

最近客戶回報,為啥不用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是我之前經常用來做編譯複制的指令,為啥我後面自己整了一個工具來複制呢?太久了,記不起來了,索性鼓搗鼓搗。

很快,我就發現了問題。在.NET Core的工程中,很多變量是擷取不到值的,如下指令:

<PropertyGroup>

<PostBuildEvent>

echo 準備複制"$(TargetPath)"

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

</PostBuildEvent>

</PropertyGroup>

輸出:

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

但是在VS的指令行編輯工具裡面,這些變量應該都是有值的:

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

于是我回想起來了,之前似乎就是遇到這個問題,因為時間緊迫,自己寫了一個指令行工具代替了之前的指令。今天再次碰到,于是決心深挖一下,從理論上來講,VS不應該犯這麼低級的錯誤。

我想,這個問題已經出現許久了,也許老外會給我一些啟發。找過了stackoverflow,沒發現有用的資訊,不過最終在Github找到了一些有用的内容。

比如說這篇:

<a href="https://github.com/dotnet/sdk/issues/1055">https://github.com/dotnet/sdk/issues/1055</a>

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

從下面的答複中,我們看到了這條關鍵内容:

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

大意似乎是,編譯事件被target元素代替了。但是大哥,都這麼久了,為啥通過項目工程的界面編輯,生成的元素還是PostBuildEvent,你們這不是坑人麼。。。

說明一點,VS界面的調整跟不上相關API和規則的調整。。。

問題似乎解決了:

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

我們再進一步完善:

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

看起來需求已經實作了,理論上就可以就此結束了。但是Target是什麼鬼?

來來來,我們直接去看官方文檔:

<a href="https://msdn.microsoft.com/zh-cn/library/t50z2hka.aspx">https://msdn.microsoft.com/zh-cn/library/t50z2hka.aspx</a>

突然發現這是一個很有意思的元素。文檔很簡單,但是我發現基于此,可以有很多玩法。

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

那麼,我們可以将上述指令進行改進:

&lt;Target Name="PostBuild" AfterTargets="PostBuildEvent"&gt;

&lt;Message Text="将插件複制到插件目錄" Importance="high" /&gt;

&lt;Copy DestinationFolder="$(SolutionDir)src\Magicodes.Cloud.Admin\wwwroot\PlugIns\" SourceFiles="$(TargetPath)" SkipUnchangedFiles="true" /&gt;

&lt;/Target&gt;

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

是否看起來又更進了一步。

.NET Core工程編譯事件$(TargetDir)變量為空引發的思考前言$(TargetPath)變量為空尋找原因,解決問題進階

Import是什麼鬼?請看大螢幕,哦,看連結:

<a href="https://msdn.microsoft.com/zh-cn/library/ms171464.aspx">https://msdn.microsoft.com/zh-cn/library/ms171464.aspx</a>

copyplus.props定義如下:

&lt;Project&gt;

&lt;/Project&gt;

至此,本篇完成。

希望本篇内容,能夠給大家更多啟發,并且開發出更多玩法。

繼續閱讀