问题
Is there a way or an extension that does the following:
Having a *.sln
file, can I list all files from all projects or all solution folders under that sln?
So if I do dotnet sln list
then I get the list of the projects from that solution file, but what I need is to get all files.
My real need is to copy all those files into a different folder.
回答1:
Here's an msbuild-based solution which is actually fairly simple and also non-intrusive. Create a file CopySource.targets in the solution directory for instance, contents:
<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>
Then run a build like
dotnet msbuild mysolution.sln /p:CustomAfterMicrosoftCSharpTargets=/path/to/CopySource.targets
(note dotnet build
also works for me but might not in older versions, don't know)
This will import ListSources.Targets in each project file and run the CopySourcesUsed target after compilation. Before compilation somewhere will also work, but then you have to figure out exactly when: after compilation all items definitely have been gathered. As an example the AllSources item is filled with the compilation source files and the embedded resources. As you can see the Compile item is filtered to exclude the generated AssemblyAttributes/AssemblyInfo files since you probably don't want those. An alternative might be to have this target ran before those files are added, but again: that's just trickier. There can be other things you want to copy (xaml/config/...) in which case you have to figure out the name of the item to include. First check if it's not simply listed in the csproj. Else running the build with diagnostic verbosity can tell you the name: dotnet msbuild mysolution.sln /v:diag
.
Instead of injecting this logic on the commandline you could instead import the file in each project you have, or use another extension point like making it system-wide by putting it in some ImportAfter directory, all these solutions can be found here on SO probably.
回答2:
Not sure if this might help, but I belive Microsoft.Build.Evaluation might help you here. There is another post about what I think is your problem:
csproj how to get all resources
I dont know with what kind of projects you are working with, I would assume csproj. But maybe this helps even if thats not the case. You should be able to modify the given example so that you get all the files you need.
Side note: It would probably helop to have a little more information about what kind of projects we are talking about, how many and if there are excluded files etc.
来源:https://stackoverflow.com/questions/53002852/having-a-sln-file-possible-to-list-all-files-from-all-projects-under-that-sln