2016-12-22 102 views
1

我正在为Visual Studio 2015编写一个扩展。 我添加了一个VSPackage来将一些CustomCommands嵌入到您在解决方案资源管理器中右键单击项目或文件夹时获得的快捷菜单上。VisualStudio VSPackage自定义命令

我现在想要做的是“打开添加新项目对话框,并选择我用这个VSPackage安装的模板之一”。

这是我使用初始化我的命令代码:(目前我只需创建一个消息框,只是为了确保它的工作原理)

private void CreateCustomTemplate(object sender, EventArgs eventArgs) 
{ 
    //TODO: code to replace! 
    var message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.CreateCustomTemplate()", GetType().FullName); 

    // Show a message box to prove we were here 
    VsShellUtilities.ShowMessageBox(
     ServiceProvider, 
     message, 
     "CREATE CustomTemplate", 
     OLEMSGICON.OLEMSGICON_INFO, 
     OLEMSGBUTTON.OLEMSGBUTTON_OK, 
     OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); 
} 

private TemplateCommand(Package package) 
{ 
    if (package == null) 
     throw new ArgumentNullException(nameof(package)); 

    _package = package; 

    var commandService = ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService; 
    if (commandService == null) 
     return; 

    AddCommand(commandService, CommandId, CreateCustomTemplate); 
} 

的CreateCustomTemplate回调代码是这样的

因此,回顾一下,如何打开添加新项目对话框并选择特定项目模板

举个例子,当您尝试在Solution Explorer RightClick on Folder, then Add -> UserControl

您获得类似这样的东西来创建一个文件夹上一个类或用户控件右击: Result

这是,正是我想要达到的目标。很显然,我想创建自己的模板而不是UserControl。

如果您需要任何澄清随时问。 预先感谢您的任何建议

回答

0

最后我解决了我的问题。

不幸的是,命令File.AddNewItem(或Project.AddNewItem)不适合我的情况,因为我想查看AddNewFile对话框(并且这些命令只是将项目添加到指定的项目中)。

我发现解决方案挖网,确切地说是here,特别感谢Vladimir.Ilic的回答。

这是我使用来实现我的目标代码:

internal sealed class TemplateCommand 
{ 
    private const int CustomCommandId = 0x1023; 

    private static readonly Guid CommandSet = COMMANDSET_GUID; 
    private readonly Package _package; 


    // ReSharper disable MemberCanBePrivate.Global 
    // ReSharper disable UnusedAutoPropertyAccessor.Global 
    public IServiceProvider ServiceProvider => _package; 

    public static TemplateCommand Instance { get; set; } 
    // ReSharper restore UnusedAutoPropertyAccessor.Global 
    // ReSharper restore MemberCanBePrivate.Global 

    public static void Initialize(Package package) 
    { 
     Instance = new TemplateCommand(package); 
    } 

    private TemplateCommand(Package package) 
    { 
     if (package == null) 
      throw new ArgumentNullException(nameof(package)); 

     _package = package; 

     var commandService = ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService; 
     if (commandService == null) 
      return; 

     AddCommand(commandService, CustomCommandId, CreateCustomCommand); 
    } 

    private static void AddCommand(IMenuCommandService commandService, int commandId, EventHandler callback) 
    { 
     var command = new CommandID(CommandSet, commandId); 
     var menuItem = new MenuCommand(callback, command); 
     commandService.AddCommand(menuItem); 
    } 

    private void CreateCustomCommand(object sender, EventArgs eventArgs) 
    { 
     AddNewItem("MyCustomCommand"); 
    } 

    private void AddNewItem(string itemName) 
    { 
     var dte = ServiceProvider.GetService(typeof(DTE)) as DTE; 
     if (dte == null) 
      return; 

     int iDontShowAgain; 
     uint projectItemId; 
     var strFilter = string.Empty; 

     var hierarchy = GetCurrentVsHierarchySelection(out projectItemId); 
     if (hierarchy == null) 
      return; 

     var project = ToDteProject(hierarchy); 
     if (project == null) 
      return; 

     var vsProject = ToVsProject(project); 
     if (vsProject == null) 
      return; 

     var addItemDialog = ServiceProvider.GetService(typeof(IVsAddProjectItemDlg)) as IVsAddProjectItemDlg; 
     if (addItemDialog == null) 
      return; 

     const uint uiFlags = (uint)(__VSADDITEMFLAGS.VSADDITEM_AddNewItems | __VSADDITEMFLAGS.VSADDITEM_SuggestTemplateName | __VSADDITEMFLAGS.VSADDITEM_AllowHiddenTreeView); 
     const string categoryNameInNewFileDialog = "MyCustomTemplates"; 

     // ProjectGuid for C# projects 
     var projGuid = new Guid("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"); 

     string projectDirectoryPath; 
     hierarchy.GetCanonicalName(projectItemId, out projectDirectoryPath); 
     var itemNameInNewFileDialog = itemName; 
     addItemDialog.AddProjectItemDlg(projectItemId, 
             ref projGuid, 
             vsProject, 
             uiFlags, 
             categoryNameInNewFileDialog, 
             itemNameInNewFileDialog, 
             ref projectDirectoryPath, 
             ref strFilter, 
             out iDontShowAgain); 
    } 

    private static IVsHierarchy GetCurrentVsHierarchySelection(out uint projectItemId) 
    { 
     IntPtr hierarchyPtr, selectionContainerPtr; 
     IVsMultiItemSelect mis; 
     var monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection)); 
     monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr); 

     var hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy; 
     return hierarchy; 
    } 

    private static Project ToDteProject(IVsHierarchy hierarchy) 
    { 
     if (hierarchy == null) 
      throw new ArgumentNullException(nameof(hierarchy)); 

     object prjObject; 
     if (hierarchy.GetProperty(0xfffffffe, (int)__VSHPROPID.VSHPROPID_ExtObject, out prjObject) == VSConstants.S_OK) 
      return (Project)prjObject; 

     throw new ArgumentException("Hierarchy is not a project."); 
    } 

    private IVsProject ToVsProject(Project project) 
    { 
     if (project == null) 
      throw new ArgumentNullException(nameof(project)); 

     var vsSln = ServiceProvider.GetService(typeof(IVsSolution)) as IVsSolution; 
     if (vsSln == null) 
      throw new ArgumentException("Project is not a VS project."); 

     IVsHierarchy vsHierarchy; 
     vsSln.GetProjectOfUniqueName(project.UniqueName, out vsHierarchy); 
     // ReSharper disable SuspiciousTypeConversion.Global 
     var vsProject = vsHierarchy as IVsProject; 
     // ReSharper restore SuspiciousTypeConversion.Global 
     if (vsProject != null) 
      return vsProject; 

     throw new ArgumentException("Project is not a VS project."); 
    } 
} 

非常感谢那个路过的那些和那些试图(甚至鑫卡特)帮助!

希望这可以帮助别人,

真诚

0

您可以执行命令“Project.AddNewItem”或“File.AddNewItem”来显示对话框。有几种编程方式来执行命令,最简单的方法是获取EnvDTE.DTE实例并调用dte.ExecuteCommand(commandName)。

至于选择所需的模板,请参阅parameters for the command File.AddNewItem。有些运气对于Project.AddNewItem命令是一样的。

+0

我没有给AddNewItem一试,因为我认为这将只是一个文件添加到我需要的项目。只要我能试一试,我会让你如果和我如何解决它 – Easly