问题描述
我们在一个解决方案中有一个项目(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)然后,完成打包,您应该先clean all nuget caches。
然后,在您的 ProjectAbc 项目中,应卸载旧的项目,然后安装新的 ProjectXyz nuget程序包。
之后,您应该首先构建ProjectAbc项目,然后您会看到nuget包中的xml文档位于 ProjectAbc 的项目文件夹下。
================================================ ====================
更新1
ProjectXyz 项目是net core
或net standard
,而 ProjectAbc 是net core
。
首先,为了帮助您理解该问题,我尝试将ProjectXyz.xml
文件打包到ProjectXyz.nupkg
中的其他文件夹中。
1)首先,更改为使用ProjectXyz.csproj
文件中的这些xml内容:
<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>
目标是将ProjectXyz.xml
文件打包到XmlFolder
中名为XmlFolder.nupkg
的文件夹中。并将ProjectXyz.xml
文件保存在Nuget包中。
确保该文件存在于nuget包中。
如果文件不存在,我认为它是由您的git控制的。或者,您可以将此ProjectXyz.xml
放入项目文件夹中。
尝试右键单击您的项目-> 属性-> 构建->选中此选项:
只需使用<Content Include="ProjectXyz.xml" Pack="true" PackagePath="XmlFolder">
在我们这方面,可以将文件复制到nupkg nuget包中,因此您应确保其他工具(如 git )不会与之连接。
2),然后更改为在ProjectXyz.props
文件中使用它们:
<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>
它的目标是,当您安装此nuget软件包时,它将首先运行该目标,以将ProjectXyz.xml
文件从nuget软件包复制到主项目 ProjectAbc 。
注意:
完成nuget软件包的安装后,首先构建 ProjectAbc 项目,该文件将存在于 ProjectAbc 项目文件夹中。
3)然后右键单击 ProjectXyz -> 属性-> 打包以打包项目
在安装新的 ProjectXyz 时,您应首先删除
下的所有文件 C:\Users\xxx(current user)\.nuget\packages
。
此外,我还有一个问题是,正在引用ProjectXyz 在多个项目中,例如ProjectAbc,Project123。我们不要 ProjectXyz.xml文件显示在Project123中,但仅显示在ProjectAbc中。一世 使用上述解决方案进行猜测,可能会在两个引用中均显示 项目。
为此,您只需要在CopyFilesToProject目标中添加如下条件:$(ProjectXyz_Flag)==true
,然后创建属性ProjectXyz_Flag
并将其值设置为true
中的ProjectAbc.csproj
文件。
构建 ProjectAbc 项目时,它将根据您当前设置的switch变量确定是否复制文件。
a)在$(ProjectXyz_Flag)
文件中添加名为ProjectXyz.props
的条件:
然后重新打包您的 ProjectXyz 项目,并按照我之前所说的做几个干净的步骤。
当您将该软件包安装到 ProjectAbc 项目中时,应在ProjectAbc.csproj
文件中添加此类属性:
<PropertyGroup>
<ProjectXyz_Flag>true</ProjectXyz_Flag>
</PropertyGroup>
然后,当您构建ProjectAbc项目时,它将执行复制目标,并且如果您未定义该属性,它将不会在 ProjectAbc 中复制该文件。>
并且,如果这些项目不需要ProjectXyz.xml
文件,则只需在这些项目中不定义该switch属性。
================================================ =====
更新2
try to use nuget.exe cli to pack your project,您只需要一个自定义nuspec文件:
首先,下载nuget.exe cli,然后将其本地路径配置到 PATH 系统环境变量中。然后,您可以在CMD中调用nuget。
第二,打开 CMD 和cd xxx(project folder path)
,运行nuget spec
生成nuspec
文件,然后修改生成的{{ 1}}文件:
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>
打包此项目。
================================================ ===============
更新3
请首先清理您的nuget缓存,或仅删除nuget pack
下的所有nuget缓存。然后重新安装您的nuget软件包。
也,请确保C:\Users\xxx(current user)\.nuget\packages
的名称与您的主体xxx.props
相同。
如果您的nuget软件包调用package_id
(package_id)。然后,道具文件应命名为ProjectXyz
。
此外,您应该在ProjectXyz.props
-> msbuild project build output verbosity
-> detailed
-下将Tools
设置为Options
> Projects and Solutions
。
然后,重建您的 ProjectAbc ,以检查目标是否执行。
================================================ =======
更新4
您应该确保在打包Build and Run
包时,请确保project.mnop
文件没有语法错误。
例如,我在props文件中错误地写了project.mnop.props
之类的东西,因为props文件的 build action 是asdczxcx
或{{1 }},Vs将不会自动分析其错误,也不会显示错误。
并且该错误与您的错误相同。
因此,您应该删除该非法字符。确保Content
没有语法错误。然后重新打包您的项目。
之后,请先在 ProjectAbc 上卸载旧的nuget软件包None
。
然后,删除project.mnop.props
下的缓存project.mnop
文件夹。
最后,删除 ProjectAbc 的project.mnop
和C:\Users\xxx(current user)\.nuget\packages
文件夹,安装新版本bin
,然后重建项目 ProjectAbc 。
=========================================== >
更新5
实际上,这应该是一种更简单的方法。而您的灵感可以通过更简洁的Nuget包结构来实现。
您应该只更改此内容:
1)更改为使用obj
中 lib 文件夹中的project.mnop
:
ProjectXyz.xml
2)将您的ProjectXyz.props
文件更改为:
<SourceScripts Include="$(MSBuildThisFileDirectory)..\..\lib\netcoreapp3.1\ProjectXyz.xml"/>
</ItemGroup>
<Copy
SourceFiles="@(SourceScripts)"
DestinationFiles="@(SourceScripts -> '$(MSBuildProjectDirectory)\%(RecursiveDir)%(Filename)%(Extension)')"
/>
3),然后打包您的项目,然后您可以得到想要的东西。
注意: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>
。
SourceScripts
表示nuget软件包的$(MSBuildThisFileDirectory)
文件所在的完整路径。
在您的身边,$(MSBuildThisFileDirectory)
表示
ProjectXyz.props
然后使用此路径在nuget软件包的 lib 文件夹中找到$(MSBuildThisFileDirectory)
的文件地址。