Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I programmatically refresh/reload a VS project after modifying the underlying file?

I am developing a Visual Studio package and I have written some code that will make a file in Solution Explorer dependant upon another file.

What this means is that it gives them the same relationship as code-behind files or designer files, where they appear nested under the parent file with a plus/minus icon.

+ MainForm.cs


- MainForm.cs
   MainForm.Designer.cs
   MainForm.resx

The code that I have written successfully and correctly modifies the underlying project file, however the change is not reflected in Solution Explorer until the project is closed and re-opened.

I'm looking for some code that will refresh or reload the project so that the change is visible in Solution Explorer immediately.

Further Information...

Here is the sudo code that demonstrates the mechanism by which I create the dependant file.

IVsBuildPropertyStorage vsBuildPropertyStorage = GetBuildPropertyStorage();
vsBuildPropertyStorage.SetItemAttribute(projectItemIdentifier, "DependentUpon", parentFileName);

I have also tried adding this in an attempt to get the project to reload, but it doesn't have any effect.

project.Save();
VSProject obj = project.Object as VSProject;
obj.Refresh();
like image 231
Martyn Avatar asked Sep 07 '12 14:09

Martyn


2 Answers

AFAIK the only way of doing this is via automation of the Solution Explorer tool-window:

EnvDTE.DTE dte = ...;

string solutionName = Path.GetFileNameWithoutExtension(dte.Solution.FullName);
string projectName = project.Name;

dte.Windows.Item(EnvDTE.Constants.vsWindowKindSolutionExplorer).Activate();
((DTE2)dte).ToolWindows.SolutionExplorer.GetItem(solutionName + @"\" + projectName).Select(vsUISelectionType.vsUISelectionTypeSelect);

dte.ExecuteCommand("Project.UnloadProject");
dte.ExecuteCommand("Project.ReloadProject");

Note that, if the project hasn't been saved, the user will get a dialog box prior to the "Project.UnloadProject" call.

like image 77
Dan Nolan Avatar answered Sep 30 '22 19:09

Dan Nolan


Here is my code (with reactivating the old window):

public void RefreshSolutionExplorer(EnvDTE.Project activeProject, string captionOfActiveWindow)
{
  DTE2 dte2 = activeProject.DTE as DTE2;
  string solutionName = Path.GetFileNameWithoutExtension(dte2.Solution.FullName);
  string projectName = activeProject.Name;

  // Activate SolutionExplorer window
  dte2.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate();
  // Select your project to be updated
  dte2.ToolWindows.SolutionExplorer.GetItem(solutionName + @"\" + projectName).Select(vsUISelectionType.vsUISelectionTypeSelect);
  // Refresh SolutionExplorer window
  dte2.ExecuteCommand("View.Refresh", String.Empty);
  // Reactivate your old window
  dte2.Windows.Item(captionOfActiveWindow).Activate();
}
like image 24
ElVit Avatar answered Sep 30 '22 18:09

ElVit