 Hello everyone and welcome. Thank you so much for tuning in live today as we show you some of the new tools and features and services available to make it really easy to get started with DevOps for Windows desktop applications. My goal for you at the end of this session is that the next time you're working on an application that you intend to deploy to other audiences, your practices change from File New, work on it a little bit whatever to File New DevOps. It's really that simple. I'm Matt Corbel from the App Center team. I'm an engineering manager that focuses on diagnostics, code push, and helping developers make their applications as stable and reliable as possible. Great. So what we're going to talk about first is, why should you as a desktop developer care about doing DevOps? We'll talk about some of the flexibility you have in deploying .NET Core desktop applications. I think one of the questions in the previous session alluded to some of these things. Most of this session is a demo. We're going to do about 15-18 minutes of demos. Then we'll talk about some resources and what's coming in the future, and then we'll open up to some questions from the audience. So why DevOps? If you've been to other DevOps talks, you may have seen a similar slide. The gist of it is that developers who adopt best DevOps practices can ship code faster with fewer bugs and ultimately increase revenue and profit. So I feel like for the longest time, the DevOps discussion has been long neglected for desktop developers. It's been prominent and pretty much front and center for web and server application deployment, and even mobile apps. But for so long, there's never really been a whole lot of talk about doing DevOps for desktop apps, and that's why we're here today. When deploying .NET Core Windows applications, you have a couple of choices for how you actually deploy that application. One of the questions previously was, have you made it easier to create a self-contained application? The answer is yes. We have tooling in Visual Studio called the Windows Application Packaging Project that lets you easily create a self-contained MSIX package, including your .NET Core application and all of the runtime dependencies. In addition, you have options to target a shared side-by-side framework if you build your own custom installation technology, or publish a single exe. For the purposes of this file new DevOps demo, we're going to compile as a single self-contained executable because it's the simplest way to just get started, and that's what we're here to do. If you remember in the past, you may have used one of these USB sticks with your development team to deploy and test your software around the office. Effectively, what we want to show you is a 2019 modern replacement for doing those types of things. So with that, we're just going to jump right into the demo. So I've got Visual Studio open to an existing WPF.NET Core application, and the application that I'm working on is just a simple calculator sample application. Although some of my friends have been telling me that it's crashing and I want to figure out, okay, why is this crashing? So this code is hosted on GitHub. You can go look at this today, at slashdiverdan92 slash.netconf2019. If you scroll down, you'll see I already have the Azure Pipelines badge, but I don't have any build or CI setup. So let's do that now. So if I click this link, it'll open me up directly to this build. This is also public, so you can create public Azure DevOps projects to share the build information, the build status, even the build output and artifacts, and later during this talk, I'm going to request that some of you try and download my app and see if it runs since it is fully self-contained. We're going to create a new pipeline, connect it directly to GitHub, and because I've previously authenticated with GitHub, it'll automatically find my repositories. So I picked the repo. I'm going to start with the.net desktop build configuration, but I'm going to remove a lot of this right now because we don't yet have a.net core template that's coming. So the trigger will be master, and for those of you who are unfamiliar with YAML definitions, it's effectively declarative definition of what's going to happen when you try to create a CI build pipeline. So when the master branch in my repository changes, it's going to trigger a new build to execute the rest of these instructions. It's going to pick a hosted build agent from the latest Windows VM available in Azure DevOps, and I'm actually going to use.net publish later, so I don't need those two variables, but I will keep build configuration as release. The other variable I'm going to add is called .net skip first-time experience, and I want to take a second to explain this for those who aren't as familiar with DevOps. When you first install and run any.net core SDK command, it does some caching behind the scenes so that consecutive and subsequent commands will actually perform faster. Because we're building this on a hosted build agent, it's essentially a throw-awayable virtual machine. As soon as the build completes, the virtual machine is discarded, and so doing this caching at the beginning is actually just going to take a little bit of extra time for no value in the future, and so that's why we're going to set this variable. Then I'm going to actually remove these tasks because we're setting this up from scratch for.net core, and I'm going to use the Assistant to help me from here on out, which makes it a lot easier. So you'll see these Azure DevOps build tasks that I can configure and run directly through the Assistant. The first one I need to do is installing the.net core SDK. One of my favorite Azure DevOps tasks is the use.net core task, because you don't have to worry about what the state of the virtual machine is in so long as it has some version of some of the Visual Studio build tools. But because I can install any version of the.net SDK I want from this task, I can always essentially keep it up to date. For the first time, I'm super excited that I no longer have to select the include preview versions because we just released 3.0 today. So I'll deselect that and I will add this. So now I've got a hosted VM, it's a Windows virtual machine, and I know it's going to install the latest.net 3.0 SDK. The next thing I need to do is actually use.net. So in this case, I'm going to use the.net core command line to run.net publish on my application. I'm not publishing a web project, I don't need to zip it so I can remove all these. The last thing I'm going to do for the use.net core CLI command is add an optional parameter. So in this case, I want to add an argument, which you could have done through the interface, but I just prefer to do it here, and I'm going to specify the output of the build artifacts. So in this case, Azure DevOps has a pre-configured variable for specifying where the artifacts get staged. So I'm going to call this build.artifactstaging directory, and that's going to be essentially consumed by my next task, which is going to be publishing these binaries. So I've generated my self-contained XE at this point using.net publish, and the last thing I need to do is essentially host it somewhere to be downloaded later. So I'm going to use the publish pipeline artifact task, again using this assistant, but I'm going to specify the file or directory path to be again build.artifactstaging directory. Last but not least, I'm going to call this a more friendly name, so that when you download it later, it'll be a little bit more useful. Just like that, I can click save and run, and what this will do, so if you see here, there's no YAML file at the root of my repo, in my GitHub repository. When I save and run this, it's actually committing this YAML file directly to the root of my GitHub repo, so that it's persisted in source, and I can make edits through an editor or when someone else downloads this repo, they can host the build definition with the same artifacts that I have. So here you can see I have set up CI with Azure Pipelines, and now the build is getting kicked off. Now, while this build goes, I know I rushed through that a little bit, but I'm going to take a step back and explain things so that the build can run in the background. We have a couple of things that I want to call out in the project file. First, I'm specifying a runtime identifier, so that I can specify publish single file true, and that build property will actually make it so I have a self-contained single executable file containing all of the .NET Core runtime dependencies this application needs to run. So if anyone downloads this later, they can just double-click run it. It's pretty cool. One other thing I want to call out, we just discovered one bug in our preview SDK for .NET Core, where you need to manually reference this SQL library to get the runtime-specific native dependency for App Center to work. This is documented in our documentation, but should be going away soon, but if you're wondering what that's there for, that's what it is. So this is now in the process, it just downloaded the right .NET Core SDK, it's running the .NET CLI. So we'll just give this a couple seconds and we'll proceed after it finishes building. If you're viewing at home or at an event, go ahead and head on over to this GitHub repository. You'll see Azure Pipeline status is never built. It'll soon update to build succeeded. But later in the session, once we configure App Center, if you download at home and run this application, you'll show up in our live telemetry. Which I think is pretty cool. Just so you can see while this is still building, if I go here, Build Pipelines, when I click on the build, when it's finished, you'll see an Artifacts link in the top right linking to the actual dependencies. So this should almost be done. Give it a few more seconds. Then as soon as this completes, we'll configure for App Center, and then I'm going to hand it off to Matt to go into the details and the intricacies of App Center. So .NET CLI finished, I published it, it's got a link to the logs if I want, but now it's going to publish these Artifact files which should take just a couple seconds. Then I'll show you what it's like for you to download at home if you'd like. Finalizing, cool. So now that this is done, now you can see Artifacts calculator. If I click on that, you'll see two files, you'll see the executable and the symbols. So if you were to go home and download this and run it, it would work. But don't do it yet, let's first add App Center. So in the App Center portal, this is effectively the first view you'd see if you sign in. If you didn't already have an app, you'd be asked to add a new app, which we're going to do, we're going to do everything live today. So I'm going to call this .NET Conf live, and I'm going to make it a Windows release and WPF. As you can see, this is in preview. So not all of the features are available, but we're adding more and more every few weeks. So I'll create this app. The next thing I will see is essentially how to add this SDK to my app. I've already added these NuGet packages just to streamline the demo. So all I need to do is copy this App Center start line of code to an early code path in my application. For now, I'm going to do it right after I initialize the main window. So last thing I'm going to do is commit and sync because I've already configured my CI. This will essentially kick off the next build. Once this goes, I'm actually going to test the application locally just to make sure that App Center is working as I'd expect. So if I go back to the App Center portal and I select Analytics, I see there's no events. Integrate the SDK first to start collecting data. Let's run the application and see just how quickly those events get sent to App Center for you to view. Let me close this version of the calculator. So I can see my calculator running. This time I'm running it under the debugger in Visual Studio, and we'll give it just a few seconds and then we'll refresh this page. There we go. So just a few seconds later, I can now see that I have one user of this application. I'm not going to see any custom events or crashes because they haven't done anything in the application that would trigger some of those that I've added. So the last thing I want to say is, again, if you go back to my repository and I'm going to refresh it, you should see the Azure Pipeline succeeded. Click on it, go to the most recent branch where I added the Azure DevOps configuration and when it's done, go ahead and try and run it from Azure DevOps directly so we can see your telemetry live. Now I'm going to hand it off to Matt and he's going to go into more of the details for what you can actually do with App Center and how it brings more value to your customers. Thanks, Daniel. So with App Center, one of the really exciting things for me is the ability to kind of gather data from all my distributed clients and bring it into one place. So what we can do here with your build is I can actually take, and we can get rid of that old thumb drive, and I can take your most recent build, yeah, toss it out of there, and App Center has a Distribute Abilities. So with App Center Distribute, I can take your most recent build and refresh the page, make sure I go back to our latest build. So as this one that is now running with App Center integrated in it, when that finishes building, I'll go ahead and download that and distribute it. There's a work item in progress on our roadmap to go ahead and wire up these Azure Pipelines to App Center, so we don't have to do this intermediate step, that'll be out shortly. So in the meantime, I kind of want to go a little bit deeper on the App Center analytics and diagnostics that we have in the app we've been using previous to this, and then once yours is built, we'll go back and run through the process for the live app. So with App Center, we mentioned analytics. So right out of the box, we provide a good amount of information that you wouldn't normally see if you've passed out your app over that thumb drive. Active users, daily sessions, top devices, countries, languages, all kinds of details. Then there's a really cool thing here, events kind of in the server world like a page view, something like that, but you can go in and as a developer, I can code into my app any events I want and I can come in and see metrics on those specific events, which really allows me to start thinking about my app in a very different way than I have in the past. So under App Center diagnostics, one of the things that I can do that's really cool is, when my app is crashing, we have a couple of ways to deal with that. So if your app crashes, the user says, hey, it just died, I don't know what happened. We received those events here in App Center and we actually received two categories of events. So one is an unhandled exception. Maybe a divide by zero error, something like that in a calculator app, or a user did something that I want to know about, a network connection wasn't available, or they clicked a button without validating some other info. So we have handled and unhandled. So we'll see this related to what's in the app when we get to the live session, but for each class of event and we group those by version build, reason frame, meaning the spot in your stack that was your code that failed, and we give you some general information on how many reports there were, what devices, and we give you the rough stack trace. So in a handled error here, we can go into individual reports of that, and we can see exactly what, and this is information you chose to fill in through the SDK, exactly what the user was doing. So this user tried to divide nine by zero, one by zero, that's people are confused with how math works, I think, using this app. There was a very interesting number divided by zero. So as I go along, I can see a lot of those details. The other type is when the app actually crashes. So we can see here that the calculator app was aware that we divided by zero, but actually went ahead and crashed as well. So since we had a native crash, we actually provide the full stack trace of everything that was going on outside of your just your handled error in your code, and when we look at these, they do start to line up with the events that you're sending in the system. So if I go into reports on this app, and look at this, so I can see that the session started and then it crashed, they didn't get to any of the custom events that we had there. One thing that we haven't put into this demo, but I do want to call out is really useful, and I'm going to just for a second, flip over to an iOS app, because App Center has actually been servicing mobile at environments and mobile platforms for a long time, and that's some of the value that we're trying to bring to the Windows development world. So this is a test app we have, and so one thing that's really fun is attachments. So as a developer, if I want to capture other additional information about why a crash happened, and what was going on at the time, I can send binary attachments, I can bring an entire custom format of details about what I'd like to know, and some really cool things to help you figure out what's going on. Let's see. I can actually download the raw crash as it came in from the SDK, from the user's device without any of the augmentation that we provide, and really let you dive in. I personally like to think of this as a lightweight picture of what I would receive if I were debugging this at the time. So I obviously can't debug on one or 10 or million user devices out in the wild, but I can here remotely, and since we group those together, it really allows developers to say, I have an error in function X, that function might be called in a dozen different stack traces around my app. I can see that it's happening here, and it'll group those things together, and let me know a prioritized list of what I need to fix, and what I can maybe in order to go on. We also allow you to configure services, we haven't configured any for this, but you can connect directly to GitHub, you can create issues when you have new crash groups come in, you can create issues when there's thresholds on crash groups, and really start to take a much bigger picture of your distributed clients, and what they can do, and what you can do with that info. So let's go back now, and so we saw that your calculator was crashing, I actually want to use AppCenter to understand why, run it on my machine, and let's see if we can get it fixed. Sure. So I believe this is the latest build. So I'm going to go ahead and make one manual step here, download this file. Like I said, we have our roadmap to ship this, so this is an integrated step. It is now for iOS and Android, Windows is equal partner on AppCenter platform now, and so it'll be shortly there as well. As I download that, I'm going to go ahead and go over to our newest app, and I'm going to go to Distrib, so with distribution, you can send apps to the relevant app store, you can send it to beta users, to testers, and this is a push thing, and so it's very different than I have a new version, you need to come get my thumb drive, or even can you go check this share. It allows me to notify people that I have apps and designate certain versions and certain release types to people. So we're going to do a new release here in AppCenter. We're going to take the artifact we just downloaded. I'm going to give it a build version, we'll call this is the first AppCenter version, close those out, put some nodes in, and say it's crashing. Then since you and I are in a shared organization here in AppCenter, we both have access to this app. There's a built-in group called collaborators and that's the two of us. So we're both going to get a notification that there's a new version of this app and you can download it and use it. So clearly I have the app on my machine, but it's good to see that we do in fact get the push notification email from AppCenter, which will take you to our install portal, and the install portal will come up and actually give me the ability to download as a tester without all the other properties and details. The version of the app, it's thinking. It's not sure if it wants to show it to me today. It's too much bandwidth from all the users trying out our application currently. Yes. I see we already have almost 50 unique users, so keep it up, that's awesome. Excellent. We'll give this one little refresh. You can do it. The Internet's are clogged. Yeah, there we go. All right. So I'm going to go ahead and download this app. It can be distributed. I'm going to open the zip file and run the calculator. So despite the smart screen coming up and warning Matt about the trustworthiness of this application, with Azure DevOps and GitHub and all these tools, you can essentially track the end-to-end Git commit and all the dependencies that went into building this. So you can essentially validate that it's not doing anything suspicious. So now that I have this one-click EXE, it has installed things on my machine, and here's the app running. So as we saw earlier, if I divide 5 by 1, 5, if I try and divide 78 by 0, we should see that the app gets very unhappy. This is baseline, this is a failing test on what we had seen on your machine. So we're going to let it think. Windows is angry. So in the meantime, well, that crashes. You can go back to the diagnostics tab. Yes. We should go be able to go back to the diagnostics tab, and we should see the handled error. Should see a lot of errors. Should see a lot of errors. Yes. Look at that. So here's the handled error from, we should be able to find my instance of the handled error. I'm running on my Windows machine as a virtual machine in Azure. So there's 78 divided by 0, there's my instance and let's see. So it hasn't crashed on my machine quite yet. I guess it has. So once we've done that, if we wanted to complete the development cycle here, the really cool thing to do would be to go back to GitHub, make a PR, there we go. So if I wanted to say, hey, you know what, I'm using this, let's see what was actually going on. So I see the handled error, I want to find the unhandled error where it actually crashed because that's the one I'm more concerned about. I handled error indicates that I knew something was going to happen and I'm aware of it. An unhandled error is when things have gone awry, and why is this crashing? So I can actually see that in calc results, it's dying. So I'm going to go back to GitHub, I'm going to go to the file, main Windows, MLCS, I'm going to just use the cool stuff in GitHub here to make a PR. We're going to do a find on calc with a parentheses, it's in there. Hey, there's the calc operation. I see this try around all the operations. So hey, we're tracking the error and telling apps that we want to be aware of this, but look, we forgot to comment out the throw, which is why the app is re-crashing, and we really just want to show this message box and let users know that at least in the math we're aware of so far, dividing by zero doesn't quite make sense. So I should be able to come to the bottom, say, remove, re-throw, propose file change. Great. So in a perfect world, we would have you approve that PR. And I will do so shortly. We would let the build run, put the new artifact in distribution, and then everyone who's been added as a tester to this point would automatically know there's a new version that we want to try, they can verify that for you, and you can send it on to your production users. Great. So I just want to show this real quick because I'm really amazed with the awesome community. We have 62 live users of this application since we distributed it just a few minutes ago, including lots of fun folks who have figured out how to make it crash. Because we have this custom crash dictionary being sent up, we can view which operating systems are affecting it, including what sort of reports there are and how people are crashing it. So someone did nine divided by zero on some device, some RS4 device. Cool. So we're going to go back and kind of rush through the slides. These slides will be available, so you'll see some resources. The first thing I want to comment on, if you're interested in other desktop related sessions, here's a good list. If you miss them, you can watch them on-demand later. The App Center roadmap, so the thing I'm most excited for is the App Center Azure DevOps task for deploying applications. That means you'll be able to commit your application, and then when it's done building, you'll be able to download and update it immediately. Combine that with supporting automatic updates with MSIX. You could theoretically commit your app and then launch the updated version with no other manual steps, no downloading something new, just it works. We're also adding support for essentially console applications in .NET Core 3 cross-platform CLI-based applications, better build and test support, mobile backend as a service to streamline your integration with client-specific services such as storage, compute, push notifications, identity, things like that, and then we'll add more testing stuff and react native support with CodePush. With that, some resources again, these slides will be available on GitHub, so you can screenshot it now or take a look later. I definitely want to open some time to questions though, so I'm going to hand it over for some Q&A.