{"id":241795,"date":"2023-03-02T09:23:06","date_gmt":"2023-03-02T17:23:06","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/visualstudio\/?p=241795"},"modified":"2023-03-02T09:23:06","modified_gmt":"2023-03-02T17:23:06","slug":"visualstudio-extensibility-preview-3","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/visualstudio-extensibility-preview-3\/","title":{"rendered":"Build Better Extensions with VisualStudio.Extensibility Preview 3!"},"content":{"rendered":"<p>Today, we\u2019re very excited to announce the third public preview of VisualStudio.Extensibility, our new SDK for creating extensions for Visual Studio!<\/p>\n<p>The VisualStudio.Extensibility SDK focuses on extensions that run out-of-process from the IDE for improved performance and reliability, and it features a modern API that has been streamlined and carefully engineered to maximize developer productivity.<\/p>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/aka.ms\/VisualStudio.Extensibility\" target=\"_blank\">Get Started with VisualStudio.Extensibility Preview 3<\/a><\/div><\/p>\n<p>This release builds on our <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/the-future-of-visual-studio-extensibility-is-here\/\">first<\/a> and <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/visualstudio-extensibility\/\">second<\/a> public previews, and it brings some big features like an API to query and modify project information and the ability to create incredible debugger visualizers. Please visit the <a href=\"https:\/\/aka.ms\/VisualStudio.Extensibility\">VisualStudio.Extensibility repo<\/a> to find docs and installation instructions. You can also use our <a href=\"https:\/\/github.com\/microsoft\/VSExtensibility\/issues\">issue tracker<\/a> to report bugs and provide feedback.<\/p>\n<p>&nbsp;<\/p>\n<h3>What&#8217;s new for Preview 3 of VisualStudio.Extensibility?<\/h3>\n<p>The VisualStudio.Extensibility Preview 3 release expands your ability to create powerful productivity extensions, with features including:<\/p>\n<ul>\n<li><a href=\"#create-custom-data-visualizers\">Debugger Visualizers<\/a><\/li>\n<li><a href=\"#interact-with-users\">Custom Dialogs<\/a><\/li>\n<li><a href=\"#query-the-project-system\">Query the Project System<\/a><\/li>\n<li><a href=\"#add-valuable-context\">Editor Margin Extensions<\/a><\/li>\n<li><a href=\"#configure-your-extension\">Configure your Extension<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h5><a id=\"create-custom-data-visualizers\"><\/a>Create custom data visualizers for better debugging<\/h5>\n<p>Debugger visualizers, such as the popular <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/view-net-collections-with-the-new-ienumerable-debugger-visualizer\/\">IEnumerable visualizer<\/a>, add tremendous power to the debugging experience in Visual Studio by enabling custom views of complex data types. With this release, we\u2019ve leveraged our Remote UI features to enable you to create debugger visualizers with VisualStudio.Extensibility!<\/p>\n<p><figure id=\"attachment_241804\" aria-labelledby=\"figcaption_attachment_241804\" class=\"wp-caption aligncenter\" ><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/RegexMatchDebugVisualizer.png\"><img decoding=\"async\" class=\"wp-image-241804 size-full\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/RegexMatchDebugVisualizer.png\" alt=\"A screenshot of a debugger visualizer for regex matches\" width=\"368\" height=\"298\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/RegexMatchDebugVisualizer.png 368w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/RegexMatchDebugVisualizer-300x243.png 300w\" sizes=\"(max-width: 368px) 100vw, 368px\" \/><\/a><figcaption id=\"figcaption_attachment_241804\" class=\"wp-caption-text\"><span style=\"font-size: 10pt;\">A debugger visualizer for regex matches<\/span><\/figcaption><\/figure><\/p>\n<p>We can\u2019t wait to see the debugger visualizers you create with this feature!<\/p>\n<p>&nbsp;<\/p>\n<h5><a id=\"interact-with-users\"><\/a>Interact with users through custom dialogs<\/h5>\n<p>With the last release of VisualStudio.Extensibility, you could interact with users through prompts with simple, configurable buttons. Now, you can go beyond buttons and interact with your users through dialogs featuring custom UI.<\/p>\n<p><figure id=\"attachment_241805\" aria-labelledby=\"figcaption_attachment_241805\" class=\"wp-caption aligncenter\" ><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/Dialog.png\"><img decoding=\"async\" class=\"wp-image-241805 size-medium\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/Dialog-300x184.png\" alt=\"A screenshot of a custom dialog\" width=\"300\" height=\"184\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/Dialog-300x184.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/Dialog.png 563w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"figcaption_attachment_241805\" class=\"wp-caption-text\"><span style=\"font-size: 10pt;\">A dialog with custom UI<\/span><\/figcaption><\/figure><\/p>\n<p>Dialogs are backed by our Remote UI features, so you can use WPF to create rich, interactive visuals, and then you can show your dialog to the user with a simple call:<\/p>\n<pre class=\"prettyprint language-cs language-csharp\" style=\"padding-bottom: 0px; margin-bottom: 0px;\"><code class=\"language-cs language-csharp\"><span style=\"font-size: 8.5pt;\">public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)\r\n{\r\n    using IRemoteUserControl content = new MyDialogControl();\r\n    await this.Extensibility.Shell().ShowDialogAsync(content, \"My Dialog\", DialogOption.Close, cancellationToken);\r\n}<\/span><\/code><\/pre>\n<p><span style=\"font-size: 10pt;\">Sample code for showing a custom dialog<\/span><\/p>\n<p>&nbsp;<\/p>\n<h5><a id=\"query-the-project-system\"><\/a>Query the project system for information about projects and solutions<\/h5>\n<p>With the latest preview, we\u2019ve added the ability to query the project system for projects in a solution that match a set of conditions or for information about those projects. For example, you could use this query API to detect that web projects are present in the solution before enabling web-related commands in your extension:<\/p>\n<pre class=\"prettyprint language-cs language-csharp\" style=\"padding-bottom: 0px; margin-bottom: 0px;\"><span style=\"font-size: 8.5pt;\"><code class=\"language-cs language-csharp\">IQueryResults&lt;IProjectSnapshot&gt; webProjects = await Extensibility.Workspaces().QueryProjectsAsync(\r\n    project =&gt; project.Where(p =&gt; p.Capabilities.Contains(\"DotNetCoreWeb\"))\r\n                      .With(p =&gt; new { p.Path, p.Guid }),\r\n    cancellationToken);\r\n<\/code><\/span><\/pre>\n<p><span style=\"font-size: 10pt;\">Sample code for finding all the projects in a solution with a given set of capabilities.<\/span><\/p>\n<p>You could also modify projects, for example by adding a project reference or creating a new file:<\/p>\n<pre class=\"prettyprint language-cs language-csharp\" style=\"padding-bottom: 0px; margin-bottom: 0px;\"><span style=\"font-size: 8.5pt;\"><code class=\"language-cs language-csharp\">await Extensibility.Workspaces().UpdateProjectsAsync(\r\n    project =&gt; project.Where(p =&gt; p.Name == \"MyProject\"),\r\n    project =&gt; project.CreateFile(\"NewFile.txt\", newFileContents),\r\n    cancellationToken);\r\n<\/code><\/span><\/pre>\n<p><span style=\"font-size: 10pt;\">Sample code for adding a new text file to a project<\/span><\/p>\n<p>With these features, your extension can deliver experiences to your users that feel directly relevant to the code they\u2019re working on!<\/p>\n<p>&nbsp;<\/p>\n<h5><a id=\"add-valuable-context\"><\/a>Add valuable context with editor margin extensions<\/h5>\n<p>We know developers spend most of their time in Visual Studio working with files and documents in the editor. With editor margin extensions, you can get your work in front of many users by leveraging Remote UI to create great front-and-center experiences that boost developer productivity. You could use this feature to offer simple at-a-glance features like the word count or the encoding of the open document, but you could also create custom navigation bars or headers!<\/p>\n<p><figure id=\"attachment_241806\" aria-labelledby=\"figcaption_attachment_241806\" class=\"wp-caption aligncenter\" ><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/WordCountMargin.png\"><img decoding=\"async\" class=\"size-full wp-image-241806\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/WordCountMargin.png\" alt=\"A screenshot of code to insert an editor margin extension that adds a word count to the bottom editor margin\" width=\"1095\" height=\"279\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/WordCountMargin.png 1095w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/WordCountMargin-300x76.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/WordCountMargin-1024x261.png 1024w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/03\/WordCountMargin-768x196.png 768w\" sizes=\"(max-width: 1095px) 100vw, 1095px\" \/><\/a><figcaption id=\"figcaption_attachment_241806\" class=\"wp-caption-text\"><span style=\"font-size: 10pt;\">An editor margin extension that adds a word count to the bottom margin<\/span><\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/p>\n<h5><a id=\"configure-your-extension\"><\/a>Configure your extension easily with configuration properties<\/h5>\n<p>Many components defined in your extensions require you to configure how or when they appear in the IDE. For example, if you define a command, you could configure it to be a menu item in the Tools menu or an icon on the toolbar. If you define a tool window, you could configure it to be either docked or floating.<\/p>\n<p>Based on feedback from user testing, we\u2019ve completely overhauled extension configuration for better discoverability and usability. Now, you\u2019ll be able to configure your extension with strongly-typed classes and properties, and you\u2019ll have IntelliSense to help you discover and browse predefined options. These changes will help you get your extensions to work like you intend them to.<\/p>\n<p>With the changes, configuration has gone from looking like this with attributes:<\/p>\n<pre class=\"prettyprint language-cs language-csharp\" style=\"padding-bottom: 0px; margin-bottom: 0px;\"><span style=\"font-size: 8.5pt;\"><code class=\"language-cs language-csharp\">[Command(\r\n\t\"VisualStudio.Extensions.MarkdownLinter.RunLinterOnActiveDocument\",\r\n\t\"Run Linter on open file\",\r\n\tcontainerType: typeof(MarkdownLinterExtension),\r\n\tplacement: CommandPlacement.ToolsMenu)]\r\n[CommandEnabledWhen(\r\n\t\"FileSelected\",\r\n\tnew string[] { \"FileSelected\" },\r\n\tnew string[] { \"ClientContext:Shell.ActiveSelectionFileName=.+\" })]\r\n[CommandIcon(\"MarkdownIcon\", IconSettings.IconAndText)]\r\ninternal class RunLinterOnCurrentFileCommand : Command\r\n<\/code><\/span><\/pre>\n<p><span style=\"font-size: 10pt;\">Command configuration using the old configuration attributes<\/span><\/p>\n<p>to looking like this with configuration properties:<\/p>\n<pre class=\"prettyprint language-cs language-csharp\" style=\"padding-bottom: 0px; margin-bottom: 0px;\"><span style=\"font-size: 8.5pt;\"><code class=\"language-cs language-csharp\">[VisualStudioContribution]\r\ninternal class RunLinterOnCurrentFileCommand : Command\r\n{\r\n    public override CommandConfiguration CommandConfiguration =&gt; new(\"%RunLinterOnCurrentFileCommand.DisplayName%\")\r\n    {\r\n        Placements = new[] { CommandPlacement.KnownPlacements.ToolsMenu },\r\n        Icon = new(ImageMoniker.Custom(\"MarkdownIcon\"), IconSettings.IconAndText),\r\n        EnabledWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveSelectionFileName, \".+\"),\r\n    };\r\n\r\n    ...\r\n}\r\n<\/code><\/span><\/pre>\n<p><span style=\"font-size: 10pt;\">Command configuration using the new configuration properties<\/span><\/p>\n<p>&nbsp;<\/p>\n<h6><span style=\"font-size: 12pt;\">Control the placement of your commands<\/span><\/h6>\n<p>As seen in the configuration properties above, you can easily place your commands inside known menus, but you can also place them inside new menus and toolbars, which you can create and control:<\/p>\n<pre class=\"prettyprint language-cs language-csharp\" style=\"padding-bottom: 0px; margin-bottom: 0px;\"><span style=\"font-size: 8.5pt;\"><code class=\"language-cs language-csharp\">[VisualStudioContribution]\r\npublic static ToolbarConfiguration MyToolbar =&gt; new ToolbarConfiguration(\"%MyToolbar.DisplayName\")\r\n{\r\n    Children = new[]\r\n    {\r\n        ToolbarChild.Command&lt;MyCommand&gt;(),\r\n    },\r\n}\r\n<\/code><\/span><\/pre>\n<p><span style=\"font-size: 10pt;\">Sample code for creating a toolbar with a command<\/span><\/p>\n<p>&nbsp;<\/p>\n<h6><span style=\"font-size: 12pt;\">Add keyboard shortcuts to your commands<\/span><\/h6>\n<p>Now you can set keyboard shortcuts for your commands using simple sets of keys and modifiers:<\/p>\n<pre class=\"prettyprint language-cs language-csharp\" style=\"padding-bottom: 0px; margin-bottom: 0px;\"><span style=\"font-size: 8.5pt;\"><code class=\"language-cs language-csharp\">public override CommandConfiguration CommandConfiguration =&gt; new(\"%MyCommand.DisplayName%\")\r\n{\r\n    Shortcuts = new CommandShortcutConfiguration[]\r\n    {\r\n        new(ModifierKey.ControlShift, Key.G),\r\n    },\r\n};\r\n<\/code><\/span><\/pre>\n<p><span style=\"font-size: 10pt;\">Sample code for setting a keyboard shortcut for a command<\/span><\/p>\n<p>&nbsp;<\/p>\n<h3>We can\u2019t do this without you!<\/h3>\n<p>As we continue to develop VisualStudio.Extensibility, we need your help! Please give Preview 3 a try and share your thoughts with us. You can give feedback, report bugs, make suggestions, and ask questions through our <a href=\"https:\/\/github.com\/microsoft\/VSExtensibility\/issues\">issue tracker<\/a>. You can also sign up <a href=\"https:\/\/aka.ms\/VisualStudio.Extensibility\/UserStudies\">here<\/a> to be contacted about future user studies, which are invaluable as we work to give you the best possible experience with our SDK.<\/p>\n<p>Please go to the <a href=\"https:\/\/aka.ms\/VisualStudio.Extensibility\">VisualStudio.Extensibility repo<\/a> for docs, code samples, and setup instructions so you can get started today!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, we\u2019re very excited to announce the third public preview of VisualStudio.Extensibility, our new SDK for creating extensions for Visual Studio! The VisualStudio.Extensibility SDK focuses on extensions that run out-of-process from the IDE for improved performance and reliability, and it features a modern API that has been streamlined and carefully engineered to maximize developer productivity. [&hellip;]<\/p>\n","protected":false},"author":108688,"featured_media":241804,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1388,155],"tags":[294,12,6815],"class_list":["post-241795","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-extensibility","category-visual-studio","tag-extensions","tag-visual-studio","tag-visual-studio-2022"],"acf":[],"blog_post_summary":"<p>Today, we\u2019re very excited to announce the third public preview of VisualStudio.Extensibility, our new SDK for creating extensions for Visual Studio! The VisualStudio.Extensibility SDK focuses on extensions that run out-of-process from the IDE for improved performance and reliability, and it features a modern API that has been streamlined and carefully engineered to maximize developer productivity. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/241795","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\/108688"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=241795"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/241795\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/241804"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=241795"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=241795"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=241795"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}