How to change assembly info in asp.net core? - asp.net-core

I want to versioning my asp.net core app.
I followed this link: http://www.matthiaseinig.de/2013/05/20/auto-generate-fileversion-for-all-projects-in-a-solution-with-t4/ , but I want to remove project assembly info, but I didn't find it.
How to remove duplicated assembly info? I want to override asp core assemblies with another file.
BETTER SOLUTION
After a while I realize that the best solution is to use a T4 file, the version is incremented automatically after each build.
look here:
http://www.matthiaseinig.de/2013/05/20/auto-generate-fileversion-for-all-projects-in-a-solution-with-t4/

Right now properties could be defined in .csproj or using AssemblyInfo.cs, but only the one place could be used, otherwise "Duplicate" errors are generated.
If you want to use AssemblyInfo.cs, add the following into .csproj to avoid duplication errors:
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
If you are interesting how does it work, look into GenerateAssemblyInfo task.
Otherwise, remove AssemblyInfo.cs and add the following property into your .csproj file:
<PropertyGroup>
<AssemblyVersion>1.2.3.4</AssemblyVersion>
</PropertyGroup>

Related

MSBuild 16.9 .NET Core 3.1 - OutDir isn't searched for dependencies

I'm trying to use MSBuild in a powershell script to build many projects and solutions in a full application suite. I set the parameter for OutDir to point to a single binaries directory and from an output perspective that works.
However the documentation states that OutDir is included in AssemblySearchPaths. But looking at the logs MSBuild is clearly stuck using the hintpath from the csproj file. I've tried setting AdditionalLibPaths as well with no success. This appears to be an issue with building from Visual Studio 2019 as well. My hintpaths point to a common debug directory. A release build still looks in the debug directory. This used to work in older versions of Studio in the .NET Framework days. It worked in older TFS XAML builds setting Output Location to "SingleFolder"
I've also played around with OutDir path ending various quantities of back slashes. I suspect that this old issue is fixed.
How can I get MSBuild to use an alternate directory for the dependencies?
https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties?view=vs-2019
EDIT:
As per the accepted answer, adding OutDir to the AssemblySearchPaths does the trick. For me, I've created a proj file that I've added to each .NET Core csproj files. My thought is that when this gets fixed I can remove the tweak in one place.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AssemblySearchPaths>$(AssemblySearchPaths);$(OutDir)</AssemblySearchPaths>
</PropertyGroup>
My hintpaths point to a common debug directory. A release build still
looks in the debug directory.
The outdir is always the output folder which does not distinguish between Release and Debug. So you have to use <OutDir>C:\ttt\$(Configuration)\</OutDir> to distinguish between them.
Actually, the system msbuild properties are read earlier than the start of build task. You have to set the properties before the start of build process.
Simply modifying the system properties outdir in csproj will only take effect during the build process, but the system properties are still read before the build starts, also AssemblySearchPaths property read the previous outdir property. So you always take the default values before the modification.
You have to use Directory.Build.props file, it set the values earlier than msbuild start.
1) create a file called Directory.Build.props under your project folder.
2) add the outdir property like these into the file.
<Project>
<PropertyGroup>
<OutDir>C:\ttt\$(Configuration)\</OutDir>
</PropertyGroup>
</Project>
3) restart VS to enable it.
However, I note that it works well in non-sdk net framework projects but it does not list under new-sdk net core projects.
non-sdk net framework projects
new-sdk net core projects
Not sure it is an issue or the Team has forgotten it. Anyway, I have reported it to our DC Forum. You can vote it or add any comments if I did not described it in detail.
As a workaround, you could try to set the new value for AssemblySearchPaths property.
In order not to lose the original value of AssemblySearchPaths, you must add it to csporj file rather than Directory.Build.props file.
Just add these into csproj file:
<PropertyGroup>
<AssemblySearchPaths>$(AssemblySearchPaths);$(OutDir)</AssemblySearchPaths>
</PropertyGroup>
Update 1
I think it is an issue for net core projects.
What I said before is for VS IDE build. Now for MSBuild Command Line, it is another situation.
For non-sdk net framework projects
When I used msbuild xxx\xxx.csproj -p:outdir=c:\ttt -v:diagnostic, it shows this:
Well. It works perfect as we wished.
However, when we used the same command line for new-sdk net core projects, it does nothing. So I think it is quite an issue for net core projects.
And you should note that AdditionalLibPaths cannot be recognized by AssemblySearchPaths.
When I used this under :
msbuild xxx\xxx.csproj -p:AdditionalLibPaths=c:\ttt -v:diagnostic
And you should note that there is no property for AdditionalLibPaths under the list of AssemblySearchPaths property. And it also does not work for net core projects.
In short, it is quite an issue for net core projects no doubt. I also modify the DC ticket.
Now for new-sdk net core projects,
Since you used msbuild command line to set properties, so there is no need to use Directly.Build.props file. MSbuild command line property assignment is actually the same effect of the file.
Also, AssemblySearchPaths is not ready-only. You could modify it. And actually, all msbuild properties can be overwritten and that is a flexible feature of MSBuild.
In summary, you still have to use AssemblySearchPaths.
Solution
Since The Team has some problems with this detail in the net core project, we can use the flexibility of MSbuild to manually modify to get what we want:
1) abandon using Directly.Build.props file and also keep adding these on the net core csproj file:
<PropertyGroup>
<AssemblySearchPaths>$(AssemblySearchPaths);$(OutDir)</AssemblySearchPaths>
</PropertyGroup>
2) use the following command line for net core projects:
msbuild xxx\xxx.csproj -p:Outdir=c:\ttt -v:diagnostic

Where do I set version of Asp.NET Core project? [duplicate]

Since dotnet core moved back to the .csproj format, there is a new autogenerated MyProject.AssemblyInfo.cs which contains, among others:
[assembly: AssemblyCompany("MyProject")]
[assembly: AssemblyVersion("1.0.0.0")]
Note that this is automatically regenerated every build.
Previously, the file was found in the /obj/ directory, now it appears to be only in memory as the file can't be found on disk and clicking the error message does not open any file.
This is the error message:
Since they are defined there, I can't define them myself in the classical AssemblyInfo.cs.
Where/how can I define the Company and Version of a project?
As you've already noticed, you can control most of these settings in .csproj.
If you'd rather keep these in AssemblyInfo.cs, you can turn off auto-generated assembly attributes.
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
If you want to see what's going on under the hood, checkout Microsoft.NET.GenerateAssemblyInfo.targets inside of Microsoft.NET.Sdk.
Those settings have moved into the .csproj file.
By default, they don't show up but you can discover them from Visual Studio 2017 in the project properties Package tab.
Once saved those values can be found in MyProject.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<Version>1.2.3.4</Version>
<Authors>Author 1</Authors>
<Company>Company XYZ</Company>
<Product>Product 2</Product>
<PackageId>MyApp</PackageId>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<FileVersion>3.0.0.0</FileVersion>
<NeutralLanguage>en</NeutralLanguage>
<Description>Description here</Description>
<Copyright>Copyright</Copyright>
<PackageLicenseUrl>License URL</PackageLicenseUrl>
<PackageProjectUrl>Project URL</PackageProjectUrl>
<PackageIconUrl>Icon URL</PackageIconUrl>
<RepositoryUrl>Repo URL</RepositoryUrl>
<RepositoryType>Repo type</RepositoryType>
<PackageTags>Tags</PackageTags>
<PackageReleaseNotes>Release</PackageReleaseNotes>
</PropertyGroup>
In the file explorer properties information tab, FileVersion is shown as "File Version" and Version is shown as "Product version"
I do the following for my .NET Standard 2.0 projects.
Create a Directory.Build.props file (e.g. in the root of your repo)
and move the properties to be shared from the .csproj file to this file.
This also enables central management of these shared properties in a multi project solution, allowing for example to set the copyright and/or version numbers only once for all projects.
MSBuild will pick it up automatically and apply them to the autogenerated AssemblyInfo.cs.
They also get applied to the nuget package when building one with dotnet pack or via the UI in Visual Studio 2017.
See https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-your-build
Example:
<Project>
<PropertyGroup>
<Company>Some company</Company>
<Copyright>Copyright © 2020</Copyright>
<AssemblyVersion>1.0.0.1</AssemblyVersion>
<FileVersion>1.0.0.1</FileVersion>
<Version>1.0.0.1</Version>
<!-- ... -->
</PropertyGroup>
</Project>
You can always add your own AssemblyInfo.cs, which comes in handy for InternalsVisibleToAttribute, CLSCompliantAttribute and others that are not automatically generated.
Adding AssemblyInfo.cs to a Project
In Solution Explorer, right click on <project name> > Add > New Folder.
Name the folder "Properties".
Right click on the "Properties" folder, and click Add > New Item....
Select "Class" and name it "AssemblyInfo.cs".
Suppressing Auto-Generated Attributes
If you want to move your attributes back to AssemblyInfo.cs instead of having them auto-generated, you can suppress them in MSBuild as natemcmaster pointed out in his answer.
Adding to NightOwl888's answer, you can go one step further and add an AssemblyInfo class rather than just a plain class:
I want to extend this topic/answers with the following. As someone mentioned, this auto-generated AssemblyInfo can be an obstacle for the external tools. In my case, using FinalBuilder, I had an issue that AssemblyInfo wasn't getting updated by build action. Apparently, FinalBuilder relies on ~proj file to find location of the AssemblyInfo. I thought, it was looking anywhere under project folder. No. So, changing this
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
did only half the job, it allowed custom assembly info if built by VS IDE/MS Build. But I needed FinalBuilder do it too without manual manipulations to assembly info file. I needed to satisfy all programs, MSBuild/VS and FinalBuilder.
I solved this by adding an entry to the existing ItemGroup
<ItemGroup>
<Compile Remove="Common\**" />
<Content Remove="Common\**" />
<EmbeddedResource Remove="Common\**" />
<None Remove="Common\**" />
<!-- new added item -->
<None Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Now, having this item, FinalBuilder finds location of AssemblyInfo and modifies the file. While action None allows MSBuild/DevEnv ignore this entry and no longer report an error based on Compile action that usually comes with Assembly Info entry in proj files.
C:\Program Files\dotnet\sdk\2.0.2\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.DefaultItems.targets(263,5):
error : Duplicate 'Compile' items were included. The .NET SDK includes 'Compile' items from your project directory by default.
You can either remove these items from your project file, or set the 'EnableDefaultCompileItems' property to 'false' if you want to explicitly include them in your project file.
For more information, see https://aka.ms/sdkimplicititems. The duplicate items were: 'AssemblyInfo.cs'
Thanks, this helped me a lot.
In my case, building the project Blazor Server Side Website was successful both on Release and Debug, but publishing the website still failed with the Duplicate Attribute error, which confused me a bit.
The solution was to add <GenerateAssemblyInfo>false</GenerateAssemblyInfo> both to the .csproj and .pubxml file:
Path: <Project>/Properties/PublishProfiles/<ProfileName>.pubxml:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
...
<!-- Add the line below -->
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
</Project>
With .NET 5+, you can use AssemblyMetadata:
<AssemblyMetadata Include="Bar" Value="Baz" />

Visual Studio 2017 and the new .csproj InternalsVisibleTo

Where do I put InternalsVisibleTo from AssemblyInfo in the new Visual Studio 2017 .csproj project file?
Just in case anyone would like to put InternalsVisibleTo within a .csproj file instead of AssemblyInfo.cs (a possible scenario is to have a naming convention between a project under test and a test project), you can do it like this:
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Test</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
Having this the following code will be generated
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyProject.Test")]
inside auto-generated AssemblyInfo.cs (e.g. for Debug configuration and .NET Standard 2.0 target)
/obj/Debug/netstandard2.0/MyProject.AssemblyInfo.cs
Additional Info
In case you're on .NET Core 3.1 and this approach isn't working, you may have to explicitly generate assembly info by adding the following to your .csproj file:
<PropertyGroup>
<!-- Explicitly generate Assembly Info -->
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
</PropertyGroup>
As of .NET 5 (and newer .NET versions) this actually works once added to your csproj:
<ItemGroup>
<InternalsVisibleTo Include="YourProject.Tests.Unit" />
</ItemGroup>
Work and discussion around this feature can be seen on this PR on dotnet's GitHub repo.
To clarify Hans Passant's comment above, you simply have to add InternalsVisibleTo to any cs file in your project. For example, I created an AssemblyInfo.cs file in the root of the project and then added the following content (only):
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=<ADD_KEY_HERE>")]

.net core (csproj) global.json 'projects' equivalent

With .net core (project.json) I used to switch between nuget packages and source code by adding the path to source code to the projects field in the global.json. After I did that it would add all the projects that it could find in that path that could replace the nuget packages I referenced.
I used this feature alot because I have my own nuget packages that I use, but I want to test the changes in my other project before I publish. But once I switched to Sdk 1.0.0/VS 2017/csproj .net core that feature seemed to disappear.
The alternative is just manually adding each project, switch the references manually (since they are broken up into project, nuget and sdk references), and then after switch it all back.
Any thoughts or advice would be great.
UPDATE:
Sounds like there is no equivalent in csproj (as expected), but there are msbuild workarounds for now (As of the initial VS 2017/.NET Core SDK 1.0.0 release)
Yes, I too had gotten used to this functionality and built my workflow around it. I am still looking for a solution but I'm currently playing with the idea of using conditional logic in the csproj files. Since it's now msbuild, you can do things like this:
<Choose>
<When Condition="Exists('..\..\..\MyProject')">
<ItemGroup>
<ProjectReference Include="..\..\..\MyProject\src\MyProject\MyProject.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="MyProject" Version="1.0.0" />
</ItemGroup>
</Otherwise>
</Choose>
This replaces the hard reference to a package with a conditional that uses a project reference if it can find the source code (in this case the directory), and a package reference if can't.
So by default you would be referencing the package, but if you want to debug one of your projects, you check it out in the location that the conditional checks, and add the project to your solution.
This way you only need to change your solution file (by adding the project) when you want to include source code, instead of rewiring all your project references.
For others that are interested in attempting to emulate with Global.json did, I worked around this for now using a couple powershell scripts and a custom json file that mimics it. Check out my answer here:
https://stackoverflow.com/a/43795974/5504245

MSBuild - Determine a solution's _PublishedWebsites

I am writing a web development targets file and would like to programmatically determine the name of the directory that appears beneath "_PublishedWebsites".
I currently have to use this:
$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\_PublishedWebsites\ MyWebApplication
Any ideas?
(I am not using this for solutions with more than one website to publish)
The new Web Publishing Pipeline (WPP) in .NET 4.0 has a method for controlling the output location.
First, you need to opt-in to WPP during the execution of the CopyWebApplication target. Set the following MSBuild properties, either at command line or in the MSBuild project file:
<PropertyGroup>
<UseWPP_CopyWebApplication>True</UseWPP_CopyWebApplication>
<PipelineDependsOnBuild>False</PipelineDependsOnBuild>
</PropertyGroup>
The command line-variant is:
/p:UseWPP_CopyWebApplication=True /p:PipelineDependsOnBuild=False
Next, create a new MSBuild targets file in the same directory as your project and name it "ProjectName.wpp.targets" where "ProjectName" is the filename of your project, minus the extension. In other words, if you have "MyWebsite.csproj" you need to create "MyWebsite.wpp.targets". I find it helps to add the targets file to the project as well. It's not required, but it makes it easier to edit.
In the new targets file, you will need to override the WebProjectOutputDir property. Only do this when CopyWebApplication will be called - in other words, when the "OutDir" is redirected away from the "OutputPath":
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebProjectOutputDir Condition="'$(OutDir)' != '$(OutputPath)'">$(OutDir)Websites\MyCustomFolderName</WebProjectOutputDir>
</PropertyGroup>
</Project>
That's it - you should be good to go. You can test it locally by setting the OutDir property. Don't forget the trailing backslash:
msbuild MyWebsite.csproj /p:OutDir=C:\Development\WebOutputTest\