{"id":2203,"date":"2010-04-16T14:23:00","date_gmt":"2010-04-16T14:23:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudio\/2010\/04\/16\/custom-extension-types-with-vsix\/"},"modified":"2022-10-13T15:23:36","modified_gmt":"2022-10-13T22:23:36","slug":"custom-extension-types-with-vsix","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/custom-extension-types-with-vsix\/","title":{"rendered":"Custom Extension Types with VSIX"},"content":{"rendered":"<p><strong>DISCLAIMER: <em>While the following technique is supported in Visual Studio 2010, the interfaces and methods exposed by Microsoft.VisualStudio.ExtensionManager.dll are likely to change in future Visual Studio releases. If you create an extension that relies on Microsoft.VisualStudio.ExtensionManager.dll, there is no guarantee that your extension binary will work on future Visual Studio releases without code changes.<\/em><\/strong><\/p>\n<p>If you\u2019ve <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/using-the-vsix-manifest-editor\/\">used the VSIX Manifest editor<\/a> when creating an extension for Visual Studio 2010, you may have noticed the various options when you add content to the VSIX container. Clicking the \u201cAdd Content\u201d button will bring up a dialog that allows you to select a content type.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/AddContentDialog_2.png\"><img decoding=\"async\" style=\"border-width: 0px;\" title=\"AddContentDialog\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/04\/AddContentDialog_thumb.png\" alt=\"AddContentDialog\" width=\"304\" height=\"222\" border=\"0\" \/><\/a><\/p>\n<p>Most of the choices are well-known types that Visual Studio already knows how to consume:<\/p>\n<ul>\n<li>Project\/Item Template: A collection of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms247064(VS.100).aspx\">VSTemplate<\/a> zip files from which a user can create projects and project items.<\/li>\n<li>Template Wizard: An assembly (distributed with one or more VSTemplates) that contains a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.visualstudio.templatewizard.iwizard.aspx\">template wizard extension<\/a> to show UI or perform custom logic at template instantiation time.<\/li>\n<li>VS Package: A <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/whats-a-pkgdef-and-why\/\">PkgDef file<\/a> containing configuration information for <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb165146.aspx\">a VSPackage<\/a>.<\/li>\n<li>MEF Component: An assembly to be queried and consumed by the VS MEF Host for <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd885013(VS.100).aspx\">extending the core text editor<\/a> and other MEF-based subsystems in the IDE.<\/li>\n<li>Toolbox Control: An assembly containing one or more controls to publish on the Toolbox for use in the various UI designers in Visual Studio.<\/li>\n<\/ul>\n<p>You may be wondering what the \u201cCustom Extension Type\u201d entry (highlighted above) is and why you would want to use it.<\/p>\n<p>Let\u2019s say you want to ship an extension to Visual Studio that is itself extensible. If the extensibility points you are exposing involve managed code, a MEF-based solution would be a reasonable option to consider. However, imagine that what you consume from your extenders is more like data or content rather than code. [For a real world example, consider the built-in Project\/Item Template extension content types.] In this case, having these extension authors create an assembly (and having Visual Studio load and manage it at runtime) simply to provide data or content is too heavyweight.<\/p>\n<p>This is where the content with a Custom Extension Type comes in handy. \u201cOK\u201d, you may be thinking. \u201cBut why couldn\u2019t I just have end-users put these content files into a certain directory on the local machine where my extension would find them?\u201d You certainly could. However, the advantage of using VSIX content with a Custom Extension Type is that the content can be managed by the end-user via the <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/how-vsix-extensions-are-discovered-and-loaded-in-vs-2010\/\">Extension Manager<\/a>. Installing and removing the content is exactly the same user experience as for any other extension.<\/p>\n<h2>Walkthrough: Consuming Custom Extension Content<\/h2>\n<p>Let\u2019s create an extension to demonstrate consuming custom content distributed in a VSIX. In this walkthrough, we\u2019ll create a tool window called Image Browser that queries the Extension Manager for content of type <em>WalkthroughImage<\/em>. Then, we\u2019ll create another extension that provides the content that our tool window will consume. (<strong><em>You must have the <a href=\"http:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyID=47305cf4-2bea-43c0-91cd-1b853602dcc5\">Visual Studio 2010 SDK<\/a> installed to complete the walkthrough.<\/em><\/strong>)<\/p>\n<ol>\n<li>Open the New Project dialog to create a new Visual Studio Package from the Extensibility category under Visual C# called \u201cImageBrowser\u201d.<\/li>\n<li>In the Visual Studio Package Wizard, select the \u201cTool Window\u201d option on Page 3.<\/li>\n<li>Rename \u201cMy Tool Window\u201d to \u201cImage Browser\u201d on Page 5.<\/li>\n<li>After completing the wizard, replace the content inside the &lt;Grid&gt; element in MyControl.xaml with the following:\n<div id=\"codeSnippetWrapper\">\n<pre id=\"codeSnippet\"><span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">ScrollViewer<\/span><span style=\"color: #0000ff;\">&gt;<\/span>\r\n  <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">WrapPanel<\/span> <span style=\"color: #ff0000;\">Name<\/span><span style=\"color: #0000ff;\">=\"wrapPanel1\"<\/span> <span style=\"color: #0000ff;\">\/&gt;<\/span>\r\n<span style=\"color: #0000ff;\">&lt;\/<\/span><span style=\"color: #800000;\">ScrollViewer<\/span><span style=\"color: #0000ff;\">&gt;<\/span><\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<\/li>\n<li>Add a reference to Microsoft.VisualStudio.ExtensionManager.dll (located in &lt;VSInstallDirectory&gt;Common7IDEPrivateAssemblies)<\/li>\n<li>In MyControl.xaml.cs, add the following method:\n<div id=\"codeSnippetWrapper\">\n<pre id=\"codeSnippet\"><span style=\"color: #0000ff;\">internal<\/span> <span style=\"color: #0000ff;\">void<\/span> AddImageFromPath(<span style=\"color: #0000ff;\">string<\/span> path)\r\n{\r\n    <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #0000ff;\">int<\/span> ImageWidth = 250;\r\n    BitmapImage bitmapImage = <span style=\"color: #0000ff;\">new<\/span> BitmapImage();\r\n    bitmapImage.BeginInit(); \r\n    bitmapImage.UriSource = <span style=\"color: #0000ff;\">new<\/span> Uri(path); \r\n    bitmapImage.DecodePixelWidth = ImageWidth; \r\n    bitmapImage.EndInit(); \r\n    <span style=\"color: #0000ff;\">this<\/span>.wrapPanel1.Children.Add(<span style=\"color: #0000ff;\">new<\/span> Image() \r\n    { \r\n        Source = bitmapImage, MaxWidth = ImageWidth \r\n    });\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<\/li>\n<li>Close MyControl.xaml.cs<\/li>\n<li>Open <strong><em>MyToolWindow.cs<\/em><\/strong> and add the following using statement:\n<div id=\"codeSnippetWrapper\">\n<pre id=\"codeSnippet\"><span style=\"color: #0000ff;\">using<\/span> Microsoft.VisualStudio.ExtensionManager;<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<\/li>\n<li>Add the following code at the end of the MyToolWindow constructor:\n<div id=\"codeSnippetWrapper\">\n<pre id=\"codeSnippet\"><span style=\"color: #008000;\">\/\/Query the Extension Manager for content of type \"WalkthroughImage\" const string WalkthroughImageContentType = \"WalkthroughImage\"; <\/span>\r\nIVsExtensionManager extensionManager = ServiceProvider.GlobalProvider.GetService(<span style=\"color: #0000ff;\">typeof<\/span>(SVsExtensionManager)) <span style=\"color: #0000ff;\">as<\/span> IVsExtensionManager;\r\n<span style=\"color: #0000ff;\">if<\/span> (extensionManager != <span style=\"color: #0000ff;\">null<\/span>)\r\n{\r\n    <span style=\"color: #0000ff;\">foreach<\/span> (<span style=\"color: #0000ff;\">string<\/span> image <span style=\"color: #0000ff;\">in<\/span> extensionManager.GetEnabledExtensionContentLocations(WalkthroughImageContentType)) \r\n    { \r\n        ((MyControl)<span style=\"color: #0000ff;\">base<\/span>.Content).AddImageFromPath(image); \r\n    }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<\/li>\n<li>Press F5 to debug the extension in the Experimental instance. You can show the tool window you just created from Views \u2013&gt; Other Windows \u2013&gt; Image Browser, but there won\u2019t be any images in the tool window just yet.<\/li>\n<li>Close the Experimental instance and return to your previous VS instance.<\/li>\n<\/ol>\n<h2>Walkthrough: Creating an Extension with Custom Content<\/h2>\n<p>&nbsp;<\/p>\n<p>Now let\u2019s create another extension that will provide content to our tool window we just created. We\u2019ll create a VSIX containing the sample images included in Windows 7 so that they display in our Image Browser tool window.<\/p>\n<ol>\n<li>In the Solution you created in the previous walkthrough, add a New Project to the solution.<\/li>\n<li>In the New Project dialog, select the \u201cVSIX Project\u201d template from under Visual C# \u2013&gt; Extensibility or Visual Basic \u2013&gt; Extensibility. (There won\u2019t be any code to compile, so the language choice here doesn\u2019t matter.)<\/li>\n<li>Name the project <strong>SampleImagePack <\/strong>and Click OK.<\/li>\n<li>In the VSIX Manifest Designer after the project is created, click the \u201cAdd Content\u201d button.<\/li>\n<li>Choose \u201cCustom Extension Type\u201d for the content type.<\/li>\n<li>In the Type field, enter \u201cWalkthroughImage\u201d.\u00a0\u00a0 (without the quotes)<\/li>\n<li>For the source, choose the File radio button and navigate to the Sample Pictures in Windows. (They are located in the Public Pictures folder.)<\/li>\n<li>Select one of the images in the folder.<\/li>\n<li>Click OK in the Add Content dialog.<\/li>\n<li>Repeat steps 4-9 for each image you wish to add.<\/li>\n<li>Press F5 to debug both the Image Browser tool window extension and the SampleImagePack extension in the Experimental instance.<\/li>\n<li>Show the image browser tool window from View \u2013&gt; Other Windows \u2013&gt; Image Browser and notice that the images added to the SampleImagePack are now displayed in the ImageBrowser control.<\/li>\n<li>(optional) You can repeat the steps above to create multiple image pack VSIX\u2019s which will be merged together in the Image Browser tool window.<\/li>\n<\/ol>\n<p>When you bring up the tool window, you should see something like this:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/ImageBrowser_2.png\"><img decoding=\"async\" style=\"border-width: 0px;\" title=\"Image Browser\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/04\/ImageBrowser_thumb.png\" alt=\"Image Browser\" width=\"244\" height=\"177\" border=\"0\" \/><\/a><\/p>\n<p>We\u2019re looking forward to seeing how you use this functionality for your own extensions! As always, please let us know what you think.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/aaronm3_2%5B1%5D_2.jpg\"><img decoding=\"async\" style=\"margin: 0px 15px 0px 0px; border-width: 0px;\" title=\"aaronm3_2[1]\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/04\/aaronm3_25B15D_thumb.jpg\" alt=\"aaronm3_2[1]\" width=\"109\" height=\"109\" align=\"left\" border=\"0\" \/><\/a><\/p>\n<p><b>Aaron Marten &#8211;<\/b> Developer, Visual Studio Platform<\/p>\n<p><b>Short Bio<\/b>: Aaron has been on the Visual Studio team for over 6 years with a focus on extensibility. For Visual Studio 2010, Aaron worked on the Extension Manager and the Visual Studio SDK. In addition to contributing to the Visual Studio blog, he also writes about extending the IDE on his own blog at <a href=\"https:\/\/learn.microsoft.com\/en-us\/archive\/blogs\/aaronmar\/\">https:\/\/learn.microsoft.com\/en-us\/archive\/blogs\/aaronmar\/<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>DISCLAIMER: While the following technique is supported in Visual Studio 2010, the interfaces and methods exposed by Microsoft.VisualStudio.ExtensionManager.dll are likely to change in future Visual Studio releases. If you create an extension that relies on Microsoft.VisualStudio.ExtensionManager.dll, there is no guarantee that your extension binary will work on future Visual Studio releases without code changes. If [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":255385,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[155],"tags":[5,653,13,133],"class_list":["post-2203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio","tag-csharp","tag-visual-basic","tag-visual-studio-2010","tag-xaml"],"acf":[],"blog_post_summary":"<p>DISCLAIMER: While the following technique is supported in Visual Studio 2010, the interfaces and methods exposed by Microsoft.VisualStudio.ExtensionManager.dll are likely to change in future Visual Studio releases. If you create an extension that relies on Microsoft.VisualStudio.ExtensionManager.dll, there is no guarantee that your extension binary will work on future Visual Studio releases without code changes. If [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/2203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=2203"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/2203\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/255385"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=2203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=2203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=2203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}