dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.73k stars 1.07k forks source link

Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute #7153

Closed SamvelS closed 4 years ago

SamvelS commented 8 years ago

Steps to reproduce

I am using 1.0.0-preview4-004079 prerelase version of .Net core. My csproj file is following:

<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="**\*.cs" />
    <EmbeddedResource Include="**\*.resx" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NETCore.App">
      <Version>1.0.1</Version>
    </PackageReference>
    <PackageReference Include="Microsoft.NET.Sdk">
      <Version>1.0.0-alpha-20161104-2</Version>
      <PrivateAssets>All</PrivateAssets>
    </PackageReference>
    <PackageReference Include="System.Collections.Specialized">
    <Version>4.0.1</Version>
    </PackageReference>
  </ItemGroup> 
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

After dotnet restore I don't get any error or warning, but after dotnet build I am getting 9 errors like error CS0579: Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute .

Is this because of incorrect version of System.Collections.Specialized and how to fix this?

dasMulli commented 8 years ago

Ran into that myself when already having a Properties\AssemblyInfo.cs in the project with an [assembly: AssemblyCompany("..")] attribute. The SDK now has targets that emit these attributes to a generated AssemblyInfo.cs that is included during build. (Here) If this is indeed your problem, you can either move all existing Attributes to the .csproj by adding a <Company>Evilcorp</Company> property or suppress the generation of the attribute by specifying <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>.

SamvelS commented 8 years ago

In my case I need to remove bin and obj folders after any change, do restore and then build. This fixed issue.

TheRealPiotrP commented 8 years ago

@SamvelS we need to improve that experience. As @dasMulli suggests, there are already flags in place for disabling any auto-generation of attributes that you are explicitly specifying. What attributes are you defining in assemblyinfo.cs? I'd first like to give you the right content to put in the csproj file, then hear your and @dasMulli's thoughts on how to improve this UX.

/cc @livarcocc @nguerrera

TheRealPiotrP commented 8 years ago

/cc @blackdwarf

SamvelS commented 8 years ago

@piotrpMSFT I didn't specify any argument at all. Everything is what was generated. The problem was with inner project. I was trying to create solution like structure, created inner folder (on same directory as root csproj file) and added new project to it. After that first was building inner project (which was generating bin and obj folders) and after that root project. I removed inner bin/obj folders and started to build only root. Also deleting bin/obj folders every time I need to call 'dotnet restore'. I was thinking that I will need to add reference to inner project but it is working without adding anything to root folder, which can cause lots of issues as on .Net many projects in solution can have classes with same name and in same namespace but here it can't happen. One more issue is that on version 1.0.0-preview4-004079 <OutputType>Exe</OutputType> is not considered and it is always generating DLL instead of exe.

TheRealPiotrP commented 8 years ago

@SamvelS I see. So you have:

/myproj
  /myproj.csproj
  /myinnerproj
    /myinnerproj.csproj

Is that right? Then for the first issue, you should be able to modify your myproj.csproj's compile Items like this:

  <Compile Include="**\*.cs" Exclude="bin\**;obj\**;myinnerproj\**.*" />

You may need to play with the glob a little, but this will allow the outer project to ignore the sources of the inner project.

RE the issue can you create a bug with a repro? CLI build generates many EXE's and we've not seen such a problem so far...

SamvelS commented 8 years ago

For first one structure is correct. I will try DLL part with tomorrows build as well and will create a bug if will see it again. I tested on Windows and Mac OS.

dasMulli commented 8 years ago

@piotrpMSFT So i just gave the migration code that parses the AssemblyInfo.cs a short test to try to reproduce my former issue. The migration fails with the following attributes (using the full namespace and/or the "Attribute" suffix):

[assembly: System.Reflection.AssemblyCompany("fooo")]
[assembly: System.Reflection.AssemblyProduct("TestApp")]
[assembly: System.Reflection.AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersionAttribute("1.0.0.0")]

used dotnet version was 1.0.0-preview3-004056. I'll try with the latest preview4 in a few minutes (sloooow download here in austria).

dasMulli commented 8 years ago

Same with 1.0.0-preview4-004079. The migration issue can be worked around by adding the corresponding <Generate*Attribute>false</..>. Or by not being such a :trollface: and sticking to the templates and good code styling.

VSCode IntelliSense currently gives the ...Attribute version for completion in 1.5.0

screen shot 2016-11-15 at 21 38 48
TheRealPiotrP commented 8 years ago

Thanks for hunting down the root cause, @dasMulli

TheRealPiotrP commented 8 years ago

/cc @livarcocc

SamvelS commented 8 years ago

@piotrpMSFT I tried suggested solution with adding Exclude to Compile section and getting following crash:

MSBUILD : error MSB1025: An internal failure occurred while running MSBuild.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Build.Shared.FileMatcher.GetFiles(String projectDirectoryUnescaped, String filespecUnescaped, IEnumerable`1 excludeSpecsUnescaped, GetFileSystemEntries getFileSystemEntries, DirectoryExists directoryExists)
   at Microsoft.Build.Internal.EngineFileUtilities.GetFileList(String directoryEscaped, String filespecEscaped, Boolean returnEscaped, IEnumerable`1 excludeSpecsEscaped)
   at Microsoft.Build.Evaluation.LazyItemEvaluator`4.IncludeOperation.SelectItems(Builder listBuilder, ImmutableHashSet`1 globsToIgnore)
   at Microsoft.Build.Evaluation.LazyItemEvaluator`4.LazyItemOperation.Apply(Builder listBuilder, ImmutableHashSet`1 globsToIgnore)
   at Microsoft.Build.Evaluation.LazyItemEvaluator`4.MemoizedOperation.Apply(Builder listBuilder, ImmutableHashSet`1 globsToIgnore)
   at Microsoft.Build.Evaluation.LazyItemEvaluator`4.LazyItemList.ComputeItems(LazyItemList lazyItemList, ImmutableHashSet`1 globsToIgnore)
   at Microsoft.Build.Evaluation.LazyItemEvaluator`4.LazyItemList.GetItems(ImmutableHashSet`1 globsToIgnore)
   at Microsoft.Build.Evaluation.LazyItemEvaluator`4.<>c.<GetAllItems>b__22_0(LazyItemList itemList)
   at System.Linq.Enumerable.<SelectManyIterator>d__157`2.MoveNext()
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source, Int32& length)
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.ToList()
   at Microsoft.Build.Evaluation.LazyItemEvaluator`4.GetAllItems()
   at Microsoft.Build.Evaluation.Evaluator`4.Evaluate()
   at Microsoft.Build.Execution.ProjectInstance.Initialize(ProjectRootElement xml, IDictionary`2 globalProperties, String explicitToolsVersion, String explicitSubToolsetVersion, Int32 visualStudioVersionFromSolution, BuildParameters buildParameters, ILoggingService loggingService, BuildEventContext buildEventContext)
   at Microsoft.Build.Execution.ProjectInstance..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, BuildParameters buildParameters, ILoggingService loggingService, BuildEventContext buildEventContext)
   at Microsoft.Build.BackEnd.RequestBuilder.LoadProjectIntoConfiguration()
   at Microsoft.Build.BackEnd.RequestBuilder.<BuildProject>d__57.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.Build.BackEnd.RequestBuilder.<BuildAndReport>d__49.MoveNext()

MSBUILD : error MSB1025: An internal failure occurred while running MSBuild.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Build.CommandLine.MSBuildApp.BuildProject(String projectFile, String[] targets, String toolsVersion, Dictionary`2 globalProperties, ILogger[] loggers, LoggerVerbosity verbosity, DistributedLoggerRecord[] distributedLoggerRecords, Int32 cpuCount, Boolean enableNodeReuse, TextWriter preprocessWriter, Boolean debugger, Boolean detailedSummary)
   at Microsoft.Build.CommandLine.MSBuildApp.Execute(String[] commandLine)

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Build.CommandLine.MSBuildApp.BuildProject(String projectFile, String[] targets, String toolsVersion, Dictionary`2 globalProperties, ILogger[] loggers, LoggerVerbosity verbosity, DistributedLoggerRecord[] distributedLoggerRecords, Int32 cpuCount, Boolean enableNodeReuse, TextWriter preprocessWriter, Boolean debugger, Boolean detailedSummary)
   at Microsoft.Build.CommandLine.MSBuildApp.Execute(String[] commandLine)
   at Microsoft.Build.CommandLine.MSBuildApp.Main(String[] args)
TheRealPiotrP commented 8 years ago

@SamvelS do you have a minimal repro you can share?

SamvelS commented 8 years ago

@piotrpMSFT sure, here is project https://dl.dropboxusercontent.com/u/65479031/folder.zip. When you try to restore, it gives error above.

TheRealPiotrP commented 8 years ago

Thanks for that! What a gnarly bug.

@cdmihai @rainersigwald @jeffkl can you guys take a look? NullRef in MSBuild!

rainersigwald commented 8 years ago

Nasty indeed. I suspect the same root cause as https://github.com/Microsoft/msbuild/pull/1349.

TheRealPiotrP commented 8 years ago

@rainersigwald do you want this in MSBuild repo? We can't do much here in CLI so I'd like to close...

rainersigwald commented 7 years ago

Yes, let's call Microsoft/msbuild#1349 the original and close this as a duplicate.

Bartmax commented 7 years ago

in my case, deleting Properties/AssemblyInfo.cs did the trick.

rkeithhill commented 7 years ago

What happened to this property? <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>

I just updated VS 2017 Preview today and I tried this property and it doesn't work. What's more I don't see it in the project file Intellisense list.

dasMulli commented 7 years ago

@rkeithhill could you be a little more specific about your issue? like what exactly did not work - or what your expectation was. If it is not related to the project.json > csproj migration, I'd suggest opening a new issue (ideally at https://github.com/dotnet/sdk where the attribute generation and defaulting logic comes from)

rkeithhill commented 7 years ago

Sure. We auto-generate our own AssemblyInfo.common.cs file that we link into each project. This file defines all the normal assembly level attributes like AssemblyVersion, AssemblyInformationalVersion, AssemblyCompany. We are getting errors along the lines of Duplicate 'System.Reflection.AssemblyVersionAttribute' attribute. When I found this issue, I thought the suggestion to turn off the SDK's generation of these attributes with the MSBuild property was the hot ticket. But AFAICT that property no longer exists.

Indeed it isn't related to project file migration. So I'll open an issue on the SDK repo. Thanks!

livarcocc commented 7 years ago

We do honor this attribute in the SDK. I wonder if you didn't have this set, so the assembly file got generated, then you set it, but you didn't clean it, so the file is still there. Can you try deleting your obj/bin folder and trying the build?

rkeithhill commented 7 years ago

I think the name might have changed? <GenerateAssemblyInfo>false</GenerateAssemblyInfo> does seem to work.

livarcocc commented 7 years ago

Here is the code: https://github.com/dotnet/sdk/blob/release/2.0.0/src/Tasks/Microsoft.NET.Build.Tasks/build/Microsoft.NET.GenerateAssemblyInfo.targets#L26.

The one you reference above can be used to prevent a whole set of the properties from being turned on by default. But notice that if something else sets them to true, setting the one above will not set them to false. Just keep that in mind.

FransBouma commented 7 years ago

Will the error reported by the build be updated? It's currently unclear one has to add a GenerateAssemblyInfo element to the csproj manually. In fact, if I hadn't found this github issue I might have never known about it. 😄 (I ran into the same issue as others in this thread: duplicate assemblyinfo attributes as I too use a shared cs file among all projects of my system)

rkeithhill commented 7 years ago

@FransBouma FYI https://github.com/dotnet/sdk/issues/438

Jdrew001 commented 7 years ago

I deleted the bin directory, obj directory and the AssemblyInfo.cs file in the Properties directory.

Ran dotnet restore then build and it fixed the issue.

eddyekofo94 commented 7 years ago

I simply commented out everything on the myPoject.AssemblyInfo.cs file

using System; using System.Reflection; // //[assembly: System.Reflection.AssemblyCompanyAttribute("myPoject")] //[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] //[assembly: System.Reflection.AssemblyDescriptionAttribute("Package Description")] //[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] //[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] //[assembly: System.Reflection.AssemblyProductAttribute("myPoject")] //[assembly: System.Reflection.AssemblyTitleAttribute("myPoject")] //[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

And then it worked? A desperate move, maybe a quick fix but it's the only thing that worked.

jeffreyschultz commented 7 years ago

Why not just set GenerateAssemblyInfo to false in the PropertiesGroup in your project file? The .targets file mentioned above has a condition on this property that determines whether those properties are set.

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

RobinHSanner commented 6 years ago

This is the only place I've been able to find this information. It would be nice if it was part of the documentation.

cmooring commented 6 years ago

I've just found this same issue when playing around with dotnet core and vscode.

I have dotnet core version 2.1.300 and vs code version 1.23.1 with Microsoft's C# extension installed.

I simply run the following in an empty directory; dotnet new mvc code .

Wait until the C# extension offers to add my launch and tasks json files and then hit F5 to debug the default app that is created. At some point after doing nothing more than opening and closing the code, I find I have 7 errors

image

@TheRealPiotrP - back to your point about fixing the user experience around this, is this something that will likely be addressed? It doesn't impact my ability to continue exploring, but it might impede adoption if simple things like that throw up errors.

livarcocc commented 6 years ago

This is a very old issue that has since been closed. If this is consistent for you, I would suggest filling a separate new issue for it, though, I just tried it and could not repro it.

Does this happen to you when doing a dotnet build from the command line? If so, could you provide a binary log of your build for us to investigate?

cmooring commented 6 years ago

Sorry @livarcocc, I just stumbled across this while searching for issues around the error I was seeing.

I wasn't able to re-produce the error with either dotnet build from the command line, so I suspect it is just something that happens within VS Code. I did notice that some errors were persisting in VS Code and would simply disappear if I closed it and opened it again. If I can get a reliable reproduction of it, I'll raise it with the VS Code team.

trosel commented 6 years ago

@cmooring I also had this occur when doing a dotnet new web -o mywebapp tutorial in VS Code...

Very bizarre first experience as all I did was just use the command line tool to create a new app. And it created it with problems?

Full list of issues is below: image

ryanbuening commented 6 years ago

Same Issue here with <TargetFramework>netcoreapp2.1</TargetFramework> and VS Code 1.25.0.

image

dasMulli commented 6 years ago

Does that error occur only in vs code or does it also happen when invoking dotnet build from the command line? if so, could you call dotnet build -bl and upload the msbuild.binlog file it creates?

ryanbuening commented 6 years ago

@dasMulli I have not been able to reproduce it when invoking dotnet build from the command line.

cmooring commented 6 years ago

@ryanbuening and @WildYorkies, I think this might well be more to do with vscode than dotnet itself. I haven't spent any time trying to make a reliable reproduction of the issue, but if I get a chance, I will try and raise it with as an issue at https://github.com/Microsoft/vscode

If you feel you have a reliable reproduction of it now, maybe you could raise it in the meantime. Hopefully they'll have some ideas on how to identify what the issue is and how to solve it, as it really does detract from what is otherwise a great development environment.

dasMulli commented 6 years ago

Interesting.. if so the repo for the C# extension would be https://github.com/OmniSharp/omnisharp-vscode

trosel commented 6 years ago

When I tried to replicate this, I couldn't even get the RazorTargetAssemblyInfo object to generate at all. I even set up the project in the same way as the first one.

I suppose it's something that it thinks it needs to pull in because it doesn't detect it the first time? Then subsequent times, it detects it and thus does not duplicate....

dasMulli commented 6 years ago

Oh I completely missed the razor part. I believe you need to set

<PropertyGroup>
  <EnableDefaultRazorTargetAssemblyInfoAttributes>false</EnableDefaultRazorTargetAssemblyInfoAttributes>
</PropertyGroup>

in the .csproj file.

If you have more issues with it, think this is too complex or it doesn't behave as expected, file an issue over at https://github.com/aspnet/Razor

gacardinal commented 4 years ago

Just to chime in on this in the hope of possibly helping someone in the future, what caused the problem for me was when I changed the target framework of my library from netcoreapp2.1 to netstandard3.0. After trying to compile my lib with dotnet build -c Debug, it turned out that every single attribute in the AssemblyInfo.cs was marked as 'duplicate'. I simply deleted the obj directory and recompiled successfully. Also if you're using VSCode with Omnisharp, you'll probably just have to hit Ctrl + Shift + P to bring up the command palette, and execute the OmniSharp Restart OmniSharp command to get rid of the errors in VSCode.

JimmyCushnie commented 4 years ago

I was getting this error on a project with multiple target frameworks. The problem was that AssemblyInfo.cs was being generated multiple times, one for each target framework. The solution was to disable the auto-generation on all frameworks but one.

<PropertyGroup>
  <TargetFrameworks>netcoreapp3.0;</TargetFrameworks>
  <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
</PropertyGroup>

<PropertyGroup>
  <TargetFrameworks>net46;</TargetFrameworks>
  <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

<PropertyGroup>
  <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
  <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
TroyWitthoeft commented 4 years ago

Looking at 4783, it seems this is by design? Are we sure this is what we want? Would we consider changing the default behavior of the CLI to NOT generate AssemblyInfo.cs file? Let developers opt-in to this behavior? I understand we want the csproj file to be terse. But this default behavior is having the opposite effect. Folks are now adding

  <PropertyGroup>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>

everywhere. Check the bottom of 4783 for examples. Should we not be moving away from Assembly Info? Let's make it opt-in by default! This would encourage folks to have more complex projects and use more of the cli. For instance, my team is trying to get into unit testing. So we ....

dotnet new console dotnet new xunit --name MyTests cd MyTests dotnet build cd.. dotnet build

The steps above yield a nicely abstract CS5079 error and their projects are slowed. Is having the AssemblyInfo by default more important than encouraging composition, unit testing, and subprojects?

dasMulli commented 4 years ago

@TroyWitthoeft are you creating projects inside of the directory of other projects? That is currently blocked because the default csproj file assumes all content to be part of the project itself. so once you fix the assembly attribute issues, you'll get missing references because all the nested project's .cs files will be imported as well.

In this case you should rather exclude these directories from the "outer" project:

  <PropertyGroup>
    <DefaultItemExcludes>$(DefaultItemExcludes);innerproject\**</DefaultItemExcludes>
  </PropertyGroup>

Changing the behavior to opt-in would be a beraking change, because projects that don't have an assembly info source file would loose metadata information.

nhanhgon commented 4 years ago

Same Issue here with <TargetFramework>netcoreapp2.1</TargetFramework> and VS Code 1.25.0.

image

Add in .csproj for everyone `

false

`

mishka88ru commented 4 years ago

I am using this to remove duplicated attributes messages (Core 3.1):

<PropertyGroup>
  <GenerateAssemblyInfo Condition=" '$(Configuration)' == 'Debug' ">false</GenerateAssemblyInfo>
  <Product>qwe</Product>
  <Company>asd</Company>
  <Authors>zxc</Authors>
  etc from https://docs.microsoft.com/dotnet/core/tools/csproj
</PropertyGroup>
TroyWitthoeft commented 4 years ago

@dasMulli Yes, I have a project in a subfolder. Thanks for catching that. That wasn't root cause, but did confuse things. The issue does exists, regardless of project/folder structure.

Instead of "opting in" - defaulting to no AssemblyInfo.cs generation - would we consider making an IDE level setting that determined whether the AssemblyInfo.cs file was created? This is happening with quite a few folks that are bouncing between dotnet versions. That flag would reduce the number folks needing to explicitly edit the .csproj files and add

  <PropertyGroup>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>

which is causing a lot of project to not have that metadata information anyways.

dasMulli commented 4 years ago

At this point, if folks are suggestion behvaior / functional changes, i'd sugest creating a new issue for specifically discussing that instead of continuing to comment on a closed issue. just for the sake of visibility.

Peronally I think the default is good. There should be no need for an assembly info file for new projects and templates and default behavior should reflect that.

These error messages really only come up when you are migrating a project over to .NET core (and soon likely .NET 5) so i would expect people to hit this. I think this is okay since that is a deliberate change / setup activity. I believe what is needed there is perhaps documentation improvements or more actionable error messages. Would that have helped you? So as long as there's documentation (guides, StackOverflow issues with answers) that tell you why you hit this when migrating your WinForms/WCF/(Xamarin -> .NET 5 ?) app and how to go foward that is okay. (cc @richlander)

As for the idea of detecting assembly info files to base generation off it: That's actually very flaky. There's really no way to tell from the name of source files if some attributes are present in it. People that sticked to templates will have a Properties/AssemblyInfo.cs file but others may have created an additional ../SharedAssemblyInfo.cs file or split it up. So I'd rather not go for a flaky option that may work for some users but not for others in favour of predictability.