24

I have two projects in VS2015

  1. One .NET Core (project.json, xproj)
  2. One regular .NET csproj

When I open project 1 with VS2017, it nicely migrates to the new csproj format.

Project 2 works in VS2017, but I like to convert/migrate/update this csproj to the new project file format to benefit from the new csproj features (multi target, no large file list, readable csproj, NuSpec info in csproj etc)

How could I do that? I cannot find an option in VS2017 for that.

Using: VS2017 RTM

Julian
  • 26,655
  • 14
  • 92
  • 132
  • 1
    I answered this question in another post, http://stackoverflow.com/questions/42659684/how-to-upgrade-csproj-files-with-vs2017/42807657#42807657 – Mark Mar 15 '17 at 10:57
  • 1
    well my question was a month before "the duplicate", so the other is the duplicate? – Julian Mar 23 '17 at 11:38
  • 1
    Although @Julian your accepted answer, that there is not an option is incorrect, as opposed to the dup which has the right answer which tells how to do it. – jbtule Mar 23 '17 at 15:39
  • well according to https://github.com/dotnet/sdk/issues/491 it's indeed not supported? Or am I missing something? – Julian Mar 23 '17 at 16:00
  • @Julian no they are not saying it isn't supported, they are just complaining that you have to add 6 more lines for Portable Profiles and a few other legacy targets that they didn't include implicit monikers for in the current sdk. – jbtule Mar 23 '17 at 16:32
  • https://github.com/dotnet/sdk/blob/master/src/Tasks/Microsoft.NET.Build.Tasks/build/Microsoft.NET.TargetFrameworkInference.targets – jbtule Mar 23 '17 at 16:41
  • @Mark meta stack overflow as go with the higher quality answer. I'm marking this as a dup. https://meta.stackoverflow.com/questions/251938/should-i-flag-a-question-as-duplicate-if-it-has-received-better-answers – jbtule Mar 29 '17 at 20:43
  • @jbtule This question was before the linked one – Julian Mar 29 '17 at 21:26
  • 1
    @Julian as stated, see meta policy linked above, If the new question has better answers, then vote to close the old one as a duplicate of the new one. – jbtule Mar 29 '17 at 21:31
  • I don't think we should promote question copying/not using the search when creating a new question. – Julian Mar 29 '17 at 21:40
  • 1
    @Julian Agreed. That is why voting to close duplicate questions is important. I think it is unfair to the original poster if their question is closed and it was asked first. However, doing so does benefit the greater good if the duplicate contains a better answer. – Mark Mar 29 '17 at 22:10
  • In time the other question got indeed better answers thus I closed this one as duplicate (even if I was "first"). It's indeed more important that users get the best answers. – Julian Jun 26 '19 at 16:32

2 Answers2

8

It may be worth your time to look at these. It looks like it can't be done for more complex project types but console and libraries appear to be upgradable http://www.natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/

https://github.com/NickCraver/PerfBenchmarks/commit/53c3013b1774056363dcab867bceb1b89ce9592c

And regarding the addition of the more complex sdk types you can watch this github issue.

https://github.com/dotnet/sdk/issues/491

SkyrawrCode
  • 612
  • 6
  • 10
3

There isn't an option built into VS because the cleaner csproj is primarily for .NET Core projects. It does not fully work with all other project types without some effort and futher customizations in the project file. For example, wiring up things like code generators or nesting in Winforms or WPF apps may not work out of the box for a new SDK-style (new style) .csproj. These can usually be worked around by updating metadata as needed:

<ItemGroup>
  <Compile Update="Properties\Resources.Designer.cs">
    <AutoGen>True</AutoGen>
    <DependentUpon>Resources.resx</DependentUpon>
  </Compile>
</ItemGroup>

Note that the Update attribute is key here - you don't want to include the file a second time in the ItemGroup, you just want to update its existing (or lacking) metadata.

There are also some caveats for some project types where targets do not get imported as expected in an SDK-based csproj vs and old one. This depends on how your targets are authored, but one example of this is building VSIX projects (VS extensions) using the VSSDK is really hard to get right in an SDK-based project.

If you want to try the conversion, Nate McMaster's blog post is an excellent resource. He covers both starting from scratch and converting the file in situ. I've found that most of the time it goes pretty smoothly to start with a new clean .csproj and add in any workaround needed.

It's also worth pointing out that a lot of the crap in your normal csproj file is just generated content, and a little hand-editing can go a long way towards cleaning it up. Using globbing patterns, for example, can save hundreds of lines in a large project file. This is part of how SDK-based projects work anyways - they just do the globs in the SDK, so it doesn't show up in the .csproj, but it works nearly the same. For example, if you want to include all the C# files under a folder (recursively), you can do something like this:

<ItemGroup>
  <!-- Include all C# files under the SampleFolder and any child folders -->
  <Compile Include="SampleFolder\**\*.cs" />
  <!-- Include all C# files under this project's root: -->
  <Compile Include="**\*.cs" />
<ItemGroup>

The ** matches any recursive folder path.

There are some differences in Visual Studio behavior, because the new project system for SDK-based projects works very different than the old .csproj project system. For example, SDK-projects will automatically detect when files change on disk and add/remove them in the projects; old-csproj won't update them in VS until the project is reloaded.

If you do use globbing everywhere, you'll run into a similar problem as in SDK-based csproj, where certain files are not hooked up to their code generators or nested correctly. As above, you can use the Update= attribute to fix up specific files (or even more specific globs) to get the metadata back to the same.

Jimmy
  • 23,789
  • 5
  • 77
  • 88
  • 6
    how could it be .NET Core only as we could target multiple frameworks, including (full) NET46? – Julian Mar 08 '17 at 20:41
  • The SDK is making it possible to target multiple frameworks. From the project system point of view, it's still a Core project. – Jimmy Mar 08 '17 at 21:30
  • It's a bit hard to send feedback about a feature if you're unable to use the feature. – kjbartel Mar 10 '17 at 01:39
  • 1
    @kjbartel You can write whatever you want in the feedback, like "please simplify all .csproj files the way they are for .NET Core" – Jimmy Mar 10 '17 at 02:00
  • 2
    The new csproj works fine with the other frameworks however VS2017 does not use it as the default. – Mark Mar 24 '17 at 02:27
  • I don't recommend mixing the csproj formats. Buggy as hell, references randomly get lost, redirect bindings don't work properly etc. – rolls Dec 11 '17 at 05:55
  • The "cleaner" format is for VS2017, not just for .net core. VS2017 can handle the older and newer format for .NET framework projects and the newer format for .NET Core/Standard. – bytedev Jul 31 '18 at 16:23
  • @bytedev (and others who've commented) I've updated the answer to be more informative about why the new csproj format doesn't always work for some existing projects. Let me know if you have more feedback to improve this answer. – Jimmy Aug 01 '18 at 09:18