PRB: Menu commands not refreshed after a change when clicking Start Debugging in a VS 2010 package project

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2010
Date: August 2014    

When you create a package in Visual Studio 2010 and you update some command menu data in the .vsct file:

  • If you just click "Start Debugging", the command menu is not refreshed with the updated data in the Visual Studio experimental instance.
  • If you rebuild and then click "Start Debugging", the command menu is refreshed.

In Visual Studio 2012 and higher just clicking "Start Debugging" does refresh the command menu (no need to rebuild).

More Information

Steps to reproduce the problem:

  • Create a package with the package wizard, with a command in the "Tools" menu.
  • Click "Start Debugging". The command appears in the "Tools" menu.
  • Stop debugging and in the .vsct file change the ButtonText property of the command.
  • Save the changes and click "Start Debugging". The command still shows the old text.
  • Stop debugging, rebuild the solution and click "Start Debugging". The comand now shows the new text.
  • If you repeat the same process with a Visual Studio 2012 or 2013 package project, no rebuild is needed to get the command button text updated.

This problem happens because the GeneratePkgDef target of the VS 2010 SDK doesn't update the timestamp of the .pkgdef file when the .vsct table has changed (and a new .cto resource is embedded in the package) and Visual Studio doesn't pick up the changes. To solve this issue:

  • Open notepad.exe with admin rights.
  • Open the Microsoft.VsSDK.targets file in the folder "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\VSSDK\"
  • Find the target with the name GeneratePkgDef".
  • Modify the code to add the lines that invoke the Touch target:
Language: XML   Copy Code Copy Code (IE only)
  <Target Name="GeneratePkgDef"

    <Message Importance="High" Text="Creating intermediate PkgDef file." />

    <CreatePkgDef AssemblyToProcess="$(TargetPath)"
              ReferencedAssemblies="@(ReferencePath)"  />

    <CopyIfChanged Condition="Exists('$(IntermediateOutputPath)$(TargetName).latest.pkgdef')"
                   DestinationFile="$(IntermediateOutputPath)$(TargetName).pkgdef" />

    <!-- If the CTO file was changed, touch the pkgdef file to cause a re-merge -->
    <Touch Files="$(IntermediateOutputPath)$(TargetName).pkgdef"
           Condition="'$(CTOFileHasChanged)'=='true' AND Exists('$(IntermediateOutputPath)$(TargetName).pkgdef')" />

      <FileWrites Include="$(IntermediateOutputPath)$(TargetName).pkgdef" 
      <FileWrites Include="$(IntermediateOutputPath)$(TargetName).latest.pkgdef" 

Go to the 'Visual Studio Extensibility (VSX)' web site for more articles like this (Articles section)