MSBUILD: "The target does not exist in the project." after modifying DependsOnTarget - msbuild

After adding to .csproj
<PropertyGroup>
<CompileDependsOn>$(CompileDependsOn.ToString())</CompileDependsOn>
</PropertyGroup>
I'm getting error MSB4057: The target does not exist in the project.
error MSB4057: The target "CheckFileSystemCaseSensitive;
...other stuff...
;" does not exist in the project.
Nevertheless string between quotes looks correct.
Edit: Looks like duplication of strange behavior of Property functions

Like in accepted answer from https://stackoverflow.com/a/10024381/915546 solution is to use [MSBuild]::Unescape function:
<PropertyGroup>
<CompileDependsOn>$([MSBuild]::Unescape(CompileDependsOn.ToString()))</CompileDependsOn>
</PropertyGroup>

Related

Condition on "PropertyGroup" in Directory.build.props not working

I've created a Directory.build.props file so I can set the C# language version in there.
But I also have Visual Basic Projects, so i wanted to limit the setting to C# projects.
<Project>
<PropertyGroup Condition="'$(ProjectExt)'=='.csproj'">
<LangVersion>7.2</LangVersion>
</PropertyGroup>
</Project>
But my project is not loading it / the UI is not displaying the language version 7.2.
I've tried to apply the same condition inside the csproj file, also not working.
<PropertyGroup>
<LangVersion Condition="'$(ProjectExt)'=='.csproj'">7.2</LangVersion>
</PropertyGroup>
However, this will work:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Message Text="Condition working" Importance="high" Condition="'$(ProjectExt)'=='.csproj'"/>
</Target>
The build will output my message
Why is the condition not working on my LanguageVersion? Any Clues?
You will need to use a property to condition on that is available very early in the build. In your case, you should condition on MSBuildProjectExtension:
<PropertyGroup>
<LangVersion Condition="'$(MSBuildProjectExtension)'=='.csproj'">7.2</LangVersion>
</PropertyGroup>
See MSBuild reserved and well-known properties for the complete set of available properties.
ProjectExt is only defined late in the build definition and is therefore not available in Directory.Build.props, which is imported very early into the project.

Get parent directory of MSBuildProjectDirectory

I have solution with projects. Also I have in solution directory folder with msbuild files.
In msbuild file I have next code :
<PropertyGroup Label="Build Directories">
<RootPath>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)'))</RootPath>
</PropertyGroup>
<ItemGroup>
<MSBuildProjectInfrastructure Include="$(RootPath)MyApp.Services.Infrastructure.sln">
<AdditionalProperties>Configuration=$(Configuration);Platform=$(Platform);</AdditionalProperties>
</MSBuildProjectInfrastructure>
</ItemGroup>
Which works badly, as I need to go in parent directory to find MyApp.Services.Infrastructure.sln
Structure :
SolutionFolder
-- MsBuildsFolder
-- ProjectFile
Here is quite similar question, but doesn't resolve my issue
To get the parent folder, you can let MSBuild determine the location of known file in that folder by means of the built in property function GetDirectoryNameOfFileAbove:
<PropertyGroup>
<RootPath>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), MyApp.Services.Infrastructure.sln))</RootPath>
</PropertyGroup>

error MSB4064: The "OverwriteReadOnlyFiles" parameter is not supported by the "Copy" task

I am using Msbuild 4.0. When i was using Msbuild 3.5 OverwriteReadonlyfiles worked without any issue.
But today when i was trying to use the copy task i am getting this issue.
error MSB4064:
The "OverwriteReadOnlyFiles" parameter is not supported
by the "Copy" t ask. Verify the parameter exists on the task, and it
is a settable public instance property.
This is my target which has copy task
<Target Name="CopyBOM">
<Copy SourceFiles="#(BOM)" DestinationFolder="%(BOM.Destination)" OverwriteReadOnlyFiles="true">
<Output TaskParameter="CopiedFiles" ItemName="CopyBOMFiles" />
</Copy>
<Message Text="Copied to BOM: #(CopyBOMFiles)"/>
</Target>
Following is the itemgroup i am using in my properties file
<BOM Include="..\..\..\Release\CoreDeployment.msi">
<Destination>..\..\..\Core\BOM\Comp1</Destination>
</BOM>
I am having multiple properties file, I have verified that in all the place Toolsversion=4.0 is placed.
Has any one faced this? Any way is there to solve this?
I'm using OverwriteReadOnlyFiles="true" without issues. Try to add ToolsVersion="4.0" into your Project tag:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
You are most likely dealing with a ToolsVersion issue, even though you say you've checked all your files and their imports. Omitting the ToolsVersion from a file will cause it to drop to a lower version, so if all you did was search for "ToolsVersion" you may have missed a file where it wasn't declared on the <Project> node at all.
Run a command line build with diagnostic level logging, with the following additional parameters:
> msbuild My.proj /fl /flp:v=diag;logfile=My.proj.diagnostic.log
After the build fails, open the log file, seach for "MSB4064" then backtrack up the file looking for anything specifying the 2.0 framework.

Property scope using msbuild extension pack detokenise

Im trying to use the msbuild extensions pack to fix up the configuration of our app on deploy,
i want to be able to pass a property (ENV) which will load my environment specific config file to use with the detokeniser, and fix up my application configs.
Like this:
<UsingTask TaskName="MSBuild.ExtensionPack.FileSystem.Detokenise"
AssemblyFile=".\Tools\MSBuild Extension Pack 4.0.3.0\MSBuild.ExtensionPack.dll"/>
<Import Project=".\Environments\$(Env).properties"/>
<Target Name="Build" >
<ItemGroup>
<SourceTemplates Include=".\Templates\**\*.*"/>
</ItemGroup>
<RemoveDir Directories=".\Temp"/>
<MakeDir Directories=".\Temp"/>
<Message Text="#(SourceTemplates)"/>
<Copy SourceFiles="#(SourceTemplates)"
DestinationFolder=".\Temp\%(RecursiveDir)" />
<ItemGroup>
<TargetTemplates Include=".\Temp\**\*.*"/>
</ItemGroup>
<MSBuild.ExtensionPack.FileSystem.Detokenise
TaskAction="Detokenise"
TargetFiles="#(TargetTemplates)"/>
</Target>
So i call this using
msbuild Detokenise.msbuild /p:Env=Prod
Msbuild knows about my file and i have access to its properties, but when the detokeniser runs i get the error:
Detokenise Task Execution Completed [15:07:50]
C:\Source\1.2\Build\Detokenise.msbuild(27,3):
error : InvalidProjectFileException: The imported project "C:\Source\1.2\Build\Environments\.properties" was not found.
Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
C:\Source\1.2\Build\Detokenise.msbuild\r
C:\Source\1.2\Build\Detokenise.msbuild(27,3): error :
All works fine if i hard code it-
Any ideas how to solve this. I thought of doing some text replacement on the msbuild before i execute...
You could try to assign this parameter to a local property:
<PropertyGroup Condition="'$(Env)'=='Prod'">
<TargetEnv>Prod</TargetEnv>
</PropertyGroup>
<!-- add other environments as needed -->
<PropertyGroup Condition="'$(Env)'=='Test'">
<TargetEnv>Test</TargetEnv>
</PropertyGroup>
<Import Project=".\Environments\$(TargetEnv).properties"/>
You could also try to enclose your parameter value in quotes:
msbuild Detokenise.msbuild /p:"Env=Prod"
As is your problem can't be reproduced, so it may be a side effect of other parameters not shown in your sample code.
I've seen a number of other questions where a similar problems was happening:
Visual Studio Ignoring MSBuild file (csproj) Customizations

Detokenising multiple files using msbuild - property not found error

I have the following piece of code to replace all tokens in a given set of files:
(I'm using the msbuild extensions detokenise task).
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="MSBuild.ExtensionPack.FileSystem.Detokenise" AssemblyFile="Extensions/MSBuild.ExtensionPack.dll"/>
<PropertyGroup>
<someValueToReplace>New Value</someValueToReplace>
</PropertyGroup>
<ItemGroup>
<TextFiles Include="test1.txt"/>
<TextFiles Include="test2.txt"/>
</ItemGroup>
<Target Name="Build">
<Detokenise TaskAction="Detokenise" TextEncoding="ASCII" TargetFiles="#(TextFiles)"/>
</Target>
</Project>
Unfortunately I get the following error:
(I don't get this error if only one item exist in the ItemGroup).
(Note that I don't want to explicitly inject the tokens that I want replaced).
"C:\Users\v\Desktop\msbuildSample\detokenise.xml" (default target) (1) ->
(Build target) ->
C:\Users\v\Desktop\msbuildSample\detokenise.xml(10,3): error : Property not found: toReplace
C:\Users\v\Desktop\msbuildSample\detokenise.xml(10,3): error : ArgumentException: Review error log\r
C:\Users\v\Desktop\msbuildSample\detokenise.xml(10,3): error :
My mistake .. I thought it was a bug in msbuild .. actually the issue was exactly what the error message indicated -- I was trying to replace a variable called toReplace -- but it wasn't defined.