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.71k stars 1.06k forks source link

VS2017 RC - The target “GetCopyToPublishDirectoryItems” does not exist in the project. #543

Closed srivatsn closed 7 years ago

srivatsn commented 7 years ago

From @Delie on November 18, 2016 23:17

After installing Visual Studio 2017 RC, and upgrading my ASP.NET Core Web Application (.NET Framework) project to CSPROJ, I am no longer able to publish my project to the file system. Building the solution works fine, but when I publish I get this error:

The target "GetCopyToPublishDirectoryItems" does not exist in the project.

To replicate:

  1. Create a new ASP.NET Core Project (.NET Framework), and solution.
  2. Add a new Class Library project (.NET Framework) to the solution.
  3. Reference the Class Library project in the .NET Core project.
  4. Instantiate a class from the Class Library project in the .NET Core project
  5. Rebuild solution.
  6. Publish the .NET Core project and it throws the error.

Copied from original issue: aspnet/Tooling#869

srivatsn commented 7 years ago

From @discostu105 on November 23, 2016 19:52

I have exactly the same problem.

btw, "GetCopyToPublishDirectoryItems" is defined over there: https://github.com/dotnet/sdk/blob/master/src/Tasks/Microsoft.NET.Build.Tasks/build/Microsoft.NET.Publish.targets

Maybe @eerhardt knows something about that? Is there a workaround? I'm trying to port my project to .csproj, but this blocks me.

srivatsn commented 7 years ago

From @duracellko on December 2, 2016 10:21

I tried workaround to add empty target to referenced class library project:

It helped a bit, but then I encountered another error. It is mentioned in known issues. https://github.com/aspnet/Tooling/blob/master/known-issues-vs2017.md "Unable to publish"

I tried to find a workaround by overriding some targets. After few hours I gave up and I converted project to standard .NET Framework Console Application.

  1. Delete old project (make a backup of course).
  2. Create new project using template Classic Windows - Console applications.
  3. Add same NuGet packages as in old project.
  4. Add all *.cs files from old project.
  5. Add references to class library project.
  6. Open WebApp.csproj in text editor.
  7. Add following element at the end of file.
  <Target Name="AfterBuild">
    <Copy SourceFiles="$(SolutionDir)\packages\Libuv.1.9.1\runtimes\win7-x64\native\libuv.dll" DestinationFolder="$(TargetDir)" />
  </Target>
  1. Add following element into App.config
<runtime>
 <gcServer enabled="true" />
</runtime>
  1. Add Web.config from old project.
  2. In Web.config change attribute aspNetCore/processPath to name of console application executable (WebApp.exe) and change arguments to empty string.

If you use different configuration in development environment, I added command line argument for debug project -AspNetCore:Environment=Development, then in Program.Main method I transformed this command line arguments to environment variable ASPNETCORE_ENVIRONMENT.

If you use User Secrets, then add into .csproj file element <UserSecretsId>YourSecretId</UserSecretsId>. Then you have to add secrets.json file to you AppData profile. No support from Visual Studio in this.

srivatsn commented 7 years ago

From @duracellko on December 2, 2016 11:2

And I forgot to set Copy to Output Directory for files web.config and appsettings.json.

My project is just WebAPI, so no .cshtml file. So it's easy.

srivatsn commented 7 years ago

From @hybridview on December 20, 2016 16:33

This issue doesn't appear to have gotten any attention yet. Does anymore know why it happens? I'm trying to find a workaround without having to hack up my project file.

srivatsn commented 7 years ago

From @jsgoupil on December 20, 2016 16:55

@hybridview Rolling back to WebAPI2 was the best solution I have done so far.

srivatsn commented 7 years ago

From @eerhardt on December 20, 2016 21:39

Sorry, I've been on vacation and haven't been checking email or GitHub. I just saw this now.

The problem is that one project uses the new Microsoft.NET.Sdk project system and the referenced class library project doesn't use the same project system.

As a workaround, I can think of the following options:

  1. Convert the class library project to use the new Microsoft.NET.Sdk project system.
  2. Add a "fake/mock" empty target to your class library project named "GetCopyToPublishDirectoryItems". This is mostly a hack, but it should get by the error mentioned above. You may run into other issues once you get by this error.

@srivatsn - Is it a supported scenario to mix and match these different project systems across P2P references?

/cc @nguerrera @dsplaisted @davkean

srivatsn commented 7 years ago

From @davkean on December 20, 2016 21:47

Yes this is supported. Either we dummy out GetCopyToPublishDirectoryItems or sniff that the target doesn't exist (not sure this is even possible)?

srivatsn commented 7 years ago

Yes referencing an existing project from a new one is supported.

srivatsn commented 7 years ago

From @coonmoo on December 20, 2016 22:32

I have the same problem with Service Fabric, Asp.Net Core and VS 2017 RC2.

To replicate:

  1. Create a new Service Fabric project
  2. Select ASP.NET Core Web
  3. Add a new Class Library project (.NET Framework) to the solution.
  4. Reference the Class Library project in the .NET Core project.
  5. Instantiate a class from the Class Library project in the .NET Core project
  6. Rebuild solution.
  7. Publish the Service Fabric project

I'd love to see a fix for this, because VS 2017 is awesome.

Register-ServiceFabricApplicationType : The BuildLayout of the application in 
4>C:\SfDevCluster\Data\ImageBuilderProxy\AppType\SfApplication1Type is invalid. Code is missing for service Web1Pkg.
4>At C:\Program Files\Microsoft SDKs\Service 
4>Fabric\Tools\PSModule\ServiceFabricSDK\Publish-NewServiceFabricApplication.ps1:244 char:9
4>+         Register-ServiceFabricApplicationType -ApplicationPathInImage ...
4>+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4>    + CategoryInfo          : InvalidOperation: (Microsoft.Servi...usterConnection:ClusterConnection) [Register-Servic 
4>   eFabricApplicationType], FabricException
4>    + FullyQualifiedErrorId : RegisterApplicationTypeErrorId,Microsoft.ServiceFabric.Powershell.RegisterApplicationTyp 
4>   e
4> 
4>Finished executing script 'Deploy-FabricApplication.ps1'.
4>Time elapsed: 00:00:12.3127633
4>The PowerShell script failed to execute.
srivatsn commented 7 years ago

From @dsplaisted on December 21, 2016 1:27

@srivatsn We should move this issue to the dotnet/sdk repo. I don't think we currently have tests that cover building an SDK project which references a non-SDK project, much less publishing in this scenario.

srivatsn commented 7 years ago

From @EuroForm on December 21, 2016 10:43

Having same problem. Would also love to see a fix to this 😅🙏🔥

NickNiebling commented 7 years ago

I've got this problem in a .NET Framework 4.6.2 MVC project using "older class libraries" when using VS2017 RC. The website builds and run locally without any problems, but I'm unable to publish the website.

It's difficult for me to know exactly what makes the "older class libraries" work or not, since all my internal project references are having this issue in the solution.

Thanks for accepting the issue and looking into it 👍 Looking very much forward to a solution asap 😊

jxlarrea commented 7 years ago

What's the status on this issue?

I am unable to publish my ASP.NET Core MVC application due to this. The workaround posted by @srivatsn does eliminate the "GetCopyToPublishDirectoryItems" error message but the web application fails at runtime, complaining about missing references "Can not find reference assembly '.NETFramework/v4.6.2/Microsoft.CSharp.dll' file for package microsoft.csharp". I'm sure this is caused by the lack of "refs" folder.

ghost commented 7 years ago

I have this issue too - can't publish, and now that the Web API project has been converted to .csproj, VS2015 can't load the project, so I can't go back to an older version of VS to publish it either. I'd rather not rollback the code changes I made since the upgrade... any workarounds would be appreciated also.

JeanRessouche commented 7 years ago

Really looking for a fix too, make VS2017 RC2 quite unusable for several kind of projects ! Not easy for .net core projects to get back to VS 2015 when the 2017 is so much better :)

cceuroform commented 7 years ago

I have this issue too. I found a "partial" solution. I added the following to every referenced assembly < Target Name="GetCopyToPublishDirectoryItems" >< / Target >

This made the problem go away, and the publish process continues much longer. BUT now i have a different error

Error MSB3094: "DestinationFiles" refers to 1 item(s), and "SourceFiles" refers to 2 item(s). They must have the same number of items.
C:\Users\cc.nuget\packages\microsoft.net.sdk\1.0.0-alpha-20161104-2\build\Microsoft.NET.Publish.targets 126

cceuroform commented 7 years ago

I installed Build 26020.00, but still same issue

drewid commented 7 years ago

This is a really critical issue and should be really basic. Just have a dotnetcore web project that is including a class library. As people have said, building and running locally works fine, but publishing up to Azure gives the failure messages already mentioned. This "really" sucks as spent a lot of time moving to VS 2017 and things have been pretty decent up until this bug bit me in the ass - at "build" time of all things. Really frustrating as got everything else to work and build.

agarwal-peeush commented 7 years ago

Really looking for a fix too. I experience the same issue and unable to publish after upgrade.

davkean commented 7 years ago

We haven't forgotten about this issue, and we're aware of the pain. We're trying to figure out the best approach to take for this.

nguerrera commented 7 years ago

For starters, here is a more complete workaround using a default target that makes non Microsoft.NET.Sdk-based projects respect the default publish semantics.

Add the following to a new or existing Directory.Build.targets somewhere that is above all of the projects in the solution (e.g.. repository root directory). MSBuild will then pick up the targets for any project underneath that directory:

<Project>
 <!--
  Work around https://github.com/dotnet/sdk/issues/543 with a default implementation of  
  GetCopyToPublishDirectoryItems that simply returns whatever GetCopyToOutputDirectoryItems 
  does with CopyToPublishDirectory implied by CopyToOutputDirectory, which is the same as
  Microsoft.NET.Sdk default when CopyToPublishDirectory is not used. Microsoft.NET.Sdk projects 
  will override this to allow the publish output to be customized independently from the build output.
  -->
  <Target
      Name="GetCopyToPublishDirectoryItems" 
      DependsOnTargets="GetCopyToOutputDirectoryItems"
      Returns="@(AllPublishItemsFullPathWithTargetPath)">

    <ItemGroup>
      <AllPublishItemsFullPathWithTargetPath Include="@(AllItemsFullPathWithTargetPath)">
        <CopyToPublishDirectory>%(CopyToOutputDirectory)</CopyToPublishDirectory>
      </AllPublishItemsFullPathWithTargetPath>
    </ItemGroup>
  </Target>
</Project>
nguerrera commented 7 years ago

Error MSB3094: "DestinationFiles" refers to 1 item(s), and "SourceFiles" refers to 2 item(s). They must have the same number of items.

@cceuroform That looks like a separate issue that was fixed by https://github.com/dotnet/sdk/pull/581

nguerrera commented 7 years ago

@cceuroform Can you do msbuild /t:publish /flp:v=diag and post the resulting msbuild.log to a gist. I want to verify that it is #581 and then we can talk about the right workaround while waiting for #581 to be fixed in VS.

drewid commented 7 years ago

@nguerrera you're totally speaking greek to me. I just want to be able to do a basic publish to and Azure Website and not sure how specific and granular the publishing controls are to Azure.

gulbanana commented 7 years ago

The idea is that if you create the Directory.Build.targets file @nguerrera describes in your source code, then it will be used during the publish process, potentially restoring your ability to publish to Azure.

cceuroform commented 7 years ago

@nguerrera The file is huge. 116 MBytes. How can I share it with you?

nguerrera commented 7 years ago

@cceuroform Can you locate where the Error MSB3094 occurs and post from that line back up to the closest occurrence of Target "<Name>" in project "<path>"?

cceuroform commented 7 years ago

@nguerrera msbuild.log I found a smaller project

cceuroform commented 7 years ago

@nguerrera Did you verify it is #581?. Any workaround?

nguerrera commented 7 years ago

Pasting the relevant part here for others to see easily:

Target "_CopyResolvedFilesToPublishAlways: (TargetId:105)" in file "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Publish.targets"
<snip>
Task "Copy" (TaskId:109)
  Task Parameter:
      SourceFiles=
          C:\Users\cc\.nuget\packages\system.io\4.1.0\ref\net462\System.IO.dll
                  CopyLocal=false
                  CopyToPublishDirectory=Always
                  FusionName=System.IO, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
                  ImageRuntime=v4.0.30319
                  NuGetIsFrameworkReference=false
                  NuGetSourceType=Package
                  OriginalItemSpec=C:\Users\cc\.nuget\packages\system.io\4.1.0\ref\net462\System.IO.dll
                  Private=false
                  ReferenceSourceTarget=ResolveAssemblyReference
                  RelativePath=refs\System.IO.dll
                  ResolvedFrom={RawFileName}
                  Version=4.1.0.0
          C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.IO.dll
                  CopyLocal=false
                  CopyToPublishDirectory=Always
                  RelativePath=refs\System.IO.dll
                  ResolvedFrom=ImplicitlyExpandDesignTimeFacades
                  WinMDFile=false (TaskId:109)
  Task Parameter:DestinationFiles=bin\Debug\net462\win7-x86\publish\refs\System.IO.dll (TaskId:109)
  Task Parameter:OverwriteReadOnlyFiles=False (TaskId:109)

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Publish.targets(128,5): error MSB3094: "DestinationFiles" refers to 1 item(s), and "SourceFiles" refers to 2 item(s). They must have the same number of items. [C:\Users\cc\Documents\Visual Studio 2017\Projects\WebApplication12\src\WebApplication12\WebApplication12.csproj]

cc @eerhardt @dsplaisted : This actually looks a little different -- there's a conflict with ImplicitlyExpandDesignTimeFacades and a package providing a newer System.IO facade.

Applying the two-line change from https://github.com/dotnet/sdk/pull/581/files#diff-ffd1a974928a37a20fbc471c040962ac (fix from #581) to C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Publish.targets might get it past this point, but it might also hide the root cause and deploy the older ref, which might cause Razor some problems.

@dsplaisted I think you mentioned looking at conflicts with implicit facades somewhere. Thoughts on this?

cceuroform commented 7 years ago

@nguerrera I will try to apply the two-line change from #581

cceuroform commented 7 years ago

@nguerrera After apply the change from #581, the previous error disapeared. :) But now I got the following error:

C:\Data\EF\Repo\Projects\EF.Definition\EF.Definition.csproj : error MSB4057: The target "GetCopyToPublishDirectoryItems" does not exist in the project.

msbuild.log(2)

Here is the csproj file EF.Definition.csproj

I was able to fix that to after inserting < Target Name="GetCopyToPublishDirectoryItems" / > into the csproj file (at the very end).

Now I was able to build a deploy for that little toy-app.

After that I inserted the same line to all our projects (~450 csprojects), and I am now able to deploy out app to IIS on a Azure VM. :)

We still need to do some testing, but for now it seems to work for our part at least.

ankgupta067 commented 7 years ago

@nguerrera i tried adding the changes you suggested by creating build.targets in the root folder i seem to get no success with this issue,

I am accessing a portable class library in .net core app(CrossPlatformWebApp).

solution can be accessed at https://drive.google.com/file/d/0B6UT1ay0CMA5S281VEhLSzZHUnM/view

i am getting below error when i try to publish to file system -

2017\Projects\CrossPlatformDevelopment\CrossPlatformWebApp\bin\Debug\netcoreapp1.0\CrossPlatformWebApp.dll C:\Users\310182638\documents\visual studio 2017\Projects\CrossPlatformDevelopment\ClassLibrary1\PortableClasslibrary.csproj(0,0): Error MSB4057: The target "GetCopyToPublishDirectoryItems" does not exist in the project.

cceuroform commented 7 years ago

@ankgupta067 Try to add < Target Name="GetCopyToPublishDirectoryItems" / > in every csproj file that fails with the error. That was helping in my case.

nguerrera commented 7 years ago

@ankgupta067 You named the file "build.targets", but it needs to be named "Directory.build.targets" to be picked up by msbuild. Try that.

@cceuroform That would get past the error, but can also cause required files to be missing from the publish directory. The target should match https://github.com/dotnet/sdk/issues/543#issuecomment-271656546. You could put that in every project, but using Directory.build.targets makes it easier to apply to all projects and also easier to revert once the real fix lands.

ankgupta067 commented 7 years ago

@nguerrera works perfectly thanks

srivatsn commented 7 years ago

The fix for this has been checked into MSBuild - https://github.com/Microsoft/msbuild/pull/1544

ConX-Ryan commented 7 years ago

Thanks for working on the problem ... seems there is a clear solution now, how does the public get there hands on an update?