How to find .CS files in a project folder that are no longer in the project?

As our projects evolved over the years, many .cs files were deleted from projects, renamed, etc., but they remain in the original management. Therefore, when you use the latest code, you get all of these .cs files that no longer reference any .csproj file.

Does anyone know a simple and reliable mechanism to detect these files and eliminate them?

+4
source share
6 answers

It is best to use a scripting language for this task. I find powershell well suited for such situations.

Step 1 - find all the actual .cs files that were included in your csproj files. The following function will search the directory structure for all csproj files and return the set of .cs files that are included in these files.

function Get-IncludedCsFiles() { param ( $rootPath = $(throw "Need a path") ) $projFiles = gci -re -in *.csproj $rootPath foreach ( $file in $projFiles ) { $dir = split-path $file.FullName foreach ( $line in (gc $file) ) { if ( $line -match 'Compile\s+Include="([^"]+)"' ) { join-path $dir $matches[1] } } } } 

Now all you have to do is wrap this in a dictionary, and then search the directory structure

 $map = @{} $pathToSearch = "Path\To\Search" Get-IncludedCsFiles $pathToSearch | %{ if(!$map.Contains($_)) { $map.Add($_, $true) } } $notIncluded = gci -re -in *.cs $path | ?{ -not $map.Contains($_.FullName) } 
+5
source

Try Show All Files in VS Solution Explorer.

+4
source

At the moment, I don’t have VS on hand, but is there a “Show files not in project” option in Solution Explorer?

+1
source

I did a small project for this some time ago. Available here .

+1
source

Thanks to JaredPar for the solution! Because of this, it was much easier for me :) A slightly powerful version of what you provided.

 function Get-IncludedCsFiles() { param ( $rootPath = $(throw "Need a path") ) $projFiles = gci -re -in *.csproj $rootPath foreach ( $file in $projFiles ) { $dir = split-path $file.FullName foreach ( $line in (gc $file) ) { $correctedLine = $line -replace '%28', '(' #some files have "(" in them, and csproj changes them for %28 $correctedLine = $correctedLine -replace '%29', ')' if ($correctedLine -match 'Compile\s+Include="([^"]+)"') { $filepath = join-path $dir $matches[1] [System.IO.Path]::GetFullPath($filePath)#this resolves path (removes \..\) } } } } $tempFilePattern = '*\obj\*' $map = @{} $pathToSearch = "Path to search" $resultFilePath = [io.path]::combine($pathToSearch, 'notIncluded.txt') Get-IncludedCsFiles $pathToSearch | %{ if(!$map.Contains($_)) { $map.Add($_, $true) } } echo "Map created" $notIncluded = gci -re -in *.cs $path | ?{ (-not $map.Contains($_.FullName)) -and !($_ -like $tempFilePattern)} | %{$_.FullName} $notIncluded | Out-File $resultFilePath $notIncluded | %{ #tf delete $_ #Remove from TFS } 

Files with brackets by name, files that are not in the same folder with csproj (or a subfolder under it) are also taken into account. Also, it does not include temporarily generated files created using compilation (/ obj / folder). It lists all the paths in the output file, and you can even remove them from TFS.

+1
source

One way to avoid this problem is procedural: (works for any project other than the Web site project, which does not have a project file):

Instead of doing the “get the latest” from your source control tool, always do the “open source control” inside Visual Studio and do the latest updates from Solution Explorer. VS will pull only files belonging to the project.

This is not an ideal answer - when you merge, you will probably end up pulling every file down in your branch, but it worked very well for us.

(of course, this requires that you use a version control tool that offers VS integration, it also requires that you add some non-compiled but necessary files (icons, etc.) to the project, or they will not to be carried down VS).

0
source

All Articles