 Hello everybody and welcome to this week's episode of writing extensions with Matt. That's me and As always we have our talented producer in the background He tends to change his name every once in a while last week. We had James and this week. We have John. Hello, John Hello, I'm the I'm the pretend. I'm the budget James No way man, don't tell yourself short I'm glad that you're here because today we have a really really great show and I know don't I don't know John Have you ever written a visual studio extension? I Have I have I mean very simple ones. I've done the little walk-through things Honestly, I did it a while ago and it was more complicated than I thought but I think it's gotten kind of easier over over the years Yeah, hopefully yeah It has like we I remember back when I was a program manager for the extensibility team on You know in visual studio We actually had some events where we where we pulled people and asked them about exactly that has it gotten easier over time to write extensions and Unanimously it was a yes. That doesn't mean it's easy. It just means it's gotten easier and It's kind of it's kind of a known thing I think everyone in the audience here that's watching live or if you're watching later on and you've tried writing extensions You probably thought oh boy This is hard How do I do anything that I want to do right and so We've been doing this show for kind of a long time now, but we've never gone back. It's okay Let's write our very first extension. What are what is an extension? Actually, how does it work? What are sort of the anatomy and and then let's just take it from there because I think if we get our foundation Right if we understand the basics of what an extension is and how we kind of get started with it and Then we know how to proceed from there And of course we have this back catalog of episodes of this very show that's gonna show you so many different aspects of Extensions you can dive into after the fact. So yeah, this is about bringing it all back to the beginning so In the beginning Feel like that's a quote in the beginning There was a an installer So john, are we looking at my screen? I can't we are we see your screen? Yep. Okay. All right So in the installer when you pop that up the visual studio installer I'm just going to click the modify button here Or if you're installing visual studio for the first time you're going to see A list of what's called workloads these different things are workloads and if we want to extend visual studio We need to go down to the bottom And put a check mark in this one called visual studio extension development So that's going to give us a bunch of tooling and project templates and so on to get started with writing extensions You cannot write a visual studio extension without this. So make sure you go grab it Uh, obviously I already have that installed actually just a question. Could you technically Build a visual studio extension without that. It would just be a huge ton of work Or is it? You can no, that's not yeah, you can technically you can do it, but you do not want to do it. Okay. Yeah So, um Where did my screen go? So we want to do another thing. We want to go and install An extension so after we've installed visual studio got the extensibility workload installed We want to go to the visual studio marketplace And install this extension And john if you can turn on that banner that runs Uh, just so that it's more clear what what it is. It's the extensibility essentials Extension it's an extension pack and it installs a bunch of extensions And these extensions are all things that help us as extension developers write extensions. It's very meta, right? You need you need an extension to write extensions You don't technically need it, but You don't want to be without it. It's going to have a lot of helpful things There's another really good resource. I want to just start out with and that is um a blog post on the visual studio blog so um, it basically just takes you through Sort of the getting started Um flow if you will and one of the things it does it links to a video from 2016 Where I go over like building an extension and so that's another way of building an extension But it's kind of five years old now It's still very good and I urge you to watch this afterwards if you want to learn more But at that time we didn't have the extensibility essentials extension so things have changed a little bit and um, that's why I think it's a really good idea that we kind of Do a new version of this right now But it kind of teaches you like different things give you links to to the right documentation and articles and so So make sure to check out that blog post as well and I'm going to put a link in the description below later so There's an interesting question in the chat Well, how this if this applies at all to visual studio code at all or if this is specific to visual studio on windows Great question. This is visual studio on windows only The three main visual studio products visual studio for windows which is studio for mac and visual studio code Are all completely different when it comes to Extensibility there are some similarities. There are something we can reuse but You know, uh, generally speaking, they're just completely separate Yep, so visual studio only So the first thing we want to do Is that we want to create a new project And i'm gonna just search for V6 vs ix So v6 is what an extension is called. It's called a v6 Um, and there's something called the v6 project so it stands for visual studio integrated experience or integrated extension, right visual studio integrated extension or ide extension So i'm going to create a v6 project I call my first extension and um We get sort of a kind of a basic Regular c-sharp project template going on here So let's take a look at Have what we got So it's a c-sharp project. So great news for all you dot netters out there This is the same old c-sharp that you know and love currently for writing extensions. We are Using dot net framework 472 Which can do dot net standard 2.0 right or 2.1 even is compatible with so if you have any Libraries or nuget packages that are written against dot net standard that works in a visual studio extension as well So We got a couple of nuget packages. We got the stk itself So we no longer have to download the stk as a separate installer as we used to back in the day It's now just a simple nuget package. It contains everything that we need And then some build tools and that's kind of it and the build tools are for c9 for ci purposes We don't actually need them when we have visual studio because visual studio is doing the builds for us But in case you don't have visual studio installed on your ci machine You can just use ms build directly if you have this nuget package We also have A v6 manifest file. So let me open that So this is where we keep the metadata of our extension So this is the description the name the icons The author and so on and so We want to give this a good name, right? My first extension. Let's just keep that name. That's kind of nice We get a nice goo it in our prior id. This is super important that we use something that's unique We don't need a goo it in there You know as long as it's unique and no one else in the world has taken it then we're safe So that's why a goo it is by default what we see here But it could be any string Short or long it doesn't matter And then we have our description and you know, there are some best practices here And of course you want to have a good title and a good description Um something that describes the benefit of your extension And so it's kind of important that we When we think about extensions that we think about how do we sell the idea of the extension? Right. We want it to be something that Other people would like unless it's just for us, right? But even if it's for our team or if it's for internal use in our company You know, we want to make it look as good as we can. So a good description a good title And We got some tags. We got some other things. So one of the things we got is an icon So we should find a good icon Um, let's actually start with that. I like to keep all my sort of Resources in a folder called resources And that's actually an old naming convention That's what we used to have in the old project templates on visual studio We would we would have a resources folder and it kind of just stuck with me. I kind of like that You can call it whatever you want And part of that extension I was talking about the extensibility essentials Is the known moniker's explorer so We get in visual studio almost four thousand icons that visual studio ship with that are under kind of a license That allow us to redistribute all those icons. So I can just find any icon I want here. Let's do What should we find something about uh, I have a search box here so I can search for Save let's say and I get save icons say yeah, I like uh I like to save icon. I'm going to double click it I'm going to give it 90 pixels 90 by 90. I'm going to export this out of visual studio and into my Uh first extension Into the resources folder like there and we're going to call it icon.png Now I can go in here right click and say include in project And after that I can select it from this list under icon And preview image preview image is actually not used anymore, but I like to just fill it in anyway And lastly, we just need to Make sure that our new icon has this property set correctly called include in v6 equals true Include in v6 that means that we want to package up that icon into our visual studio extension Okay, and that's a perfect segue because what is an v6 actually So let's uh Open our bin folder And it's empty. We have not compiled yet. So let's compile. So here it goes And we can see even now we have a bunch of stuff right here in The bin folder and one of them is a v6 file A file with the file extension of dot vsix. That is an extension And it's actually just a zip file. So if I right click it and I have uh like a unzipped or installed I could just open it as if it was a zip file and I can see what's inside of it So We have our dll file. That's just our project rc sharpcode compiled We have our v6 manifest that was this file that we were editing here, which is just an xml file And we have our icon because I made sure that include in v6 was set to true, right? So it gets added to the v6 like this And then we have some things that are automatically generated for us like there's four things that are generated We don't really have to know about them right now The only thing we want to know about is potentially the package def file right here But the others we don't actually ever interact with they're meant for other things. We don't really care so That is the what that is what a visual studio extension looks like when you pop it open and um So let's see here. So I think we have we have a good starting point right now Um, our extension doesn't do anything. It doesn't do anything at all Um, it does have a c sharp file though my first extension package Okay, so let's just take a look it comes with a bunch of Comments I want to remove those You got a keyboard shortcut. Oops lightly build a visual studio Kiss me all sorts of errors here. So I just removed all the comments I'm just gonna I'm just gonna remove some of this stuff. It makes it kind of easier to understand Um, I'm gonna move this goo it Up here again just to simplify so that we can better See what's going on. Here we go so I have a what's called a package so A visual studio extension the most common visual studio extension is what's called a package file and it's basically Something that describes how What are the different Commands or buttons or UI elements that we want to include that if you want to include some settings under tools options, for instance That's all kind of defined from in our package It's also where we can start something up. So if we want our extension to do something automatically when visual studio starts up This is where we define that our extension should be automatically loaded So it's kind of a starting point, right But this one doesn't actually do anything We have to override a single method called initialize async and All it does is this switches to the main thread So when we're dealing with visual studio extensions, we have to be a little bit aware Of threading. Are we on the UI thread? Are we on the background thread? but lucky for us The sdk ships with a bunch of analyzers So if we go check that out under references Oh, I can't even see that. Oh analyzers here we go. We can see it actually shifts with some analyzers here that are really handy Here visual studio sdk analyzers and threading analyzers And that kind of helps us uh steer clear of some of these um Threading issues that we might face So a lot of people are not accustomed to writing big desktop apps, right? Like wpf of windforms where threading can become really complicated when you have a large complex application And that's exactly what visual studio is right? It's a large complex application. It's probably the biggest I'm pretty sure it's the biggest uh wpf app in the world And so a lot of things are going on and we're now injecting our v6 our extension directly into the running code Into that process that runs visual studio So uh threading becomes a thing we need to be aware of That sounds maybe complicated or something that's scary. It's really isn't it really isn't all right, so Let's make this extension actually do something So john should we do a command or tool window? I'm thinking tool window I like tool windows too. It's neat to have something visual. Yeah, so let's do a new item And i'm gonna go under extensibility and click that And we have we have a async tool window and a tool window Okay, those are our two options The difference between these two is ha ha one is async and one is not But it's actually that the tool window is kind of the old An old way of doing tool windows and the async tool window is the new way of doing tool windows And so if you want to support the latest version of visual studio only like visual studio 2019 That's what today is the latest then you want to do async tool window Async tool windows didn't exist in older versions of visual studio So we're going to do that and we're going to call this uh my tool window So we're really creative here with our naming And add that and a lot of things are going to happen here. This is a very fancy Uh item template. It's going to do a lot of things for us. This is not your Typical template. Just check this out just see this so it added Let's just zoom in a bunch of stuff over here in solution explorer. So what did we get next to our icon file? We got What looks like an image sprite of six small icons in like an image strip here Then we got a vsc t file. Okay, that's weird. I've never heard of that before um We have a tool window and then we have a command and then we have some saml Okay, so a lot of things happened Um, but that's not everything that happened. It's not just that it put down files Um, if we look at our package You can see something here happened it said My tool window command initialized async Okay, so it wrote some c-sharp into my package class That's kind of interesting. So my tool window command we have that right here My tool window command again, I'm going to just remove the comments We see a bunch of stuff going on. Okay We're going to return to that for a little bit But what I want to show you here is like a command is basically a button Right, it's any a button inside visual studio any of these things up here In in the context menu anything you can click. That's a button That's a command And so any command is a is a good and an id Okay, which is an integer Uh, so a good and an integer pair Is what is sort of the identifier of a command But let's open that weird vsc t file This is a xml document and it describes the ui elements the commands the menus That we want to add to visual studio So check this out Here I have a button Okay So I declaratively define in this xml file Um, the definition of my buttons Of my commands That means that, um The source of truth of what visual studio will believe the command is is defined in here and The what kind of format is that there that looks like is that like xml ui stuff or is that kind of its own custom? Yeah, good question. Um, this is its own custom. This is a data representation of The of a command table that you're going to provide visual studio with so vsc t stands for visual studio command table Okay, and It's it's just data. It doesn't describe the ui except it kind of does sometimes Uh, a little bit because we have to be dealing with images. So for instance This button here says that it has images just like you can see that we have images right up here A bunch of these commands have images associated with them. Where do we go? Right here. So it does describe the ui a little bit, but it does so in a way that's um I don't know sort of data like we can't control the images. We can't control how they show up It's just what image do you want to associate with your command? That's kind of what we're doing here Like as I said, we have a good and an id okay And then we have a parent because where does that command live? So in this case, it's kind of a cryptic cryptic name here window other windows, okay And in that case that's actually view other windows somewhere in here So that's going to go in here into this menu is where we're going to put our button into other when What's it called other windows And we should call it my tool window like this So as I said, we have some images and they're defined down here Everything has to be defined by GUIDs and IDs and You can see these GUIDs here. Let me zoom in a little bit These GUIDs right here Um, if we look at our image we could see that we had Can I open this in visual studio? We can see that my image here? My png is basically one two three four five six individual images 16 pixel by 16 pixel Okay And I then define them like this. There's six of them I can give them whatever name I want and then just the order when they occur and that can then reference those Up here So give me the good images and give me with id number one bmp pick one. Okay So the first image in this case, it's the first image in our image strip And then I import the image here from uh from the file system like this So that is how we used to do a lot of the, uh, how we brought in images in the past Today, we're going to do it a little bit differently Because visual studio actually ships with a lot of icons just like I showed over here, right? So I can include Hop in the top here include What's called known monikers? Known image ids like this I get full intelligence for this so it's kind of easy to just fill it in And that allows me to do Something else instead of using those images. I can use any of the ones the visual studio ship with And that is a good thing The more native we can make our extension feel to visual studio The more seamlessly it will integrate in and the user will just use it like any other feature of visual studio Right because it looks the same it behaves similar. They expect certain things and so one of those things could be about Icons that if you have a save button that you use the save icon that they know In visual studio, right We had a question come in if if there's a list of those ids somewhere so we can find them yes, um, so the list of the ids so if you well Yes, so if you want to find for instance the parent where to put the parent stuff That is uh, you get full intelligence for that So you can kind of search. Okay. I want to do something about Tools Okay, so here's a bunch of stuff that has to do with tools. It kind of filters to that So you can figure out. Oh, there's a toolbar has to do with actions or something like that So there are ways to find that You can also go to view or the windows and What they call command explorer Let's see. So this is where we list all the commands that are in visual studio So this is a very long list, right? So there's like thousands and thousands of commands in visual studio That you can listen to by the way you can you can extend and you can get in before they run or after they run and do some more work so so they're kind of nice to find and Some of them we can see what groups they're in but I'll look up here guid and id so we can just find the The exact one we need for instance, uh, there's save all Well, let's save all This is the guid And here's the id Okay, so they are Uh, they're kind of easy to find It can be hard to find out exactly the parent window like I showed in here or the parent menu to put things in but It's doable Okay, so let's say I want to use that save icon again, right? So I want to go in here and add a command flag to my button and say Icon is moniker That's something we have to do now because Since we can do both we need to like help visual studio find out Whether or not this is an image on disk or it's an image from the visual studio image Library that we're using we're going to use an image library one And I'm going to use the uh, so that means we need to change this guid Because this good here points down to this good here And we don't want to use these anymore. I'm going to delete them like this I'm going to delete Our bitmaps here as well And so now if I go in here, I can just write good the image catalog do it Image catalog that's where I want to go. This is the visual studio image catalog And now I can just say save Save all or save Just do uh, let's do save So that's how I now put an icon on my um button here And it's kind of interesting that it's called button because it's a command Right. It's also a command Okay, so I'm no longer using those bitmaps. I can also delete them from solution explorer over here Let's just get rid of those bitmaps. I'm using the build in ones Making visuals making my extension feel like it belongs natively in visual studio instead of using custom icons, right? okay so A menu a button is created a command is created using a guid And an id and so if we go back to that command Now this is the class that is going to handle whenever people invoke that command. So when people click the button And this is the same guid and that is the id of that button that we just defined in our command table xml file So that's kind of nice. So let's just see exactly what happens. So When we call initialize async in our package Um, we all like we now call initialize async on our two two window command So if we just go to definition on that we go back to that class We're just in under initialize async And in here we do something interesting. We make sure we switch to the main thread If we didn't we get an analyzer that tells us that we should do that. So let's just move on Um, and here's something interesting. Now. How do you interact with visual studios build in? Uh extensibility points well, one of the most common things that we do is that we request services visual studio is built up by tons of services each doing various different things We can write our own services as well and expose those to other extenders if we want to So yes an extension can extend another extension to visual studio, right and doing it through a service It's just one way to do that so We can now figure out what uh, so here we're basically requesting a service um get service async We're retrieving that And then we're going to new up an instance of this particular class. We're in a static one So we're just going to new up a new tool window command. So let's look in the constructor We have that right here Yep Got another question that came in is how do you avoid id collisions between different extensions? Do you need to worry about that? You don't because well no Theoretically you can you can feel that you should worry about that but since Uh, since there's a good involved It is I don't think it has ever happened in the history of anything. Uh, so So no don't worry about that if you fork another person's open source extension Then maybe you want to change the goods. Um, you definitely want to change the package good Um, yeah change the goods if you if you if you want to fork an extension And you want to release it out to the marketplace where all the extensions are there to make sure that you update all the goods But other than that now because because there are goods, you're not going to see any any If you just say file a new project that good will never be the same as an existing good I hope that answers that question Okay So in our constructor that we just called we're passing in our command service Just checking for null But here's what we're what we're going to do. We're going to basically hook up a command id pass it our good And our integer right are good. So this we're now saying hey I'm creating a command idea you and this is so that I can now start listening to when people click That particular command with that good and that id that integer that pair Then I'm going to create a new menu command Where I pass in my command id and then I pass in A delegate to the code I want to execute when someone clicks my command And then add that to the command service. Okay, so simple enough Execute let's go down to the execute method. Here we go and what this does Is that it starts running something asynchronously So when you click a button It happens on the ui thread because the button is literally on the ui thread as you click it right? It's a ui event so You are always on the ui thread down here when the execute is being executed and So if you want to do something that If you don't want to block the ui Which you don't you don't want visual students to be unresponsive or frozen for the for whatever logic that you're running Right, it could be a long running task or whatever You want to jump into a background threat and here's the way to do that Can we we use here the joinable task factory that hangs off of our package To be able to run something asynchronously and in this case We're going to show a tool window We're going to show my tool window Now that's the type that we have out here. We haven't looked at yet So that's kind of nice. So show show this tool window asynchronously Okay, so this should run automatically And let's just see if it does okay, so i'm just going to set a breakpoint i'm also going to set one in here And let's hit f5 the way that we Debug and run our visual studio extensions is like any other dot net app console apps or wpf for whatever you might do You just hit f5 Most of the time when I don't want to debug I always hit just hit Control f5 so that means you don't attach the debugger because when the debugger is attached The visual studio version that now shows up here. You can see it's loading It's going to slow down significantly when there's another uh When there's a debugger attached to that process that kind of makes sense, right? So I only do it when I want to debug so This is a very special version of the visual studio of visual studio It's it. Well, it's the exact same version of visual studio that you have But if we look up here in the corner, it says exp That stands for Experimental instance So this is the experimental instance Of visual studio And just means that it was started visual studios. It's just started with a certain command line argument passed to it and It uses a different place in the registry it uses a different Place on disk to store all the settings and so on so that it doesn't interfere with your regular visual studio Okay So in here if I go to extension and manage extensions As I said, everything is a little bit slower and we go and look at the installed extensions here You see my first extension with our icon has now been loaded Right. It's been installed into this experimental instance. You can see I have a bunch of other Things because I work on a lot of extensions, right? So my experimental instance is full off of extensions and that's cool because They don't necessarily I don't necessarily have them installed on my regular visual studio extension Or sorry my regular instance of visual studio. They're only in the experimental instance So that's a nice way of we get that for free, right? Um, okay, so my extension is there That probably means Oh, I want to I want to set another break point want to set a break point in our package class In our initialize async method So if we go to view and other windows, we should see a My tool window command All right or button So if I click that You see here that first My package is now initializing. Okay So what happens is the visual studio whenever it starts up and I Haven't explicitly set to auto load my extension, which I haven't done here, right? It will not Initialize it will not load itself Because that would be kind of silly. Why would visual studio load an extension that hasn't been used yet, right? So the first time a command is being used That's when the package class is being initialized by visual studio and not before So now that runs And we can dive into this we can you know, you can just step debug like we can any other App I'm just going to hit f5 to let it run. Okay, so that we catch it in our execute method Because that's what we click we click the button, right which Then triggers our execute method here And we finally we get into our background thread And we can now execute that I'm just going to hit f5 again to kind of keep it going And boom we have a tool window Look at that Click me. All right And we get a little button. So now We have ui and visual studio and this is a tool window that you can put anywhere you want You know, that's a really cool part like you do have to do some work to wire it up But it is a real full tool window. It's stockable. It's got all the kind of like stuff that people expect Exactly. It's like it's exactly what you would want As a starting point, right? It's it's actually really really nice And let's just take a look. So I'm just going to leave it open So wherever I leave it, I'm going to leave it here next time you open We'll see that it's probably going to be in the exact same place actually I want it there So smaller like that And I can just Close down the experimental instance and go back and continue my coding, right? so um, you'll notice something that happens quite a bit And that is that Um Attributes get added to our package class whenever we do something So when I added that tool window from the item template, I said add new item async tool window It also wrote this on top of my Package class it says provide tool window Okay, so that's an attribute that when I compile It writes it down to this package def file that we were talking about but didn't look into so This package def file i'm looking at the bin directory, right? This is our v6 So let's just open i'm going to drag it in just open it up and we can see what that looks like We can see here tool window This is exactly what that attribute does it produces it produces This little bit piece of of text three lines in our package def file Okay, and we don't have to worry about any of this. This is automatically generated when we build this package def file. It's being updated Just to prove that i'm going to delete this and just Go here and hit build I hope i'm right Let's see we should get that and boom it's back, right? so That's super nice. Um, and we we don't have to worry about that set a cryptic File we just put attributes on and the cool thing is some of these attributes we can actually Uh extend here Okay, what's the height and the width of this is it? What are the different aspects we can see what about the orientation? See here, what can we give with that orientation bottom left right top? Let's say orientation left That's kind of nice. We as a style Equals doc style and we usually do want a floating window. Do you want it linked or tapped? You know, so depending on what where you kind of want to what you want to do you can do stuff like this So customize these different things all in C sharp. So very handy Okay, let's take a look at our tool window because that's what we were executing, right? We said Show tool window async and we gave it the the type of our tool window. So I'm gonna F12 to go to definition on my tool window and I'm going to remove the comments again control kq And um, so here we go So this tool window it just inherits from a tool window pane and then That's it. It doesn't really do anything you give it a name. You can give it other things Like I think there's a icon or what they're called moniker It may be image moniker So if you want to give it an icon, let's say known money curse dot Save it was save right that icon we used That's the save icon We can give it that and now we and I'll show you where icon so all two windows actually have icons, but Not that many people know about that. I'll show you how you can how you can See them And then we just new up Your content this is an object This can take windforms and it can take wpf like a ui framework element, right a ui element It could be a button. It could be a A SAML file like in this case. It's a regular SAML file. There's nothing special here whatsoever. It's just Wpf SAML There's a little bit to be aware of when it comes to like visual studio brushes and so on to make sure that we use the right colors and theming but that's That's a different show than this than the beginner show on how to like look at theming. We do have an episode where we go over that So make sure to check out the back catalog of of episodes here But that's all it is right. So that was my SAML. Let's look at the code behind And all we did was we called the message box that show you remember what it did, right? It came up you click the button inside the tool window and you just had a message box and that was it Let's see him Just going to start it up again and we can see How the tool window now starts with visual studio It's right here Where we uh where we left it, right? So it stays in the same place And if you click it, that's the message box that show that just comes up right here All right, so let's figure out how we can see the icons Huh, let's see if I can even remember how to do it I want to do this Let's move this over here Oh Gonna move it here And um, let's resize this window There we go John, did you notice? See these two windows now are down to their Ah Nice There's an there's an extension out there that does it so that by so that they always just have their icon instead of their full name And it it hooks into some windows apis and stuff it does some some I looked at that code and it's like oh, that's kind of some advanced stuff And that's really cool because when you think about what this is it's just a wpf app running on windows So anything that's true From another windows app or any other wpf app Is true for this as well So you can like walk the tree of wpf you can change whatever you want you can hook into windows apis and do certain things And that includes you can do anything that you can and see sharp So whatever trust level visual studio is running under Like are you running visual studio as an admin? That means that your code can now run in that use in that space, right? And you have admin privileges Uh, but if not then you don't so for instance, you cannot write to this to the System drives for instance here unless you're running visual studio as an admin So as an extension author, you have to be careful about that Make sure if you want to write to files or whatever write them in user space like under the user profile somewhere Under the my documents folder or something like that and not in the visual studio install directory For instance, you're not allowed to do that unless you're running as admin Do we have any questions here that I missed john? Uh, I don't see any more No, people people are happy with what you're building and But yeah, no no more questions since since the ones about ids Okay, so I think we have a pretty good extension. What do you think? It's maybe the best extension Um, we could show something maybe more interesting in our Uh in our uh dialogue here. So why don't we do that? So in our tool window There we go Why don't we There we create here's the tool window. Here's the tool that I've created So can we go in and request a service? When you click that button, let's see if we can do that So I want to just when instead of just showing uh something like invoke this method in my message box I want to show the version of visual studio we're running So i'm going to request um Something called the dte So this is like the design time extension automation object or something like that and here I can say uh service provider Dot global service provider dot get service and i'm going to get Myself the dte. So now we're going to consume a service. Okay. It's called dte like this And we're going to cast it to dte like that So this is an object that's really handy to know of when you are new to extension And I'll show you why in a second. Notice these greens quickly It says I don't think I consume and well, maybe I consume and hover at the same time. We'll see Can you see that? Yeah It says accessing service providers should only be done on the main thread Called microsoft visual studio shell thread helper dot throw if not on ui thread first And the cool thing is there was a light bulb Yeah, it says add call to this boom done Okay So we're getting a lot of help from our those analyzers I was talking about so threading does not seem that Uh complicated now does it? Those analyzers are so cool Uh, just the whole way that works that they analyze your code and they they're looking at as you're typing and recommending stuff We had a question from riccardo is if um, should I call all services in the i async? In initialize async or just as I need them Uh do it as you need them That's the that's the best call like be lacy We want to make sure that we put as little stress as possible on visual studio at any given point in time So don't do things up front Do things while as you need them like lazy loading if you will So the thing about extensions is that if you're not uh being cognizant about Being sort of a good citizen when it comes to performance and reliability Uh, first of all people are going to uninstall your extension faster than you can count to three Uh, but secondly like think about visual studio users. They actually sit in visual studio eight hours a day or something like that That's their you know What they do and so even the small things like typing delays that like just delay typing by like milliseconds Uh can be they can notice that and be annoyed So we want to make sure that from a performance perspective. We are as late as possible What's really good about buttons is that from you click a button Till you expect to see something happened You know, I think it's like a hundred milliseconds or something like that before you're like Before your brain even picks up that something happened And getting a service like i'm doing here takes like no time at all, right? So um So if you want to be if you want to do lazy loading do it on button clicks where people invoke your command directly Because if that takes a little longer, it doesn't really matter because users Did something specifically and they're okay taking time Whereas if you they're just typing in the editor and you have some sort of Logic that runs and every time a character is typed then You're probably not doing them a service, right? They didn't want to explicitly call your thing your feature when they do that so, um That's why like be lazy on those button command clicks instead And load is loaded as late as possible. Now. Let's take a look at this dge So this is basically Actually, i'm gonna cast dge is dg2 Okay, and I probably have to add a using statement here for that to work So dge is like the first version of dge But then we have dge2 which actually is kind of old now, but It gives us even more good stuff. So if we look at what's in here, we can see we have a long list of all sorts of things We can look at the active document what's currently loaded in the document. What's the full name? Um all sorts of things what's the language? Like programming language and so on so we can really like in a single place inspect So many different things and hook into all sorts of events Because there's events in here, right? Or do you want build events? Or do you want document events or debugger events or command events? Okay command event. Is there something before execute after execute? I can hook into any Google it into your pair right a command pair And say before this command normal command is executed execute my code first All right, so you can really come in here and do a lot of things and that's the dge Some people say that the dge is easy to abuse it's um It's not necessarily following the best practices and that is to some extent true but it is the Easiest place to get started And we can always hone our skills afterwards But oftentimes when you start out you just want to get something up see it work and get your success experience And feel good right and then we can always optimize later So the dge is a it's a super good place to start um So i'm gonna update this I'm gonna say message box show and I want to use the dge dot version version Okay So the version is just the string that says what version of visual studio are we dealing with And um that might be also something you can use in your code, right? What bill there's I can't believe it Oh, I already had visual studio experimental instance open. Oh my so here's what happens This is the experimental instance, right that we just said I never closed it So it was still open here, but there can only be one because Uh, what happens is that when I build my extension Let's look at our project property pages here So when I build my extension see v6 It says deploy v6 content to area to experimental instance for debugging It's by default checked So what happens is that when I build control shift b It deploys that v6 that i'm creating in my bin directory into the experimental instance of visual studio But it requires that experimental instance not to be running in order to do that So my build will fail And so you're going to see this time and time again. I do this uh very very often I forget to close the experimental instance. So now you know why so if you ever get that error That says hey problem occurred while you know can't access the file and then some Long path here make sure your experimental instance is closed and now if we build again I might have to do a rebuild, but let's see It worked just fine, right So That's just a kind of a good troubleshooting tip That uh, you you're definitely going to run into and you're going to run into it many times So now we're running back up again here. And if I click this we can see we're running on version 16 And so that brings us to another interesting thing about visual studio The internal names of visual studio is the version that we as extenders Are using so as an extender you are not thinking about visual studio Version 2019 or 2017 or 2015 You're thinking about visual studio version 16 15 and 14 Because that is the number that is the verse that is the actual version of visual studio The the whole thing about having 2019 after that's just a name That's actually not the version number. So internally In microsoft on the visual studio team, we refer to it as visual studio 16.0 16.3 if you have the third update for instance, right? And if we look in our V6 manifest file, I'm going to show you that here again We can look at install targets And check this out I can define where my extension applies to what version of visual studio my extension applies to And it actually says here 16 comma 17 and visual studio community So visual studio community is the lowest. It's the free one of visual studio It's sort of the lowest one Then we have pro on top and at the very top we have enterprise Those are the three versions of visual studio or the three skews of visual studio And so if we say that our extension works in community then By default it also works in pro and enterprise But if I say it only works in enterprise it will then not be able to install on pro or community. Okay And then comes this whole thing about the version range. I'm just going to double click this or click edit here Let's talk about this Um This is kind of weird right 16 And 17 so I have a square bracket that means From and including version 16.0 So that's the very first version Of visual studio 2019 is called 16.0 The next update would be had been 16.1, right? But 16 zero that means all versions of visual studio 2019 All the way up until version 17 But not including so the parenthesis means not including whereas The square bracket meant including so From and including 16 To but excluding 17. So that means All versions of visual studio 16.0, you know 999999 and so on But not 17. So Visual studio 17 doesn't actually exist Not yet at least by the time you watch this video, maybe it does but not right now So that's how we can uh, this is all versioned And this v6 manifest i'm going to hit f7 to go to code or right click and say new code It's actually just an xml file like this So that's all Um, so now we have our extension The last thing we want to do is We want to go to chrome. I'm just going to go in here to the Marketplace and then bring it back here So here is my uh, I logged in I create a create an account on the visual studio marketplace like marketplace.visualstudio.com And here's a list of all my personal extensions. Let's say you want to You're happy about this extension that we just built. It's right here. You want to upload it notice here It's 64 kilobytes And I it's in debug. I want to make sure that I compile this in release mode So let's go ahead and do that change to release Hit the build So in debug mode is 64 kilobytes. Let's look in release mode It's 54 Oh, that's interesting. So the difference here is that in release mode this v6. It's a zip file, right? It's actually Compressing the contents that's within it Whereas in debug mode. It doesn't compress. It just puts things in a zip container without sipping it without compressing it So I want to make sure that I use the That version Okay, so I'm going to create a new extension for visual studio And I can upload it right here My first extension Continue so now the visual studio marketplace is checking for Am I adhering to some best practice and all in this case? We're doing just fine. It can find the icon First thing it wants is to want to figure out. What should the unique name be? So on the marketplace it has a URL for all extensions and you get the opportunity to define what the last part of that URL should be um Also, I want to check like so two extensions can have the same name, right? So my first extension. I don't know if one is called that We should then give it some content here. So my first extension, I don't know if this is enough. We'll see we can see oh we can uh determine what category should this be and let's say that's uh about performance And tag here could be something like a message box This box why not, right? We can tag it we can put in our github URL down here um, you know github whatever our repo is And uh, we kind of want to do that because if there's any issues if there are any feature requests or whatever They can come directly to where our source code lived instead of on the marketplace itself So now I think I'm happy. I'm just going to click save and upload and I'm going to sort by updated and we can see it's in the top here. So now the marketplace is going to verify our extension and so by verifying means it's um It's basically checking it for like security issues like for instance, is there a zip bombing being used like are you trying to Hurt the marketplace website here. Do you have malicious intent, right? So it does that and it kind of does things in like a detonate detonation chamber to uh to make sure that That everything is fine. That doesn't mean that your Code can't do some bad things because you just run on the same trust level as vision studios being run, right? so you can access things and And do things, but of course that's really really bad and um So this will this is going to take a little time So let's just say when you it's fully uploaded what you want to do is that you want to go in and click a button That says make public So right now on one of my other extensions. I have one called make private Because it is already public So if I make tweaks private here Yeah, let's just make it private. So I just took that down from the marketplace. No one can now upload it or download it And I can say make public like that. Are you sure? Yes So by default when we upload a new extension, they are private. Okay, that means no one else can see them You have to be logged in as the same user that uploaded them to see them and so That's just to make sure that we didn't We want to double check that it all looks good and so on and so now my extension is up. I'm probably going to delete this again just So that it's not out there But that's it. We've now uploaded our extension to the marketplace and I think we got around to showing a good Good start here. Do we have any questions from the live audience? We don't which I think means that you're covering things really well Yeah, no, it's good. We've got we've got over 60 people watching and it's and people are liking what you're doing Um, definitely do ask questions in the chat if you have any Yes, um, I shared some of your blog posts like for instance, uh a blog post on On understanding the version number ranges and stuff. So good. Yeah, that's a really good blog post that shows that Because that's a hard one to understand and so that would be a good one to read. Thank you john So I hope this de mystified water visual studio extension is and hopefully Inspired you to kind of take a deeper look and maybe get your first extension out there Um, you know, I'm sometimes asked about You know, and you probably maybe I thought of this, uh, john like well, what extension should I then build? Yeah, what are some good ideas and the way I think about it is, um It would be cool if That's always been my thing, right? It would be cool if Anything it would be cool if I could make my workflow simpler It would be cool if I can take this repetitive task that I do often in visual studio and automate it It would be cool if I found like a bug or an inconsistency or something that's unconvenient in visual studio And made something that made it super easy for me to move around that um Another really interesting thing I think is to go to the developer community So, um, if you go to visual studio Send feedback report a problem. That's one way you can get there. Then you don't have to remember the url And then just go to explore feedback click visual studio here. Uh, let me see. I don't see that on your screen. There I wasn't sharing it. It was on my second monitor. Uh, okay So let's let's just do that again to go to help send feedback report a problem or my feedback here whatever my feedback And you can then see here, um, we can go to explore feedback visual studio And then you can see all sort of things including like shows feature requests Okay, what are the features that people actually want and only show me the ones that are open So not the ones that we should studio. It's already closed and fixed and you can see here. Boom. Boom. There's a lot, right? And so next page you can just go through And so this is a great way to find inspiration to what you should build Uh, it's one that I use all the time And so, uh, I can highly recommend going through here if you I'm not sure or you don't really have an idea of what you want to build And that's actually true of whether or not you're brand new and you kind of just want to try it out Or if you've done this for many many years, this is a great resource to to go through Well, you're showing online resources Is there a good spot if I get started trying to build something and I get stuck Like if I have questions build in an extension, where should I go? Yes, um, so there is a There's a forum Let's see. Do I hear gitter? I am so a really good place is gitter I am Slash microsoft slash extend vs that's sort of a chat room for extenders and there's also a microsoft employees on this every now and again And um, this is a good place Nice one place to hang out Stagger overflow is another Interesting spot. There's always twitter and so people can also just reach out to me on twitter And I might be able to send you to the right location But the number one Thing when you get stuck Is to ask the right question And I I think i'm here know how to search for help This is uh, super duper important Because Um, it can be very hard if you don't know When you're new to visual studio extension development, you don't know what you don't know And so how can you search for help if you don't even know what the name is of the thing that you don't know exists right So go through this, um This, uh blog post Make sure you don't skip the introduction which you haven't because we just had one here. So that's good on this video But the more you know about sort of the aspects that's a package. There's a command. What are these things called? Okay, I can get a service. What are the services available? The more precise you can get the better your search result better your google foo will be um, one thing that I found incredibly Useful is to if I know what the type is So for instance when I say type, I mean Um, we're dealing with some types here like the dge or dge 2 for instance, right or service provider. That's a type um, if I do this or method call like dge dot, um Active documents. Okay. What what what can I do with this or why doesn't it do what I think it does? Go to github and search for and you can see how other people are using it I found that to probably be the number one best resource For getting myself unstuck is to basically see how other people are doing it Can can you just show an example of that in the browser? How you do the search just in case people are Absolutely unfamiliar go to github.com Uh, let's see if I can find something a little bit more meaty here uh active solution projects search get up Okay, so that was a very bad example DTE dot, okay, I'm just going to do active document. Let's just do that one Maybe no one used the other one. So that's another interesting thing, right? All of github or they don't do dge hang on Okay, not to dge Oh, I have to sign in right right. Yeah, this is annoying. Okay. So that's that's annoying. So let's do it here. I'll I'll do it on uh Okay, so it probably worked just fine just before so let me just pull in i'm signed in here on this window So let's do that again DTE dot active document people might not call it DTE So I have a thousand things here showing up I'm just going to get to C sharp Okay, and here's one right from uh, this is an extension context menu command click it. How do people do this? Um, you know find other extensions. That's great So this is this is your go to it's really really handy What what neat trick I like this is an open source or it's a community thing but click on that link that you were just on And in the in the url change At the end so make it github instead of github.com make it github one s dot com This is just a quick way for navigating. Oh, yeah. Yeah source. Have you seen this? I have it's it's kind of fun I mean it's Yeah, so it basically opens the monocoe editors or the ds code editor To that file Yeah, so a nice kind of quick way to just browse it in context a bit. Yeah, that's awesome cool Wow, well, this is a ton of information and I always like You know that like the getting started is great But now as people get started you'll hit your first bug and knowing what to do next is really good So I love that you cover that in your blog post and then talked a bit more about it here And actually I want to I want to push a book hang on So this is not my book Is it written by someone else? And uh, it's available on any uh in any bookstore near you I guess maybe online And uh, wherever you go to buy your this was to do extensibility literature. You can pick this up And it's like it's basically taking you through Like super super easy way to go through it has code samples It has like a real world code sample that I love And uh, it expands on it makes it better as it goes along and explains all the different facets of extension development. So Check that one out for reals. This is good. This is I love this book So, um, yeah, we finally have a good book for extension development. So that's cool I I it might be neat some time today. I don't know Have you done contests in the past like create a new extension and give away a book or something That can be fun to see what people come up with. We should do that, shouldn't we? That's a great idea Is the end in chat I can't do that right now, I guess, um, but um, there's only one with this title Michelle studio extensibility development I reshop verma. He's a microsoft guy and uh, I've written some create extensions and so And this is very well written It's easy to follow along Trying to grab a link to it. I guess that's from a press, huh? It's an a press book Yep, i'm putting a link to the publisher then in the chat Excellent. Thank you Great Wow, well, I guess should we wrap up there then? I think so Thank you so much Yeah, do we have a show scheduled for next week? No, I have no show Okay, anyone, uh, if anyone has um An extension they would like me to review in one of these shows It's very friendly. So you don't have to be afraid of anything Then let me know I'd be happy to clone it down from github or wherever you host it and go over and see How we can improve it and maybe send you a pull request at the end of the show or something like that That's a great idea. Yeah, we've had mad lacy. We had one of his extensions early on and that's the only one we've had so um If you're interested hit me up on twitter or in the comments here on youtube or but twitter is better So please let me know Awesome. Okay. Well, I guess are we ready to play the outro music then? Let's do it. All right. Thanks everybody