VB.NET EnvDTE Up-To-Date check before building project
Asked Answered
P

2

4

how do I check if a project is up-to-date?

I'm basically trying to programmatically build each project in a list but only if they have changed. So does anyone know of a way (using EnvDTE maybe) to check if a project changed and therefore needs to compile?

Thanks in advance for all the help.

Panier answered 5/11, 2009 at 21:9 Comment(5)
In theory, a project that supports the Build and Rebuild commands is supposed to not build if a build is not necessary, so you shouldn't have to check anything, and just go build. And if the project doesn't support that, there are good chances that you won't be able to find out its build status anyway.Congresswoman
@SimonMourier If you Build a C# project that hasn't been changed, indeed Visual Studio won't recompile the code, but it will still run its post build events, etc.. Somehow when you hit F5 and there were no changes, Visual Studio avoids that completely. I'd like to do the same thing myself.Crupper
Are you only focused on C# projects?Congresswoman
Yes, in all their different variations (Console, Class Library, Azure, ASP.NET Web Site, ASP.NET Web Project, etc etc...)Crupper
Why would you need to do that?Octagonal
R
0

Use the EnvDTE.Document interface:

Document d = //get document
bool saved = d.Saved;

The Saved property will be false if the document is dirty.

Remarque answered 5/11, 2009 at 21:17 Comment(3)
Ok .. So I have to iterate through the entire list of source code files in the project and check for d.Saved then right? That sounds like a good suggestion but do you know of doing that on the Project level without iterating through the list? ThanksPanier
No, you'd only have to iterate through open windows... if you close a window after editing you are prompted to save or discard the changes so a closed window can't be dirty. EnvDTE.Windows will give you a collection of all open windows.Remarque
I just thought of a scenario where relying on the d.Saved method to determine if a project is out-of-date or not will fail. If I have a x.vb class and I make changes to it. Then hit save but not build the project right there, then this method would fail because d.Saved will return True (but the project is in dirty mode). I'm basically looking for the exact method the Visual Studio IDE uses to determine whether to compile the project or just return up-to-date check. ThanksPanier
C
0

You can do it using the UpToDate property of VCConfiguration.

Assuming you can get an instance of EnvDTE.DTE you can get the required VCProjectEngine VCConfiguration for the active project like this:

public Project GetSolutionStartupProject(DTE dte)
{
  string startupProjectName = String.Empty;

  SolutionBuild solutionBuild = dte.Solution.SolutionBuild as SolutionBuild;
  foreach (string item in solutionBuild.StartupProjects as Array)
  {
    startupProjectName += item;
  }

  return dte.Solution.Item(startupProjectName);
}

public void BuildStartupProject(DTE dte)
{
  Project project = GetSolutionStartupProject(dte);
  Configuration activeConfiguration = project.ConfigurationManager.ActiveConfiguration;

  // annoyingly can't just do activeConfiguration.Object as VCConfiguration
  //
  VCProject vcProject = project.Object as VCProject;
  VCConfiguration vcActiveConfiguration = null;
  foreach (VCConfiguration vcConfiguration in vcProject.Configurations)
  {
    if (vcConfiguration.ConfigurationName == activeConfiguration.ConfigurationName &&
        vcConfiguration.Platform.Name == activeConfiguration.PlatformName)
    {
      vcActiveConfiguration= vcConfiguration;
      break;
    }
  }

  if (!vcActiveConfiguration.UpToDate)
  {
    vcActiveConfiguration.Build();
  }
}

If you wanted to do all projects in the solution then it would be easier as you don't need to find the startup project. The important part is converting an instance of DTE Project to a VCProjectEngine VCProject, looping the VCConfigurations once you've done that should be easy.

Also worth noting that VCConfiguration.Build() will only build that configuration and fail if the dependencies haven't been built. You can use SolutionBuild.BuildProject() to build the project and its dependencies.

Camillacamille answered 8/3, 2013 at 0:1 Comment(7)
This looks great, but is there a solution that works for C# projects as well?Crupper
Ah sorry, didn't realise that. I'm looking through the MSDN docs which I guess you've also done, can't seem to see anything. I'll keep looking but it doesn't look like there is a way.Camillacamille
I guess you could loop the project file items and look at the VSLangProj.IsDependentFile property and then check the modified time for that and compare it to the output file (VSLangProj2.ProjectConfigurationProperties2.OutputPath) time stamp. I can try and write a function that tries that if you want?Camillacamille
that could be nice, but the question is, is that 100% equivalent to what Visual Studio does? And also, wouldn't I have to do the same for all projects I reference?Crupper
I'll award you the bounty since it seems you're close... but please let me know whether you're sure your proposed solution will correctly emulate Visual Studio's behavior in 100% of cases. I'm writing a commercial VS extension so can't take any chance :)Crupper
I'm not completely sure if that would be identical to Visual Studio's behaviour it's the closest I could find when looking through the MSDN documentation. You may have to ask on the Visual Studio Extensibility forum and see if anyone working on Visual Studio can give you some clarification.Camillacamille
For those who don't know, this only works for C++ projects. It would seem a useful comment has been deleted.Sheriff

© 2022 - 2024 — McMap. All rights reserved.