title: Changing Project Metadata in Visual Studio 2013 C#
body: <p>I've got a Visual Studio 2013 package written in C# where I need to <strong>make some changes in the items and their attributes in a C++ project file while Visual Studio 2013 is running</strong> and has the project loaded. Actually, it could also be OK to save the project file at the point when the whole solution is being saved.</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
    &lt;ItemGroup Label="Test"&gt;
      &lt;MyItemToChange Include = "TestItem"&gt;
        &lt;MyMetadata1ToChange&gt;Value1&lt;/MyMetadata1ToChange&gt;
        &lt;MyMetadata2ToChange&gt;Value2&lt;/MyMetadata2ToChange&gt;
      &lt;/MyItemToChange&gt;
    &lt;/ItemGroup&gt;
    &lt;!-- The rest of the file --&gt;
  &lt;/Project&gt;
  </code></pre>
  
  <p>In previous Visual Studio versions I used the <a href="http://msdn.microsoft.com/en-us/library/microsoft.build.evaluation.project.aspx" rel="nofollow">Microsoft.Build.Evaluation.Project</a> class to change the items and the metadata of the project. When you have the reference to the project, you can either accessed the XML structure of the project directly through <code>Project.Xml</code> property or get a hold on different <code>Microsoft.Build.Evaluation.ProjectItem</code> and use the interfaces found there.</p>
  
  <p>However, since Microsoft has changed the structure of Visual Studio in their 2013 release, though the <code>Microsoft.Build.Evaluation.Project</code> is not deprecated, you can't access the C++ projects any more through <a href="http://msdn.microsoft.com/en-us/library/microsoft.build.evaluation.projectcollection.loadedprojects(v=vs.110).aspx" rel="nofollow">Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.LoadedProjects</a> as the collection is empty. However it still works if you want to access C# projects. (As a matter of fact, browsing deep into the objects while debugging you can find that they still use the same <code>Microsoft.Build.Evaluation</code> namespace for inner representation.)</p>
  
  <p><strong>Since I can't access the <code>Microsoft.Build.Evaluation.Project</code> any more, I need an alternative to</strong></p>
  
  <ol>
  <li>access the project otherwise than using the
  <code>Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.LoadedProjects</code></li>
  <li>write project items and metadata while Visual Studio 2013 is running.</li>
  </ol>
  
  <p><strong>Unless I've missed something, the following are not good for my purposes:</strong></p>
  
  <ol>
  <li><code>Microsoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage.SetItemAttribute</code> sets only attributes to items that are displayed in the Solution Explorer. "MyItemToChange" is not displayed in the Solution Explorer</li>
  <li>Opening the file and manually editing and saving it. Unless you know how to suppress Visual Studio's warning about a changed project and how to auto reload it, it is not a way to go.<br>
  <strong><em>Note:</strong> You can close the solution, open the project file manually, edit then save it and reopen the solution. It would work fine, the data is there, unless the files are under source control. Now it opens up a whole lot of new issues (why EnvDTE.DTE.SourceControl.CheckOutItem() doesn't work, etc.) So I still think I would be better off if Visual Studio would handle writing data to the project file.</em></li>
  <li>Reflection. Yes, as I mentioned before, I could dig into internal classes to get a hold on the "original" <code>Microsoft.Build.Evaluation.Project</code>, and <code>Microsoft.Build.Evaluation.ProjectItem</code>, but first of all, it is quite unsafe for future uses and as far as I remember, you cannot be sure that if you modify these now internal classes, the project will know that it is dirty and has to be saved.</li>
  </ol>
  
  <p>I'm glad to have any suggestions as I'm really running out of options.</p>
  
  <p>Thanks.</p>