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