A macro to find missing files in Visual Studio Solutions
- Written by Boris Drajer
- Published in Development Environment
Or: how to solve the setup project message “ERROR: An error occurred while validating. HRESULT = '80004005'” It seems that for a large part of features in Visual Studio .Net, the development stops at the point where they are mostly usable and effectively demo-able. The Microsoft people are very eager to show you how easy it is to solve a trivial problem with a couple of clicks, but they are very reserved once something really serious has to be done. A case in point: the Setup/Deployment projects in Visual Studio. (Yeah, the ones, Zero Click Deployment - they make it sound like it reads your thoughts - and the like). If you have a missing file in your solution, and if the file is of a non-critical type (e.g. a resource) so that the solution compiles, you have a big problem because the setup won’t. It will fail with a moronic message “ERROR: An error occurred while validating. HRESULT = '80004005'”. Which file is missing? Well, if you really really care – go through all files in your projects and check (don’t forget to expand the controls, some RESX child file may be the culprit!) Another thing that can happen is that a reference in one of the projects is bad. For example, you had the project reference another project and you moved the other project out of the solution… The first project doesn’t use anything from it so that the build passes but the setup is not as forgiving. In this case, you need to check all references. If, like me, you have a solution that consists of thirty project and thousands of files, this would mean a major headache. One way to solve it would be to create a new, temporary setup project and add to it one by one all outputs from the original setup. Build after each step and when the error appears you’ll know which project is at fault. Now, if the first is the case (a missing source file), one possible solution is to automate the manual search by using a macro. Below you’ll find one, modified from the example on the excellent MZ Tools site. As for the missing reference, it is somewhat easier to find since there are considerably less references in a solution than project files (you can detect these using the one-by-one method described above). I’m leaving it to you as a TODO: improve this script to detect missing references, post it on your blog and let me know so I can add a link to it.
Option Strict Off
Option Explicit Off
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.Windows.Forms
Public Module Module2
Sub FindMissingFiles()
Dim objProject As EnvDTE.Project
Try
If Not DTE.Solution.IsOpen Then
MessageBox.Show("Please load or create a solution")
Else
For Each objProject In DTE.Solution.Projects
NavigateProject(objProject)
Next
End If
Catch objException As System.Exception
MessageBox.Show(objException.ToString)
End Try
End Sub
Private Sub NavigateProject(ByVal objProject As Project)
Dim objParentProjectItem As ProjectItem
Try
objParentProjectItem = objProject.ParentProjectItem
Catch
End Try
NavigateProjectItems(objProject.ProjectItems)
End Sub
Private Sub NavigateProjectItems(ByVal colProjectItems As ProjectItems)
Dim objProjectItem As EnvDTE.ProjectItem
If Not (colProjectItems Is Nothing) Then
For Each objProjectItem In colProjectItems
For i As Integer = 1 To objProjectItem.FileCount
Dim fileName As String = objProjectItem.FileNames(i)
If fileName <> "" And Not System.IO.File.Exists(fileName) _
And Not System.IO.Directory.Exists(fileName) Then
MessageBox.Show("File missing: " + fileName)
End If
Next
If Not (objProjectItem.SubProject Is Nothing) Then
' We navigate recursively because it can be:
' - An Enterprise project in Visual Studio .NET 2002/2003
' - A solution folder in VS 2005
NavigateProject(objProjectItem.SubProject)
Else
' We navigate recursively because it can be:
' - An folder inside a project
' - A project item with nested project items (code-behind files, etc.)
NavigateProjectItems(objProjectItem.ProjectItems)
End If
Next
End If
End Sub
End Module
3 comments
-
(17,0): error BC30469: Reference to a non-shared member requires an object reference.
(20,0): error BC30469: Reference to a non-shared member requires an object reference.
i get this error when trying to compile abv code -
how to use this script? in vs2012
-
This script just saved me several hours of work. Thank you very much. Great piece of code.