0

I apologize if this is trivial, but I'm not a regular VS user and my Google-Fu is turning up nothing obvious or simple.

I have inherited responsibility for a large (500k+ LOC, a dozen solutions, hundreds of projects) repository that's been forked a number of times in the past. The solution/project structure is... spaghetti-esque, in that the filesystem folder structure and the solution/project structure are only weakly correlated, and many projects import/reference other projects outside the filesystem folder hierarchy of their containing solution, and that are not even part of the containing solution.

For example:

c:\SolutionA\SolutionA.sln contains c:\SolutionA\ProjectB.csproj and c:\SolutionA\ProjectC.csproj. But C:\solution\ProjectC.csproj contains a <Import Project="..\SomeOtherRandomSolutionDir\ProjectD.csproj" /> reference.

I know there are a lot of projects/files/resources in this repo that are not used by any of the solutions I'm actually building and I don't need them, but the tentacular nature of the project imports/references makes it hard to determine what's actually necessary for the builds and what's superfluous.

So: is there any relatively simple way to run a solution build in Visual Studio (or MSBuild) and obtain a list of every single file used by the build process? I've tried creating a diagnostic-level build log and grepping[1] it for the repo base path; will that get me what I want? (Narrator: it won't)

EDIT: Assume that all file operations are done entirely by default Visual Studio solution project handling and there's no custom targets or shelling out to copy or move files, in the way Perry Qian describes below

[1] Well, Get-Content | Select-String-ing it, but that's clunkier to say

Chris Doherty
  • 525
  • 1
  • 4
  • 12

1 Answers1

1

is there any relatively simple way to run a solution build in Visual Studio (or MSBuild) and obtain a list of every single file used by the build process? I've tried creating a diagnostic-level build log and grepping[1] it for the repo base path; will that get me what I want?

Sorry but I'm afraid this is not supported scenario. You cannot obtain a list of every single files that are used in a project or a solution during build process.

Let me explain it more detailed:

Usually the files which are in the solution explorer are all useful in the project. Since your solution is too large and logically complex, we do not recommend deleting any of the files, and I think they all work.

We can obtain a list of files which are parts of the input items of the projects by MSBuild(usually in <Itemgroup> node of the xxx.csproj file).This is the only way I can think of to get a set of project files through MSBuild. We can add this target into xxx.csproj to list all of them like this:

<Target Name="ShowSingleProjectItemList" AfterTargets="Build">

<Message Importance="high" Text="None file:@(None)---Compile files:@(Compile)---Content files:@(Content)---Embedded Resource files:@(EmbeddedResource)---CodeAnalysisDictionary files:@(CodeAnalysisDictionary)---ApplicationDefinition files:@(ApplicationDefinition)---Page files:@(Page)---Resource files:@(Resource)---SplashScreen files:@(SplashScreen)---DesignData files: @(DesignData) Reference dlls :@(Reference)"> 

</Target>

Note that this method can only be used for each project and not for the entire solution so if you want to use, add it into every xxx.csproj file.

But for other files which are not as the input items of the projects and added or referenced in the projects by some CMD commands or powershell scripts, build events(Right-click on Project-->Properties-->Build Events)(You can refer to this) and any other custom target in the xxx.csproj,we cannot list all of them by a function.

For example, if you use powershell to do some copy operation like coping some dlls from the path outside of your solution into projects,they can't stay in the project as an item of the project. So we cannot obtain them by MSBuild.

For this situation, we can only manually view all of them that are imported into the projects in whatever way in the diagnostic-level build log.

Conclusion

As input items of the projects, we can get the required files for each project by MSBuild, but for some other operations(powershell,build events,etc) to add files from other path outside into the current project,we cannot retrieve all of their information by a method. You can only look it up one by one by diagnostible-level build log.

Besides,we don't know the structure and logic of the entire solution, so we can't guarantee that every file is an item element, so for now you have to look at it manually.

Update 1

To avoid adding every target into your xxx.csproj(since you have a lot of projects under a solution), you can try to use Directory.Build.props. You just write the custom target into this file and then put the file under your solution. After that, when you build the solution, the build will execute into every project so that you just have to write it once.

Solution

1) create a file namedDirectory.Build.props under the solution

2) write these info into the file

 <Target Name="ShowSingleProjectItemList" AfterTargets="Build">

    <Message Importance="high" Text="None file:@(None)---Compile files:@(Compile)---Content files:@(Content)---Embedded Resource files:@(EmbeddedResource)---CodeAnalysisDictionary files:@(CodeAnalysisDictionary)---ApplicationDefinition files:@(ApplicationDefinition)---Page files:@(Page)---Resource files:@(Resource)---SplashScreen files:@(SplashScreen)---DesignData files: @(DesignData) Reference dlls :@(Reference)"> 

    </Target>

3) build your solution and you will find the files in the build output window.

Mr Qian
  • 21,064
  • 1
  • 31
  • 41
  • As far as I can tell, we're not doing any out of band stuff like powershell file manipulation, so this may get me a signficant portion of the way towards my goal. Thanks! – Chris Doherty Dec 18 '19 at 16:22
  • This looks like it'll get me as close as is possible to my goal. Thanks, Perry! – Chris Doherty Dec 21 '19 at 18:06