4

I need to delete files (mostly .cs and .cshtml) that have been removed from solution in Visual Studio 2010 but have not been deleted from filesystem. I know that these files are shown if I choose Show all files option, however, I don't want to search for them manually because it will take much time and it's error-prone.

Is there any way to list these files? I'm using Visual Studio 2010 and Resharper 6.1 (maybe Resharper has some option that can do this).

empi
  • 15,755
  • 8
  • 62
  • 78
  • Doesn't it tack on a .exclude extension to files that are excluded but not deleted? – jim31415 Mar 21 '12 at 15:49
  • These files are not included in csproj files. What do you mean by .exclude extension? – empi Mar 21 '12 at 15:59
  • Sorry, it seems to be ASP.NET project functionality only. – jim31415 Mar 21 '12 at 17:07
  • Check here http://stackoverflow.com/questions/2000197/visual-studio-macro-find-files-that-arent-included-in-the-project – jim31415 Mar 21 '12 at 17:14
  • 2
    possible duplicate of [Remove unused cs-files in solution](http://stackoverflow.com/questions/8800977/remove-unused-cs-files-in-solution) – bummi Jan 15 '15 at 07:48

1 Answers1

4

I wrote a PowerShell script based on @jovball's answer. The primary difference is mine will accept a .sln file and delete all files excluded from all projects within that solution.

Here is the version of the script at the time of posting this answer. But please check here for the most recent version.

<#
.SYNOPSIS
Find all files excluded from a Visual Studio solution with options to delete.

.DESCRIPTION
Finds all excluded files in all projects in the provided Visual Studio solution with options to delete the files.

.PARAMETER Solution
The path to the .sln file

.PARAMETER VsVersion
The Visual Studio version (10, 11, 12) (Used to locate the tf.exe file)

.PARAMETER DeleteFromTfs
Mark files as pending deletion in TFS

.PARAMETER DeleteFromDisk
Delete the files directly from the disk

#>

[CmdletBinding()]
param(
    [Parameter(Position=0, Mandatory=$true)]
    [string]$Solution,
    [Parameter(Mandatory=$false)]
    [ValidateRange(10,12)] 
    [int] $VsVersion = 12,  
    [switch]$DeleteFromDisk,
    [switch]$DeleteFromTfs
)
$ErrorActionPreference = "Stop"
$tfPath = "${env:ProgramFiles(X86)}\Microsoft Visual Studio $VsVersion.0\Common7\IDE\TF.exe"
$solutionDir = Split-Path $Solution | % { (Resolve-Path $_).Path }

$projects = Select-String -Path $Solution -Pattern 'Project.*"(?<file>.*\.csproj)".*' `
    | % { $_.Matches[0].Groups[1].Value } `
    | % { Join-Path $solutionDir $_ }

$excluded = $projects | % {
    $projectDir = Split-Path $_

    $projectFiles = Select-String -Path $_ -Pattern '<(Compile|None|Content|EmbeddedResource) Include="(.*)".*' `
        | % { $_.Matches[0].Groups[2].Value } `
        | % { Join-Path $projectDir $_ }

    $diskFiles = Get-ChildItem -Path $projectDir -Recurse `
        | ? { !$_.PSIsContainer } `
        | % { $_.FullName } `
        | ? { $_ -notmatch "\\obj\\|\\bin\\|\\logs\\|\.user|\.*proj|App_Configuration\\|App_Data\\" }

    (compare-object $diskFiles $projectFiles -PassThru) | Where { $_.SideIndicator -eq '<=' }
} 

Write-Host "Found" $excluded.count "excluded files"

if ($DeleteFromTfs) 
{
    Write-Host "Marking excluded files as deleted in TFS..."
    $excluded | % {
        [Array]$arguments = @("delete", "`"$_`"")
        & "$tfPath" $arguments
    }
} 
elseif($DeleteFromDisk)
{
    Write-Host "Deleting excluded files from disk..."
    $excluded | % { Remove-Item -Path $_ -Force -Verbose}
}
else 
{
    Write-Host "Neither DeleteFromTfs or DeleteFromDisk was specified. Listing excluded files only..."
    $excluded
}
mikesigs
  • 10,491
  • 3
  • 33
  • 40
  • I see your point, but as the content of the script IS my answer, it seems like the link is appropriate. I'll post the current version of the script here, but it could get out of date if I make changes to it (highly likely) and forget to update my answer. I will do my utmost to ensure the link stays put though. – mikesigs Jan 16 '15 at 04:43