12

Is there a way for Visual Studio to report an error/warning when you build a solution that has missing files (yellow triangle icon with exclamation) that do have necessarily cause a compile error? Like a missing config file that is read during run-time.

Thanks

JKJKJK
  • 850
  • 1
  • 11
  • 18
  • 1
    I would also like an answer to this question. I'm finding it infuriating that a file can be missing and yet the build compiles successfully, along with view compilation. Surely, at the very least, there should at least be a setting in Visual Studio or the project that I can set to enforce this. – Dan Atkinson Sep 09 '11 at 16:29

4 Answers4

11

You need to define an EnvironmentEvents macro. See the general description on how to do this here: Customize Your Project Build Process.

And here is the code you can directly paste in the macro environment to check missing files:

Private Sub BuildEvents_OnBuildBegin(ByVal Scope As EnvDTE.vsBuildScope, ByVal Action As EnvDTE.vsBuildAction) Handles BuildEvents.OnBuildBegin
    For Each proj As Project In DTE.Solution.Projects
        For Each item As ProjectItem In proj.ProjectItems
            If (item.Kind <> "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}") Then ' only check physical file items
                Continue For
            End If

            For i As Integer = 1 To item.FileCount
                Dim path As String = item.FileNames(i)
                If Not System.IO.File.Exists(item.FileNames(i)) Then
                    WriteToBuildWindow("!! Missing file:" & item.FileNames(i) + " in project " + proj.Name)
                End If
            Next
        Next
    Next
End Sub

Public Sub WriteToBuildWindow(ByVal text As String)
    Dim ow As OutputWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput).Object
    Dim build As OutputWindowPane = ow.OutputWindowPanes.Item("Build")
    build.OutputString(text & Environment.NewLine)
End Sub

It will display the "missing file" text directly in the Visual Studio "Build" output window. It should be fairly easy to understand and tune to your needs. For example, you could add errors to the error output.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • 2
    Visual Studio 2012 / 2013 no longer supports macros, see http://stackoverflow.com/questions/20689829/report-error-warning-if-missing-files-in-project-solution-in-visual-studio-2012/20711912#20711912 for an updated solution – Turch Dec 20 '13 at 21:07
  • Thanks for the VS 2012 and up redirect! – granadaCoder Aug 01 '14 at 14:05
3

When we had missing files, we were getting crazy compile errors, like unable to write xyz.pdb even though the file ended up getting written. I took what Simon had provided (thanks!) and flipped it around a bit; specifically, I added a bit of recursion and added support for folders and files with sub-files (e.g. datasets, code-behinds).

Private Sub BuildEvents_OnBuildBegin(ByVal Scope As EnvDTE.vsBuildScope, ByVal Action As EnvDTE.vsBuildAction) Handles BuildEvents.OnBuildBegin

    For Each proj As Project In DTE.Solution.Projects
        walkTree(proj.ProjectItems, False)
    Next

End Sub

Private Sub walkTree(ByVal list As ProjectItems, ByVal showAll As Boolean)

    For Each item As ProjectItem In list

        ' from http://msdn.microsoft.com/en-us/library/z4bcch80(v=vs.80).aspx
        ' physical files:   {6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}
        ' physical folders: {6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}

        If (item.Kind = "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}" OrElse _
            item.Kind = "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}") Then

            For i As Integer = 1 To item.FileCount ' appears to be 1 all the time...

                Dim existsOrIsFolder As Boolean = (item.Kind = "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}" OrElse System.IO.File.Exists(item.FileNames(i)))

                If (showAll OrElse _
                    existsOrIsFolder = False) Then

                    WriteToBuildWindow(String.Format("{0}, {1}, {2} ", existsOrIsFolder, item.ContainingProject.Name, item.FileNames(i)))

                End If

            Next

            If (item.ProjectItems.Count > 0) Then
                walkTree(item.ProjectItems, showAll)
            End If

        End If

    Next

End Sub

Private Sub WriteToBuildWindow(ByVal text As String)
    Dim ow As OutputWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput).Object
    Dim build As OutputWindowPane = ow.OutputWindowPanes.Item("Build")
    build.OutputString(text & Environment.NewLine)
End Sub
Andy S.
  • 79
  • 1
  • 4
2

In case anyone else stumbles across this thread, there's a plugin that will give you a build error when you have files missing from your project.

Alec
  • 2,432
  • 2
  • 18
  • 28
0

If you happen to have a linux-like environment with access to the project folder (for instance, if you use git for version control, you can probably use the included Git Bash for this, or if you use Cygwin), here's my really quick and dirty way:

grep '<Content Include="' "project_file.csproj" | sed 's/^.*"\([^"]*\)".*/\1/' | sed 's/\\/\//g' | xargs -d'\n' ls > /dev/null

(How this works: I try to ls every file named in the project, and send the stdout output of the ls command to /dev/null, so it will be hidden. If any files do not exist, ls will barf their names to stderr rather than stdout, so those will be visible.)

Note that this doesn't understand URL-encoded escapes, so you will get a few false positives if your project contains filenames with characters like '(' in them.

Felix
  • 433
  • 4
  • 8