【问题标题】:Having a sln file, possible to list all files from all projects under that sln?有一个 sln 文件,可以列出该 sln 下所有项目的所有文件吗?
【发布时间】:2019-03-30 20:49:13
【问题描述】:

有没有办法或扩展来做以下事情:

有一个*.sln 文件,我可以列出该 sln 下所有项目或所有解决方案文件夹中的所有文件吗?

因此,如果我执行dotnet sln list,那么我会从该解决方案文件中获取项目列表,但我需要的是获取所有文件。

我真正的需要是将所有这些文件复制到不同的文件夹中。

【问题讨论】:

  • 使用 Microsoft.Build.Evaluation 之类的程序集,您可以加载项目文件并从中获取源文件(假设这是您想要的,您只需指定“文件”?)。或者,如果您不使用通配符来选择文件,那么将项目文件解析为文本是相当容易的。
  • 有些是用通配符指定的。有些被排除在外。我需要所有文件、源代码、资源,任何东西都包含在 csproj 中。我会探索那个 api。
  • 运气好吗?实际上,考虑一下:可能您甚至不需要直接使用 api,但是您可以从命令行使用 msbuild.exe 并通过编写一个执行此操作的小目标来指示它将所有文件转储到文本文件左右然后将该目标导入到您的项目文件中,并使用 ImportAfter 之类的扩展点。没有时间在自动取款机上写答案,但我很确定这样可以解决问题。
  • 还没查。也是。 net core,所以格式有点不同。可能dotnet build 实现有答案。
  • 在此处查看程序化解决方案:stackoverflow.com/questions/53070977/…

标签: .net build msbuild .net-core dotnet-cli


【解决方案1】:

不确定这是否会有所帮助,但我相信 Microsoft.Build.Evaluation 可能会对您有所帮助。关于我认为是您的问题的另一篇文章:

csproj how to get all resources

我不知道你正在处理什么样的项目,我会假设 csproj。但也许这会有所帮助,即使情况并非如此。您应该能够修改给定的示例,以便获得所需的所有文件。

旁注:了解更多关于我们正在讨论的项目类型、数量以及是否有排除文件等信息可能会有所帮助。

【讨论】:

  • csproj。在一个文件夹中,我可以有两个解决方案,每个解决方案都有自己的 csprojs 列表。当 Visual Studio 构建一个 sln 时,它知道要查看哪些 csprojs,要编译哪些文件,或者将哪些文件放入输出文件夹(即复制到输出)或嵌入哪些文件 dll。我想要实现的是制作包含该 sln 的文件的干净副本(通过 csprojs 和/或解决方案文件夹)。
  • 目前我们有一个解析sln的powershell脚本,创建一个csprojs列表,然后复制相应的文件夹。但不是很好维护。
【解决方案2】:

这是一个基于 msbuild 的解决方案,它实际上相当简单且非侵入性。 在解决方案目录下创建一个文件 CopySource.targets 例如,内容:

<Project>
  <Target Name="CopySourcesUsed" AfterTargets="AfterCompile">
    <PropertyGroup>
      <DestinationDirectory>c:\temp\dest\</DestinationDirectory>
      <SourceDirectory>$([System.IO.Path]::GetDirectoryName($(MSBuildProjectDirectory)))</SourceDirectory>
    </PropertyGroup>
    <ItemGroup>
      <CompileSources Condition="!$([System.Text.RegularExpressions.Regex]::IsMatch('%(Identity)', `.*Assembly(Attributes|Info)\.cs`))" Include="@(Compile)"/>
      <AllSources Include="@(CompileSources);@(EmbeddedResource);$(MSBuildProjectFile)" />
      <AllSources>
        <Dest>$([System.String]::new('%(FullPath)').Replace($(SourceDirectory), $(DestinationDirectory)))</Dest>
      </AllSources>
    </ItemGroup>
    <Message Importance="High" Text="%(AllSources.FullPath) -> %(AllSources.Dest)"/>
    <Copy SourceFiles="@(AllSources)" DestinationFiles="@(AllSources->'%(Dest)')" />
  </Target>
</Project>

然后像这样运行构建

dotnet msbuild mysolution.sln /p:CustomAfterMicrosoftCSharpTargets=/path/to/CopySource.targets

(注意dotnet build 也适用于我,但可能不适用于旧版本,不知道)

这将在每个项目文件中导入 ListSources.Targets 并在编译后运行 CopySourcesUsed 目标。在某个地方编译之前也可以工作,但是你必须弄清楚什么时候:编译之后所有的项目肯定都已经收集好了。例如,AllSources 项填充了编译源文件和嵌入的资源。如您所见,编译项被过滤以排除生成的 AssemblyAttributes/AssemblyInfo 文件,因为您可能不想要这些文件。另一种方法可能是在添加这些文件之前运行此目标,但同样:这更棘手。可能还有其他要复制的内容(xaml/config/...),在这种情况下,您必须确定要包含的项目的名称。首先检查它是否没有简单地列在 csproj 中。否则,以诊断详细程度运行构建可以告诉您名称:dotnet msbuild mysolution.sln /v:diag

您可以在您拥有的每个项目中导入文件,而不是在命令行中注入此逻辑,或者使用另一个扩展点,例如通过将其放在某个 ImportAfter 目录中使其成为系统范围,所有这些解决方案都可以在此处找到大概是这样。

【讨论】:

  • 我意识到我没有正确表达这个问题。是的,这确实将所有文件复制到目标文件夹,但它不会保留相同的项目结构,它不会复制 csproj 文件,也不会复制 sln 文件本身。复制操作的结果应该是build-able(即 dotnet build dest/target.sln 应该像 dotnet build src/target.sln 一样工作)
  • 保留结构是添加一些路径操作的问题(可能只是用 dst 替换 src)并且复制 csproj/sln 并不难添加。但是考虑到您的实际要求:列出整个 src 目录并指定诸如 bin/obj 目录之类的排除项,然后复制它不是更简单吗?或者例如如果您的项目在源代码管理中,请使用它来获取要从中复制的文件?此外,您可能应该重新表述您的问题以陈述实际问题,而不是一种可能的方式,并可能提供一些有关您的目录结构的信息。
  • 虽然这不是一个完整的解决方案,但我会将其标记为已回答。如果我有时间写一个完整的解决方案,我会自己发布一个答案。
  • 如果你愿意,我可以修改代码以保留目录结构等?
  • 好的,见编辑。复制 .sln 不存在,因为为每次调用(即每个项目)复制它是没有意义的,而且如果您要构建单个项目,甚至没有解决方案文件。我只是将它添加到一个批处理文件中,它也运行构建。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多