Logo
BUG: EnvDTE80.Solution2.GetProjectTemplate returns wrong template for ClassLibrary if Windows Phone SDK installed

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2012
Date: July 2013    
       
Introduction

This article explains a bug that happens when trying to get the project template for a Windows Class Library project if the Windows Phone SDK 8.0 is installed.

More Information

When you call EnvDTE80.Solution2.GetProjectTemplate("ClassLibrary.zip", "CSharp") and you have the Windows Phone SDK 8.0 installed, the returned template belongs to the Windows Phone class library, rather than to the Windows class library. According to the MSDN Documentation of Solution2.GetProjectTemplate:

"Custom templates require unique file names that do not conflict with the file names defined in: C:\Program Files\Microsoft Visual Studio <version>\Common7\IDE\ProjectTemplates\Language".

If that applies to custom templates, it should also apply to templates provided by SDKs, and it happens that the "ClassLibrary.zip" file name is not unique, the Windows Phone SDK 8.0 uses also that name inside the "CSharp\Windows Phone\1033\ClassLibrary" folder.

A similar problem was reported for Windows Metro Class Library projects during the Visual Studio 2012 Beta and was fixed. Unfortunately, the problem happens also with other SDKs like Windows Phone SDK 8.0.

The following add-in reproduces the problem: when the Windows Phone SDK 8.0 is installed, the template file name returned for Class Library projects of C# is:

"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ProjectTemplatesCache\CSharp\Windows Phone\1033\ClassLibrary.zip\csClassLibrary.vstemplate"

 instead of:

"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ProjectTemplatesCache\CSharp\Windows\1033\ClassLibrary.zip\csClassLibrary.vstemplate"

Language: C#   Copy Code Copy Code (IE only)
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;

namespace MyAddin1
{
   public class Connect : IDTExtensibility2
   {
      private DTE2 _applicationObject;
      private AddIn _addInInstance;
      
      public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
      {
         _applicationObject = (DTE2)application;
         _addInInstance = (AddIn)addInInst;
         
         switch( connectMode)
         {
            case ext_ConnectMode.ext_cm_AfterStartup:

               // The add-in has been loaded after Visual Studio was loaded. Since Visual Studio
               // is fully initialized, we can initialize the add-in
               InitializeAddIn();
               break;

            case ext_ConnectMode.ext_cm_Startup:

               // The add-in has been loaded with Visual Studio. Do nothing until Visual Studio 
               // is fully initialized (the OnStartupComplete method will be called)
               break;

            case ext_ConnectMode.ext_cm_UISetup:

               // Do nothing in this case
               break;
         }
      }

      public void OnStartupComplete(ref Array custom)
      {
         InitializeAddIn();
      }

      private void InitializeAddIn()
      {
         EnvDTE80.Solution2 solution2;
         string projectTemplateFileFullName;

         solution2 = (EnvDTE80.Solution2)_applicationObject.Solution;

         projectTemplateFileFullName = solution2.GetProjectTemplate("ClassLibrary.zip", "CSharp");

         System.Windows.Forms.MessageBox.Show(projectTemplateFileFullName);
      }

      public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
      {
      }

      public void OnAddInsUpdate(ref Array custom)
      {
      }

      public void OnBeginShutdown(ref Array custom)
      {
      }
   }
}

Related articles


Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this


Top