Due to issues with merging etc, we have lots of project files that don’t contain all source code files that are within their folders.
Before I write a little tool, that
In my search for a solution for this, I ran into this VS Extension, but it only works with VS 2012. It's also on Github.
For VS 2013+ I use a Powershell script found on this blog post. Note that it only works for C# projects, but you can modify it for VB projects.
#Author: Tomasz Subik http://tsubik.com
#Date: 8/04/2012 7:35:55 PM
#Script: FindProjectMissingFiles
#Description: Looking for missing references to files in project config file
Param(
[parameter(Mandatory=$false)]
[alias("d")]
$Directory,
[parameter(Mandatory=$false)]
[alias("s")]
$SolutionFile
)
Function LookForProjectFile([System.IO.DirectoryInfo] $dir){
[System.IO.FileInfo] $projectFile = $dir.GetFiles() | Where { $_.FullName.EndsWith(".csproj") } | Select -First 1
if ($projectFile){
$projectXmlDoc = [xml][system.io.file]::ReadAllText($projectFile.FullName)
#[xml]$projectXmlDoc = Get-Content $projectFile.FullName
$currentProjectPath = $projectFile.DirectoryName+"\"
Write-Host "----Project found: " $projectFile.Name
$nm = New-Object -TypeName System.Xml.XmlNamespaceManager -ArgumentList $projectXmlDoc.NameTable
$nm.AddNamespace('x', 'http://schemas.microsoft.com/developer/msbuild/2003')
[System.Collections.ArrayList]$filesListedInProjectFile = $projectXmlDoc.SelectNodes('/x:Project/x:ItemGroup/*[self::x:Compile or self::x:Content or self::x:None]/@Include', $nm) | Select-Object Value
CheckProjectIntegrity $dir $currentProjectPath $filesListedInProjectFile;
}
else { $dir.GetDirectories() | ForEach-Object { LookForProjectFile($_); } }
}
Function CheckProjectIntegrity([System.IO.DirectoryInfo] $dir,[string] $currentProjectPath, [System.Collections.ArrayList] $filesListedInProjectFile ){
$relativeDir = $dir.FullName -replace [regex]::Escape($currentProjectPath)
$relativeDir = $relativeDir +"\"
#check if folder is bin obj or something
if ($relativeDir -match '(bin\\|obj\\).*') { return }
$dir.GetFiles() | ForEach-Object {
$relativeProjectFile = $_.FullName -replace [regex]::Escape($currentProjectPath)
$match = $false
if(DoWeHaveToLookUpForThisFile($relativeProjectFile))
{
$idx = 0
foreach($file in $filesListedInProjectFile)
{
if($relativeProjectFile.ToLower().Trim() -eq $file.Value.ToLower().Trim()){
$match = $true
break
}
$idx++
}
if (-not($match))
{
Write-Host "Missing file reference: " $relativeProjectFile -ForegroundColor Red
}
else
{
$filesListedInProjectFile.RemoveAt($idx)
}
}
}
#lookup in sub directories
$dir.GetDirectories() | ForEach-Object { CheckProjectIntegrity $_ $currentProjectPath $filesListedInProjectFile }
}
Function DoWeHaveToLookUpForThisFile($filename)
{
#check file extensions
if ($filename -match '^.*\.(user|csproj|aps|pch|vspscc|vssscc|ncb|suo|tlb|tlh|bak|log|lib|sdf)$') { return $false }
return $true
}
Write-Host '######## Checking for missing references to files started ##############'
if($SolutionFile){
[System.IO.FileInfo] $file = [System.IO.FileInfo] $SolutionFile
$Directory = $file.Directory
}
LookForProjectFile($Directory)
Write-Host '######## Checking for missing references to files ends ##############'
Example usage (should be run from the NuGet console):
./FindProjectMissingFiles.ps1 -s $dte.Solution.FileName