1

We have a project (ProjectAbc) in a solution which is referencing a nuget package (which is our different project [ProjectXyz] from other solution). We use .net core framework and package reference to include nuget package (ProjectXyz) in .csproj file.

<PackageReference Include="ProjectXyz" Version="1.1.2.3" />

When the solution is build locally or in Prod, ProjectXyz.dll and ProjectXyz.xml gets generated in

ProjectAbc/bin/debug(locally) or release(inProd)/netcoreapp3.1

We want Only ProjectXyz.xml of Only ProjectXyz nuget package to get generated in following folder directly

ProjectAbc

I found various articles which directed me to do different things like copying file to output directory after building or using relative path. Though, tried different ways, I keep getting various errors. It may be because I am not aware of the syntax in .csproj file or also may be because I am not sure what I am doing.

What would be best way to copy file in above case or to generate file directly in the required folder?



for my comment response:

Since I am unable to paste the screenshot in my comment for @Perry Qian-MSFT. So pasting it here.

enter image description here

enter image description here

8/20/2020-----package screenshot---------------------------

enter image description here

Vicky
  • 624
  • 2
  • 12
  • 35
  • Who generates that file? Or is it in the NuGet package? – CodeCaster Aug 10 '20 at 22:52
  • @CodeCaster I assume you are asking about ProjectXyz.xml in above context. Yes, nuget package generates that file as the xml documentation is enabled in the ProjectXyz. – Vicky Aug 10 '20 at 23:18
  • Actually, to copy the xml document of the nuget into the main project, it is controlled by `ProjectXyz`. I suggest you could add these in `ProjectXyz.csproj` file: ` true` – Mr Qian Aug 11 '20 at 02:05
  • When you finish it, pack `ProjectXyz` project again. Then [clean all nuget caches](https://learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders#clearing-local-folders) and reinstall the new nuget `ProjectXyz` in `ProjectAbc` to test again. Please let us know if it works and then we could provide better support. – Mr Qian Aug 11 '20 at 02:07
  • Thanks @PerryQian-MSFT for suggestion. I will implement this and let you know if it is working or not. But, can you please explain what this is doing? We already have XML documentation file enabled in build configuration of .csproj file. So why do we need – Vicky Aug 11 '20 at 03:27
  • @PerryQian-MSFT I just tried above, doing exactly what you said. And it is not working. The file is not getting generated in the expected folder as needed. – Vicky Aug 11 '20 at 04:31
  • Did you want to make `ProjectXyz.xml` copied into the project folder of ProjectAbc when you install the pacakge? – Mr Qian Aug 11 '20 at 06:53
  • @Vicky,any update about this issue? If my answer helps you handle the issue, please do not forget to mark it. If not, please feel free to let us know. – Mr Qian Aug 13 '20 at 01:50
  • Sure I am going to test it today and let you know accordingly. – Vicky Aug 13 '20 at 12:15
  • @Vicky, we will wait for your any response and provide any support for you if necessary:) – Mr Qian Aug 14 '20 at 02:02
  • @Vicky, any progress about this issue? – Mr Qian Aug 19 '20 at 01:40
  • @PerryQian-MSFT Sorry. I will test the update 2 in a day/two and let you know. I am currently travelling with not much access to internet. Sorry for the inconvenience and thanks a lot for your help. I will update or reply asap. – Vicky Aug 19 '20 at 04:06
  • Thanks for your help. The abnormal behavior which the `ProjectXyz.xml `file does not exist in the nupkg by the pack command is not controlled by nuget. I think it is related to your project itself or something constrains the XML Document. So I suggest you could additionally create a new net core library project and then migrate old content into the new one to test whether the issue exists. Also, before you pack the project, try to delete `.vs` hidden folder, `bin` and `obj` folder. – Mr Qian Aug 20 '20 at 02:10
  • @Vicky, any progress about your issue? If my answer helps you handle the issue, please do not forget to `mark it`. – Mr Qian Aug 26 '20 at 10:03

1 Answers1

4

You could use <package_name>.props file in nuget project ProjectXyz to copy such file into the project folder of ProjectAbc. You should use <package_id>.props.

1) First, in your ProjectXyz project, create a folder called build and then add a file called <package_id>.props, in your side, it is called ProjectXyz.props.

enter image description here

2) Add these in ProjectXyz.props file:

<Project>
  <Target Name="CopyFilesToProject" BeforeTargets="Build">
    <Message Text="Copying ProjectXyz.xml to project" />
    <ItemGroup>
      <SourceScripts Include="$(MSBuildThisFileDirectory)..\..\content\any\any\**\*.*"/> //file from the ProjectXyz nuget package
    </ItemGroup>
    <Copy
       SourceFiles="@(SourceScripts)"
       DestinationFiles="@(SourceScripts -> '$(MSBuildProjectDirectory)\%(RecursiveDir)%(Filename)%(Extension)')"     //copy into the main ProjectAbc project folder
         />
  </Target>
  
</Project>

3) Unload your ProjectXyz project and add these in ProjectXyz.csproj file:

 <ItemGroup>
    <Content Include="bin\Debug\xxx\ProjectXyz.xml(the path of the ProjectXyz.xml)" Pack="true" 
    PackagePath="content\any\any;contentFiles\any\any\;;"> 
    <PackageCopyToOutput>true</PackageCopyToOutput>
    </Content>

    <None Include="build\ProjectXyz.props" Pack="true" PackagePath="build\$(TargetFramework)"/>
  </ItemGroup>

4) Then you should pack your new ProjectXyz project.

5) Then you finish packing, you should first clean all nuget caches first.

Then in your ProjectAbc project, you should uninstall the old one and then install the new ProjectXyz nuget package.

After that, you should build ProjectAbc project first and then you will see that xml document from the nuget package is under the project folder of ProjectAbc.

enter image description here

====================================================================

Update 1

ProjectXyz project is net core or net standard while ProjectAbc is net core.

First, to help you understand the issue, instead, I try to pack ProjectXyz.xml file into other folder in the ProjectXyz.nupkg.

1) First, change to use these xml content in ProjectXyz.csproj file:

<ItemGroup>
    <Content Include="bin\Debug\netcoreapp3.1\ProjectXyz.xml" Pack="true" PackagePath="XmlFolder">
      <PackageCopyToOutput>true</PackageCopyToOutput>
    </Content>

    <None Include="build\ProjectXyz.props" Pack="true" PackagePath="build\$(TargetFramework)"/>
  </ItemGroup>

The goal of it is to pack ProjectXyz.xml file into the folder called XmlFolder of XmlFolder.nupkg. And save ProjectXyz.xml file in the Nuget package.

enter image description here

Make sure that the file exists in the nuget package.

If the file does not exist, I think it is controlled by your git. Or you could put this ProjectXyz.xml in your project folder.

Try to right-click on your project-->Properties-->Build-->check this:

enter image description here

Just use <Content Include="ProjectXyz.xml" Pack="true" PackagePath="XmlFolder">

In our side, the file can be copied into nupkg nuget package so you should make sure that other tools like git will not interface it.

2) Then change to use these in ProjectXyz.props file:

<Project>
  <Target Name="CopyFilesToProject" BeforeTargets="Build">
    <Message Text="Copying ProjectXyz.xml to project" />
    <ItemGroup>

    //ProjectXyz.xml file from the ProjectXyz nuget package
      <SourceScripts Include="$(MSBuildThisFileDirectory)..\..\XmlFolder\**\*.*"/>
    </ItemGroup>

   //copy ProjectXyz.xml file into the main ProjectAbc project folder
    <Copy
       SourceFiles="@(SourceScripts)"
       DestinationFiles="@(SourceScripts -> '$(MSBuildProjectDirectory)\%(RecursiveDir)%(Filename)%(Extension)')"    
         />
  </Target>
  
</Project>

The goal of it is that when you install this nuget package, it will first run this target to copy the ProjectXyz.xml file from the nuget package into the main project ProjectAbc.

Note:

When you finishing installing nuget package, first build ProjectAbc project and the file will exists in ProjectAbc project folder.

3) Then right-click ProjectXyz-->Properties-->Pack to pack your project.

When you install the new ProjectXyz, you should first delete all files under

C:\Users\xxx(current user)\.nuget\packages.

Also, one more question I had is, the ProjectXyz is being referenced in multiple projects like ProjectAbc, Project123. We dont want ProjectXyz.xml file to show up in Project123 but only in ProjectAbc. I guess with above solution, it might show in both of referencing projects.

For this, you only need to add a condition in CopyFilesToProject target like this: $(ProjectXyz_Flag)==true and then create a property ProjectXyz_Flag and set its value to true in ProjectAbc.csproj file.

When you build ProjectAbc project, it will determine whether to copy the file based on the switch variable you are currently setting.

a) Add a condition called $(ProjectXyz_Flag) in ProjectXyz.props file:

enter image description here

Then repack your ProjectXyz project and do several clean steps as I said before.

When you install that package in ProjectAbc project, you should add such such property in ProjectAbc.csproj file:

<PropertyGroup>
    <ProjectXyz_Flag>true</ProjectXyz_Flag>
</PropertyGroup>

Then when you build ProjectAbc project, it will execute the copy target and if you do not define that property, it will not copy that file in ProjectAbc.

And if those projects do not need ProjectXyz.xml file, you just do not define that switch property in those projects.

====================================================

Update 2

try to use nuget.exe cli to pack your project, you just need a custom nuspec file:

First, download nuget.exe cli and then configure its local path into PATH System Environment Variable. Then, you can call nuget in CMD.

Second, open CMD and cd xxx(project folder path), run nuget spec to generate the nuspec file and then modify the generated nuspec file:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
    <!-- ... -->
    </metadata>
    <files>
       
        <file src="xxx\ProjectXyz.xml" target="XmlFolder" />

        
        <file src="build\ProjectXyz.props" target="build\netcoreapp3.1" />
    </files>
</package>

Third, run nuget pack to pack this project.

==============================================================

Update 3

Please first clean your nuget caches or just delete all nuget caches under C:\Users\xxx(current user)\.nuget\packages. Then reinstall your nuget package.

Also, make sure that the xxx.props name is the same as your nuget package_id.

If your nuget package calls ProjectXyz(package_id). Then the props file should be named as ProjectXyz.props.

Besides, you should set msbuild project build output verbosity to detailed under Tools-->Options-->Projects and Solutions-->Build and Run.

Then, rebuild your ProjectAbc to check whether the target executes.

enter image description here

======================================================

Update 4

You should make sure that when you pack your package project.mnop, make sure that the project.mnop.props file has no syntax errors.

For an example, I have incorrectly wrote something like asdczxcx in the props file, however, since the build action of the props file is Content or None, Vs will not automatically analyze its errors and will not show the errors.

enter image description here

And the error shows the same as yours.

enter image description here

So you should delete that Illegal characters. Make sure that project.mnop.props has no syntax errors. Then repack your project.

After that, first uninstall the old nuget package project.mnop on the ProjectAbc.

Then, delete the cache project.mnop folder under C:\Users\xxx(current user)\.nuget\packages.

Finally, delete bin and obj folder of ProjectAbc, install the new version project.mnop, then rebuild your project ProjectAbc.

=============================================

Update 5

Actually, this should be an easier way. And your inspiration can be done with a more concise Nuget package structure.

You should only change this:

1) change to use ProjectXyz.xml from the lib folder in your ProjectXyz.props:

<SourceScripts Include="$(MSBuildThisFileDirectory)..\..\lib\netcoreapp3.1\ProjectXyz.xml"/>
    </ItemGroup>
    <Copy
       SourceFiles="@(SourceScripts)"
       DestinationFiles="@(SourceScripts -> '$(MSBuildProjectDirectory)\%(RecursiveDir)%(Filename)%(Extension)')"    
         />
  

2) change your xxx.nuspec file to:

<?xml version="1.0"?>
<package >
  <metadata>
    ........
    <copyright>Copyright 2020</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>

<files>

<file src="build\ProjectXyz.props" target="build\netcoreapp3.1" />
</files>
</package>

3) then pack your project and then you can get what you want.

Note: SourceScripts uses the path $(MSBuildThisFileDirectory).

$(MSBuildThisFileDirectory) means the full path where the ProjectXyz.props file of the nuget package exists.

In your side, the $(MSBuildThisFileDirectory) means

C:\Users\xxxxx\.nuget\packages\project.mnop\45.0.0\build\netcoreapp3.1

And then use this path to find the file address of ProjectXyz.xml in the lib folder of the nuget package.

Mr Qian
  • 21,064
  • 1
  • 31
  • 41
  • 1st of all, thanks a lot. The file is not generating as needed. And the reason, I think is after step 1, 2 and 3, In ProjectXyz, I see ProjectXyz.xml is included but being ignored (may b bcoz of .gitignore thing). I have pasted the snapshot for the same in above question since I am unable to paste it here. Also, one more question I had is, the ProjectXyz is being referenced in multiple projects like ProjectAbc, Project123. We dont want ProjectXyz.xml file to show up in Project123 but only in ProjectAbc. I guess with above solution, it might show in both of referencing projects. – Vicky Aug 14 '20 at 03:23
  • I have also peeked in to nuget package of ProjectXyz that got generated to see what is the structure of the folder and pasted the screenshot for the same in above question. The structure of contentFiles and content seems odd. Did these get generated because of step 2 & 3 code. I somewhat understood step 3 as it is packing the files in the content/contentFiles in to the package. Also including the .xml file and ignoring build folder. Can you explain what step 2 does? Correct me if I am wrong. Thanking in advance. – Vicky Aug 14 '20 at 03:41
  • For my step 2, the goal of it is that when you install your nuget package, it will first run this target first to copy the `ProjectXyz.xml` file from the nuget package into the main project `ProjectAbc`. – Mr Qian Aug 14 '20 at 05:55
  • I think packing `ProjectXyz.xml` file into `Contentfiles` for `content `folders can be confusing to you. So I will update my answer to add some more detailed info. – Mr Qian Aug 14 '20 at 05:57
  • @Vicky, I have updated my answer and you can check it. – Mr Qian Aug 14 '20 at 06:40
  • thank you for detailed explanation. I followed the step 2 and see the ProjectXyz.xml file generated in projectXyz. And based on your suggestion, updated below include path as well. Though, I see, XmlFolder being generated in the nuget package, **I don't see ProjectXyz.xml** in it. I have below in .cs project, true – Vicky Aug 14 '20 at 15:32
  • Actually, it is quite strange and it did not happen in my side. Did your project controlled by other tools so that the file cannot be imported into nupkg. You could first run VS as administrator and then test it. If you use `git`, I think you should first disconnect the url and then delete `.git` folder to test again. – Mr Qian Aug 17 '20 at 08:39
  • Or delete `bin` and `obj` folder and then click `pack` button. Besides, you could try to create a new net core class library project and try my solutions in this new project to test whether the behavior happens again. – Mr Qian Aug 17 '20 at 08:42
  • Hi Ricky, any update about this issue? [Use nuget.exe cli to pack your project](https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package), does this work? I also update my answer and you can check `update 2`. – Mr Qian Aug 18 '20 at 07:29
  • Good news is that files are getting generated in the package and I am able to see them. I have added the screenshot in the above Question section. But, bad thing is that props is not working as the ProjectXyz.xml is not getting generated in ProjectAbc. I tried with above given props and also tried updating this line with different path for xml folder in props. It did not work. – Vicky Aug 20 '20 at 20:19
  • Please first clean your nuget caches or just delete all nuget caches under `C:\Users\xxx(current user)\.nuget\packages`. Then reinstall your nuget package. Also, make sure that the `xxx.props` name is the same as your nuget `package_id` and then it will work due to the nuget rule. – Mr Qian Aug 21 '20 at 02:38
  • Besides, please set `msbuild project build output verbosity` to `detailed` under `Tools`-->`Options`-->`Projects and Solutions`-->`Build and Run`. Then rebuild your project to search whether the target `CopyFilesToProject` executes. See my `update 3`. – Mr Qian Aug 21 '20 at 02:42
  • you were correct. Package_id Project.Mnop was not matching with ProjectXyz.props. Updated it to be same. And now, I am seeing below error while trying to built, Project C:\Users\xxxxx\.nuget\packages\project.mnop\45.0.0\build\netcoreapp3.1\Project.Mnop.props" was not imported by "C:\ProjectAbc\ProjectAbc\obj\ProjectAbc.csproj.nuget.g.props" at (16,5), due to the file being invalid. – Vicky Aug 21 '20 at 04:07
  • Also, opened path (C:\ProjectAbc\ProjectAbc\obj\) to look at the file, saw this as of the xml tag/node, – Vicky Aug 21 '20 at 04:10
  • Thanks @Perry Qian-MSFT for all the help. – Vicky Aug 21 '20 at 04:24
  • I think you have some syntax errors in the props file, please see `update 4`. You should make sure that when you pack your package `project.mnop`, make sure that the `project.mnop.props` file has no syntax errors. When you finish it, first uninstall this nuget package, then delete nuget caches like `project.mnop` nuget package under `C:\Users\xxx(current user)\.nuget\packages`. After that, install this new package to test it. See my `update 4`. – Mr Qian Aug 21 '20 at 05:51
  • Yay it worked! it was basically copy paste thing bcoz of the comment in that file. After removing, it is worked as expected. – Vicky Aug 21 '20 at 16:43
  • Now, just need one customization for our project, In the .nuspec file of solution ProjectXyz we have something like below, This is basically used to generate nuget package. When I opened nuget package, I see a file ProjectXyz.xml file in folder lib\netcoreapp3.1. Can we use this file directly instead of putting in to XmlFolder separately? And if yes, I am confused with folder location like what the sourcescripts location path in the props file should be? – Vicky Aug 21 '20 at 16:44
  • Thanks for your suggestion. It is quite a good idea. And you should not create such document in your ProjectXyz project. I have tested my new solution in `Update 5`. And you should not pack the file in the `XmlFolder` and uses the file in the `lib` folder directly. Quite simple. You can check `Update 5`. – Mr Qian Aug 24 '20 at 06:18
  • And if my answer helps you handle the issue, please do not forget to `mark it`. :) – Mr Qian Aug 24 '20 at 06:18
  • yup. everything worked well in the local. Thank you!. But, as we pushed the code to the sandbox, we are seeing below error:C:\Users\ContainerAdministrator\.nuget\packages\project.mnop\1.xxx\build\netcoreapp3.1\project.mnop.props(7,5): error MSB3030: Could not copy the file "C:\Users\ContainerAdministrator\.nuget\packages\project.mnop\1.xxx\build\netcoreapp3.1\..\..\lib\netcoreapp3.1\project.mnop.xml" because it was not found. Any idea about this? (may be this might be the last hurdle :)) – Vicky Aug 26 '20 at 22:53
  • Did you check the full path and make sure that the `project.mnop.xml` is under path? it is quite strange that the file should not be empty. Also, make sure that you have access to that folder. How did you build that project, delete `bin` and `obj` folder, `clean nuget caches` can solve the issue? Please check on the path and if you build with command line, you should add `msbuild -t:restore`.We will wait for your any response:) – Mr Qian Aug 27 '20 at 02:05
  • @Vicky,since the issue is about sandbox rather than the local path. I suggest you could mark this answer and make a new ticket about your new issue with more detailed description of sandbox. And it will help us give you better support. – Mr Qian Aug 27 '20 at 02:06
  • Thanks for all the help. as suggested, I have a raised a new question, any idea about this? https://stackoverflow.com/questions/63747258/nuget-restore-is-ignoring-xml-files-but-downloading-only-dll-and-pdb-files – Vicky Sep 04 '20 at 19:53
  • since we are facing this issue (https://stackoverflow.com/questions/63747258/nuget-restore-is-ignoring-xml-files-but-downloading-only-dll-and-pdb-files?noredirect=1#comment112825175_63747258) on the server, is there a way we can add a condition in above update 5, step 1 to copy the file only if it exists so that it does not throw error on server if it does not exist there. – Vicky Sep 09 '20 at 15:24
  • not sure but if something like this is correct or is there a better way. – Vicky Sep 09 '20 at 15:43