仅将SPECIFIC nuget包的.xml文件包含在其他文件夹中 [英] Include ONLY .xml file of SPECIFIC nuget package in a different folder

查看:100
本文介绍了仅将SPECIFIC nuget包的.xml文件包含在其他文件夹中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在一个解决方案中有一个项目(ProjectAbc),该项目引用了一个nuget包(这是我们与其他解决方案不同的项目[ProjectXyz]).我们使用.net核心框架和程序包引用在.csproj文件中包含nuget程序包(ProjectXyz).

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

在本地或Prod中构建解决方案时,将在以下位置生成ProjectXyz.dll和ProjectXyz.xml

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

我们希望Only ProjectXyz nuget包的Only ProjectXyz.xml直接在以下文件夹中生成

ProjectAbc

我发现了许多文章,这些文章指导我做不同的事情,例如在构建或使用相对路径后将文件复制到输出目录.尽管尝试了不同的方法,但我不断遇到各种错误.可能是因为我不知道.csproj文件中的语法,也可能是因为我不确定自己在做什么.

在上述情况下复制文件或直接在所需文件夹中生成文件的最佳方法是什么?



对于我的评论回复:

由于我无法将屏幕截图粘贴到@Perry Qian-MSFT的评论中.所以将其粘贴到这里.

8/20/2020 -----程序包屏幕截图---------------------------

解决方案

您可以在nuget项目 ProjectXyz 中使用<package_name>.props文件将此类文件复制到 ProjectAbc 的项目文件夹中.您应该使用< package_id> .props .

1)首先,在您的 ProjectXyz 项目中,创建一个名为build的文件夹,然后在您的身边添加一个名为<package_id>.props的文件. ProjectXyz.props.

2)将它们添加到ProjectXyz.props文件中:

<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)卸载您的 ProjectXyz 项目并将其添加到ProjectXyz.csproj文件中:

 <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),然后应打包新的 ProjectXyz 项目.

5)然后,完成打包,您应该首先尝试使用nuget.exe cli进行打包您的项目,您只需要一个自定义nuspec文件:

首先,下载 nuget.exe cli ,然后配置其本地 PATH 系统环境变量的路径.然后,您可以在CMD中调用nuget.

第二,打开 CMD cd xxx(project folder path),运行nuget spec生成nuspec文件,然后修改生成的nuspec文件:

<?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>

第三,运行nuget pack打包此项目.

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

更新3

请首先清理您的nuget缓存,或仅删除C:\Users\xxx(current user)\.nuget\packages下的所有nuget缓存.然后重新安装您的nuget软件包.

,请确保xxx.props名称与您的裸名package_id相同.

如果您的nuget软件包调用ProjectXyz(package_id).然后,道具文件应命名为ProjectXyz.props.

此外,您应该在Tools-> Options-> Projects and Solutions-> Build and Run下将msbuild project build output verbosity设置为detailed. >

然后,重建您的 ProjectAbc ,以检查目标是否执行.

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

更新4

您应该确保打包软件包project.mnop时,请确保project.mnop.props文件没有语法错误.

例如,我在props文件中错误地写了asdczxcx之类的内容,但是,由于props文件的 build action ContentNone,因此Vs不会自动分析其错误,并且不会显示错误.

并且该错误与您的错误相同.

因此,您应该删除该非法字符.确保project.mnop.props没有语法错误.然后重新打包您的项目.

之后,首先卸载 ProjectAbc 上的旧nuget软件包project.mnop.

然后,删除C:\Users\xxx(current user)\.nuget\packages下的缓存project.mnop文件夹.

最后,删除 ProjectAbc binobj文件夹,安装新版本project.mnop,然后重建项目 ProjectAbc .

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

更新5

实际上,这应该是一种更简单的方法.而您的灵感可以通过更简洁的Nuget包结构来实现.

您应该只更改此内容:

1)更改为使用ProjectXyz.props中的 lib 文件夹中的ProjectXyz.xml:

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

2)将您的xxx.nuspec文件更改为:

<?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),然后打包您的项目,然后您可以得到想要的东西.

注意:SourceScripts使用路径$(MSBuildThisFileDirectory).

$(MSBuildThisFileDirectory)表示nuget软件包的ProjectXyz.props文件所在的完整路径.

在您的身边,$(MSBuildThisFileDirectory)表示

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

然后使用此路径在nuget软件包的 lib 文件夹中找到ProjectXyz.xml的文件地址.

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.

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

解决方案

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.

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.

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

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.

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:

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:

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.

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

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.

And the error shows the same as yours.

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.

这篇关于仅将SPECIFIC nuget包的.xml文件包含在其他文件夹中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆