I am trying to get some net core 2.1 projects to build on a new build server that we have. We have installed Visual studio tools for 2017 and 2019.
I am getting this error when it tried to build it via our TFS build process. We use cake scripts to build the code.
C:\Program Files\dotnet\sdk\6.0.102\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.TargetFrameworkInference.targets(54,5): error MSB4186: Invalid static method invocation syntax: "[MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')". [MSBuild]::GetTargetFrameworkIdentifier Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)). [D:\Agents\EROS-006\_work\2\s\src\Cases.CommandHandlers\Cases.CommandHandlers.csproj]
Is it something to do with the csproj contents? We have this declared at the top as this bit of the message stands out
GetTargetFrameworkIdentifier Static method invocation should be of the form: $([FullTypeName]::Method())
The csproj version details:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeFrameworkVersion>2.1.4</RuntimeFrameworkVersion>
<TargetLatestAspNetCoreRuntimePatch>True</TargetLatestAspNetCoreRuntimePatch>
</PropertyGroup>
...
I have searched for an answer but seem to point to mono related things, which we don't use at all, its a windows machine with the visual studio tools installed as mentioned above.
The cake build part looks like this
Task("Build")
.IsDependentOn("Version")
.Does(() =>
{
var settings = new DotNetCoreRestoreSettings()
{
Sources = packageSources
};
DotNetCoreRestore(settings);
if(useLatestMsBuild){
MSBuild(solution, new MSBuildSettings {
Configuration = configuration,
MaxCpuCount = maxcpucount,
ArgumentCustomization = args => args
.Append("/p:Version=" + versionInfo.InformationalVersion.Replace("/", "-"))
.Append("/p:AssemblyVersion=" + versionInfo.AssemblySemVer)
.Append("/p:FileVersion=" + versionInfo.AssemblySemVer)
});
}else{
MSBuild(solution, new MSBuildSettings {
Configuration = configuration,
MaxCpuCount = maxcpucount,
ToolVersion = MSBuildToolVersion.VS2017,
Restore = true,
ArgumentCustomization = args => args
.Append("/p:Version=" + versionInfo.InformationalVersion.Replace("/", "-"))
.Append("/p:AssemblyVersion=" + versionInfo.AssemblySemVer)
.Append("/p:FileVersion=" + versionInfo.AssemblySemVer)
});
}
});
Looking at further build steps in cake and powershell there was mention of it compiling with mono instead of the default. Updating cake to version 2.0 and rewiting it from the ground up seems to resolve the issue.
Installing Visual Studio Build Tools 2022 and latest nuget.exe added to the environmental variable PATH seemed to help. Ideally installing everything that the build server has on it and running the same scripts locally helped a lot.
I am trying to use filescoped namespaces in visual studio 2019. So instead of:-
namespace my.namespace
{
public class MyClass
{
}
}
I want:-
namespace my.namespace;
public class MyClass
{
}
Following online tutorials and going through other answers I have tried adding editorConfig file but the editorConfig visual studio is generating for me is different than what I am seeing online. My file is starting with this text:-
# Rules in this file were initially inferred by Visual Studio IntelliCode from the C:\myproject codebase based on best match to current usage at 3/25/2022
# You can modify the rules from these initially generated values to suit your own policies
# You can learn more about editorconfig here: https://learn.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
[*.cs]
#Core editorconfig formatting - indentation
#use soft tabs (spaces) for indentation
indent_style = space
#Formatting - indentation options
#indent switch case contents.
csharp_indent_case_contents = true
#indent switch labels
csharp_indent_switch_labels = true
And this file has no information on filescoped namespaces.
I want to get the value of the element <Location>SourceFiles/ConnectionStrings.json</Location> that is child of <PropertyGroup /> using C#. This is located at the .csproj file for a .NET Core 2 classlib project. The structure is as follow:
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<Location>SharedSettingsProvider.SourceFiles/ConnectionStrings.json</Location>
</PropertyGroup>
Which class can I use from .NET Core libraries to achieve this? (not .NET framework)
Update 1:
I want to read the value when the application (that this .csproj file builds) runs. Both before and after deployment.
Thanks
As has been discussed in comments, csproj content only controls predefined build tasks and aren't available at run-time.
But msbuild is flexible and other methods could be used to persist some values to be available at run time.
One possible approach is to create a custom assembly attribute:
[System.AttributeUsage(System.AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
sealed class ConfigurationLocationAttribute : System.Attribute
{
public string ConfigurationLocation { get; }
public ConfigurationLocationAttribute(string configurationLocation)
{
this.ConfigurationLocation = configurationLocation;
}
}
which can then be used in the auto-generated assembly attributes from inside the csproj file:
<PropertyGroup>
<ConfigurationLocation>https://my-config.service/customer2.json</ConfigurationLocation>
</PropertyGroup>
<ItemGroup>
<AssemblyAttribute Include="An.Example.ConfigurationLocationAttribute">
<_Parameter1>"$(ConfigurationLocation)"</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
And then used at run time in code:
static void Main(string[] args)
{
var configurationLocation = Assembly.GetEntryAssembly()
.GetCustomAttribute<ConfigurationLocationAttribute>()
.ConfigurationLocation;
Console.WriteLine($"Should get config from {configurationLocation}");
}
I have the following pragma in one of the generated C# class and it is used to ignore a CLSCompliant warning
#pragma warning disable 3021
This works perfectly when compiling with msbuild 12. After upgrading my project to use msbuild 14, this warning is enabled again.
It seems to happen with partial class. This how I reproduce:
Create empty project in visual studio 2013(ToolsVersion=12.0)
Add new file TestPragmaFile1.cs with this content:
namespace TestPragma
{
public partial class TestPragma
{
}
}
Add new file TestPragmaFile2.cs with this content:
namespace TestPragma
{
#pragma warning disable 3021
[System.CLSCompliant(false)]
public partial class TestPragma
{
}
}
4.Compile by executing this command in the project directory(directory that contains csproj file):
"C:\Program Files (x86)\MSBuild\14.0\Bin\msbuild" /T:Clean;Build
Result:
"C:\Users\me\Documents\Visual Studio
2013\Projects\TestPragma\TestPragma\TestPragma.csproj" (Clean;Build
target) (1) -> (CoreCompile target) -> TestPragmaFile1.cs(5,26):
warning CS3021: 'TestPragma' does not need a CLSCompliant attribute
because the assembly does not have a CLSCompliant attribute
[C:\Users\me\Documents\Visual Studio
2013\Projects\TestPragma\TestPragma\TestPrag ma.csproj]
1 Warning(s)
0 Error(s)
Can you please help understand why this happens? Is it normal ? how to fix it ?
I solved the issue by adding #pragma warning disable 3021 to the first cs file(TestPragmaFile1.cs).
You may also want to try #JeroenMostert solution by adding [assembly:CLSCompliant(false)] to the assembly.
I have the following code contract:
public void F(string x)
{
Contract.Requires(!string.IsNullOrWhiteSpace(x));
throw new NotImplementedException();
}
When compiling, I get the following warning:
warning CC1036: Detected call to method 'System.String.IsNullOrWhiteSpace(System.String)' without [Pure] in contracts of method [...]
How to deal with it?
What's odd, is that I'm also using string.IsNullOrEmpty, which isn't marked as [Pure] as well, in other contracts and the rewriter does not have a problem with that.
My Contract Rewriter's Version is 1.9.10714.2.
This is the relevant part from the implementation of String class I'm using (retrieved from metadata):
#region Assembly mscorlib.dll, v4.0.0.0
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll
#endregion
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace System
{
// Summary:
// Represents text as a series of Unicode characters.To browse the .NET Framework
// source code for this type, see the Reference Source.
[Serializable]
[ComVisible(true)]
public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable, IComparable<string>, IEnumerable<char>, IEquatable<string>
{
// [...]
//
// Summary:
// [...]
public static bool IsNullOrEmpty(string value);
//
// Summary:
// [...]
public static bool IsNullOrWhiteSpace(string value);
Why is the [Pure] attribute missing?
Here we have two points:
1. Why is the [Pure] attribute missing in string class for IsNullorWhiteSpace function?
2. How to resolve the CC1030 warning issue?
I will try to discuss both.
1. Why is the [Pure] attribute missing? It's not missing, metadata does not seem to be showing this.
This may not be marked as Pure in previous version of .NET FX as, they were saying:
Yes, we need to make our checker sensitive to the disable pragma...
Sigh.
We currently don't have that implemented, but I've added it to our
work list.
Refer to the 5 year old discussion here.
But this has been marked as Pure in latest FX (4.6.1), Refer to .NET Framework 4.6.1, the new string class code.
[Pure]
public static bool IsNullOrWhiteSpace(String value) {
if (value == null) return true;
for(int i = 0; i < value.Length; i++) {
if(!Char.IsWhiteSpace(value[i])) return false;
}
return true;
}
Then Why CC1036?
This warning "CC1036" is from CodeContracts, developers have open this issue yesterday only (refer here).
Now why metadata is not spitting up Pure attributes, this is a different question, like for Equals method, Pure is added but only SecuritySafeCritical is displayed in metadata code.
[SecuritySafeCritical]
public static bool Equals(String a, String b, StringComparison comparisonType);
The same problem applies to Invariant(). Given the following code, the
same warnings are displayed:
private string testString = "test";
[ContractInvariantMethod]
private void TestInvariant()
{
Contract.Invariant(!string.IsNullOrWhiteSpace(testString));
}
How to resolve?
As others are also suggesting, create another method, mark it as Pure and call this in your contract condition.
Going through a pure delegate will make the warning go away. Predicate<T> is already marked pure, so you can just use that to work around the bug:
// Workaround for https://github.com/Microsoft/CodeContracts/issues/339
public Predicate<string> IsNullOrWhiteSpace = string.IsNullOrWhiteSpace;
public void F(string x)
{
Contract.Requires(!IsNullOrWhiteSpace(x));
throw new NotImplementedException();
}
Although kind of ugly, you can wrap the function string.IsNullOrWhiteSpace with an extension method and mark this new function as Pure.
I just encountered the exact same problem. I'm using VS2015, so it does not seem to be related to VS version. I also tested the exact same code on .NET 4.0, 4.5.1 and 4.6, without getting the warning.
Like others have commented before me, the IsNullOrWhiteSpace is marked as [Pure] in .NET 4.6.1, and additionally should by default be considered pure by Code Contracts because it is in the System.String namespace. This makes it look like a bug, so I have submitted an issue to Code Contracts about this, so with some luck we will see an official answer soon.
While we wait for an answer, it is possible (like #Jaco suggests) to wrap it in an extension method and mark it as Pure yourself. Optionally, you can suppress the warning for that particular method like this:
[SuppressMessage("Microsoft.Contracts", "CC1036", Justification = "string.IsNullOrWhiteSpace is Pure")]
... but note that this will also suppress this warning from other Contract definitions in the same method.
Actually, this is a problem with the way .NET 4.6+ is compiled. See this GitHub pull request.
I was able to work around this by modifying the following file(s):
For Visual Studio 2013:
C:\Program Files (x86)\Microsoft\Contracts\MsBuild\v12.0\Microsoft.CodeContracts.Targets
For Visual Studio 2015:
C:\Progarm Files (x86)\Microsoft\Contracts\MsBuild\v14.0\Microsoft.CodeContracts.Targets
In both files, ensure the <Otherwise> child element of the first <Choose> element has the following content shown below:
...
<Choose>
<When Condition="'$(TargetFrameworkIdentifier)' == 'Silverlight'">
...
</When>
<Otherwise>
<Choose>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.0">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.0</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.5'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.5.1'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.5.2'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.6'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<When Condition="'$(TargetFrameworkVersion)' == 'v4.6.1'">
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v4.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<CodeContractsReferenceAssemblyLibPath>$(CodeContractsInstallDir)Contracts\.NETFramework\v3.5</CodeContractsReferenceAssemblyLibPath>
</PropertyGroup>
</Otherwise>
</Choose>
</Otherwise>
</Chose>
...
After making these changes to these files (per the GitHub pull request referenced above), I no longer received Code Contracts static analysis warnings for the use of String.IsNullOrWhiteSpace.
It should be noted that the referenced pull request has been merged into the main code for Code Contracts up on GitHub; they just haven't made a new release containing these changes yet.
Also, for those concerned about changing "system files", don't be. When the next version of Code Contracts is released, it will install updated versions of these files--and hopefully the changes will be included, and all will be right with the world. (Unless, of course, the changes aren't included--in which case, you'll be coming back here to reference this post to make those changes again ;) lol.)