Category Archives: Windows Blog

Windows Blog

A new product badge for Microsoft Store applications

As many of you know, building quality apps is quite a commitment and investment in time. Once your app is in the Store, the next challenge is getting the word out about your new title and driving traffic to your product. Today, we’d like to announce a new tool for marketing your apps in your own blogs and websites. We’d like to introduce our new web badge for Microsoft Store products.

The new badge will render in your own website pulling localized logo, pricing (including sale pricing!), ratings and artwork directly from the store catalog. To render this badge for 8 Zip simply embed this script using its Store Id (9wzdncrfhwb8). Please note you must add the Id in two places in the badge script, the “class=” and inside the “mspb-“.

<div id="mspb-nc9jl2ngc1i" class="9wzdncrfhwb8"></div>
<script src="https://storebadge.azureedge.net/src/badge-1.6.1.js"></script>
<script>
mspb(‘9wzdncrfhwb8’, function(badge) {
document.getElementById(‘mspb-nc9jl2ngc1i’).innerHTML = badge;
});
</script>

The button click on the badge will direct your customers to the proper Product Description Page where they make the actual purchase. You can add multiple badges to any single page, just make sure they all use a unique div Id, as shown above.
To see the badge in action, check out XBOX’s @majornelson (www.majornelson.com) who is using the badge to promote Xbox content on his blog.
Example post here: https://majornelson.com/2018/05/03/xbox-live-gold-members-play-for-honor-xcom-2-and-just-cause-3-for-free-this-weekend/.
That’s it! Feel free to promote your apps and games on your own sites.

Console UWP Applications and File-system Access

As announced in the May 2018 issue of MSDN Magazine, the latest Windows update introduces support for Console UWP apps. We’re also introducing support for UWP apps to get broader access to the file-system than was previously possible. In fact, it was during the design and development phases of the Console app support that we realized we’d need to provide these apps with better file-system access – so the two features complement each other nicely.
Console apps represent a significant departure from the “normal” UWP model. Specifically, these apps don’t have their own windows, and don’t use the familiar input mechanisms. One of the attractions of UWP is the rich UI support, which allows you to build beautiful, highly-interactive apps. Console apps, on the other hand, use the standard console window for input and output, and the model is very much command-line driven and plain-text-based.
So, yes, Console apps are very different from traditional UWP apps, and they meet the requirements of a rather different target audience. They’re aimed squarely at developers who need to build admin or developer tools. To help you get started, we published a set of Console App (Universal) Project Templates in the Visual Studio Marketplace.
Let’s walk through creating a very simple Console UWP app, just to explore the possibilities, and to examine some of the options you have in using UWP features. The finished app is an (extremely primitive) implementation of the classic findstr tool – the app is in the Store here, and the sources are in the AppModelSamples repo on GitHub here.
To create this app from scratch, in VS, having installed the project templates, select File | New Project, and then select one of the two C++ project types for Console UWP apps – either C++/CX or C++/WinRT. In this example, I’ll choose C++/WinRT:

When prompted for the target platform version information, select a version that’s at least 17083 or later (including Windows Insider builds):

Two things to notice in the generated code. First, the Package.appxmanifest declares namespace aliases for desktop4 and iot2, and adds the SupportsMultipleInstances and Subystem attributes to both the Application node and the AppExecutionAlias node:

<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="MyFindstr.App"
desktop4:Subsystem="console"
desktop4:SupportsMultipleInstances="true"
iot2:Subsystem="console"
iot2:SupportsMultipleInstances="true"
>

<Extensions>
<uap5:Extension
Category="windows.appExecutionAlias"
Executable="MyFindstr.exe"
EntryPoint="MyFindstr.App">
<uap5:AppExecutionAlias
desktop4:Subsystem="console" iot2:Subsystem="console">
<uap5:ExecutionAlias Alias="MyFindstr.exe" />
</uap5:AppExecutionAlias>
</uap5:Extension>
</Extensions>

</Application>
</Applications>

From this it should be clear that in this release Console UWP apps are only supported on Desktop and IoT devices. Currently, only Desktop and IoT devices have consoles, so the feature only makes sense there.
The second thing to notice is the main function in Program.cpp. This simply gets hold of the command-line arguments and prints them out in a loop to the console.

int main()
{
// You can get parsed command-line arguments from the CRT globals.
wprintf(L"Parsed command-line arguments:n");
for (int i = 0; i < __argc; i++)
{
wprintf(L"__argv[%d] = %Sn", i, __argv[i]);
}

wprintf(L"Press Enter to continue:");
getchar();
}

You can press F5 at this point, just to get the app built and deployed, before changing anything.

As expected, if you execute the app this way, the only command-line argument is __argv[0], which is the executable filename itself. Now that the app is deployed, you can also run it from its tile on the Start menu – and get the exact same results.
However, if you run a separate cmd (or Powershell) window, and execute the app from there, you can then provide any arbitrary command-line arguments you like. This works because installing the app also registered the AppExecutionAlias declared in the manifest. By default, this is set to the same as the project name, although you can of course change this, if you wish:

You can see from the standard generated code that you can use many of the traditional Win32 APIs – the latest Windows update adds a lot more console-specific APIs to the approved list, so that these can be used in Store-published apps.
But, what if you want to use WinRT APIs? Well, of course, this is a UWP app, so you’re free to use WinRT APIs also. This does come with a caveat, however. There are some WinRT APIs that assume that the caller is a regular UWP app with a regular window and view. A console app doesn’t have a regular window or view, so any window-specific APIs won’t work. For the more obvious window-related APIs, you should have no reason to call any of them since you don’t have your own windows, so the point should be moot.
For our simple findstr app, the first change is to add the broadFileSystemAccess restricted capability to the manifest. Add the namespace declaration at the top:

xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp desktop4 iot2 rescap">

…and then the capability itself at the bottom:

<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="broadFileSystemAccess" />
</Capabilities>

This corresponds to the File system setting under Privacy in the Settings app. This is where the user can enable or disable broad File-system access on either a per-app basis, or globally for all UWP apps:

Now for the meat of the app. The classic findstr tool is used to perform string searches in files. It has a lot of command-line options for configuring the search. Internally, it performs all the operations from scratch, using low-level Win32 APIs and without using any higher-level libraries. However, for the purposes of this demo, I’m going to cheat and use the std::regex APIs. One obvious reason for this is because I don’t want to write thousands of lines of code for this sample. A less obvious reason is that I want to explore how to use libraries of different types in my Console UWP app (more on this in a later post). My cut-down version of findstr will take in only two simple command-line arguments:
A pattern to search for.
A fully-qualified folder path, in which to search.
First, some housekeeping. I’ll add some #includes in my pch.h. I plan on using the Windows.Storage APIs as well as std::regex:

#include "winrt/Windows.Storage.h"
#include <regex>

At the top of my Program.cpp, I’ll add corresponding namespace declarations:

using namespace winrt;
using namespace winrt::Windows::Storage;
using namespace Windows::Foundation::Collections;

Now I can update main to get the search pattern and the starting folder supplied on the command-line. If for some reason I can’t open that folder using the Storage APIs, I’ll just bail with some suitable error code. This could be because the user has disabled File-system access in Settings, or because the folder path supplied was non-existent or badly-formed, and so on. Also note that I’m not doing any input-validation here – but of course in a real app you would be very careful to check all inputs before proceeding, and most especially if your app is expecting to have broad file-system access.

int main()
{
hstring searchPattern = to_hstring(__argv[1]);
hstring folderPath = to_hstring(__argv[2]);
StorageFolder folder = nullptr;
try
{
folder = StorageFolder::GetFolderFromPathAsync(folderPath.c_str()).get();
}
catch (…)
{
wprintf(L"Error: cannot access folder ‘%S’n", __argv[2]);
return 2;
}

If I did manage to get the folder open, I can then continue to use the Storage APIs to get all the files in this folder for searching, and then to call a recursive GetDirectories function, so that I can walk the folder tree from this point downwards. I’ll write the GetDirectories and SearchFile functions shortly.

if (folder != nullptr)
{
wprintf(L"nSearching folder ‘%s’ and below for pattern ‘%s’n", folder.Path().c_str(), searchPattern.c_str());
try
{
IVectorView<StorageFolder> folders = folder.GetFoldersAsync().get();

// Recurse sub-directories.
GetDirectories(folders, searchPattern);

// Get the files in this folder.
IVectorView<StorageFile> files = folder.GetFilesAsync().get();
for (uint32_t i = 0; i < files.Size(); i++)
{
StorageFile file = files.GetAt(i);
SearchFile(file, searchPattern);
}
}
catch (std::exception ex)
{
wprintf(L"Error: %Sn", ex.what());
return 3;
}
catch (…)
{
wprintf(L"Error: unknownn");
return 3;
}
}

return 0;
}

Now for the recursive GetDirectories function. Given the collection of folders in the current directory, I can recursively process all sub-directories. At each level, I can also get all the files for searching.

void GetDirectories(IVectorView<StorageFolder> folders, hstring searchPattern)
{
try
{
for (uint32_t i = 0; i < folders.Size(); i++)
{
StorageFolder folder = folders.GetAt(i);

// Recurse this folder to get sub-folder info.
IVectorView<StorageFolder> subDir = folder.GetFoldersAsync().get();
if (subDir.Size() != 0)
{
GetDirectories(subDir, searchPattern);
}

// Get the files in this folder.
IVectorView<StorageFile> files = folder.GetFilesAsync().get();
for (uint32_t j = 0; j < files.Size(); j++)
{
StorageFile file = files.GetAt(j);
SearchFile(file, searchPattern);
}
}
}
catch (std::exception ex)
{
wprintf(L"Error: %Sn", ex.what());
}
catch (…)
{
wprintf(L"Error: unknownn");
}
}

Now, the SearchFile function. This is where I’m cheating and using std::regex instead of doing all the work myself. First, I’ll read all the text out of the file with ReadTextAsync. If the file isn’t a text file, this will throw an exception – for simplicity, I’m just reporting the error and moving on. Then, I enhance the raw search pattern to search for any whitespace-delimited “word” that contains the pattern. Finally, I use regex_search to do the pattern-matching, and print out all the found words and their position in the text:

void SearchFile(StorageFile file, hstring searchPattern)
{
if (file != nullptr)
{
try
{
wprintf(L"nScanning file ‘%s’n", file.Path().c_str());
hstring text = FileIO::ReadTextAsync(file).get();
std::string sourceText = to_string(text);
std::smatch match;
std::string compositePattern =
"(S+s+){0}S*" + to_string(searchPattern) + "S*(s+S+){0}";
std::regex expression(compositePattern);

while (std::regex_search(sourceText, match, expression))
{
wprintf(L"%8d %Sn", match.position(), match[0].str().c_str());
sourceText = match.suffix().str();
}
}
catch (std::exception ex)
{
wprintf(L"Error: %Sn", ex.what());
}
catch (…)
{
wprintf(L"Error: cannot read text from file.n");
}
}
}

One additional convenience: because this is a UWP app, it will have an entry in the Start menu app-list, and the user could pin its tile to Start. So, if could be executed from Start – in which case, of course, it won’t have any command-line arguments. Given how I’m assuming the command-line includes at least a search pattern and folder path, I’ll allow for this with a simple check. So, I’ll add this right at the beginning of main:

if (__argc < 3)
{
ShowUsage();
return 1;
}

…and define the matching ShowUsage function:

void ShowUsage()
{
wprintf(L"Error: insufficient arguments.n");
wprintf(L"Usage:n");
wprintf(L"MyFindstr <search-pattern> <fully-qualified-folder-path>.n");
wprintf(L"Example:n");
wprintf(L"MyFindstr on D:Temp.n");

wprintf(L"nPress Enter to continue:");
getchar();
}

That’s it! Having re-deployed this version with F5, I can then execute it from a cmd or Powershell window, supplying a search pattern and a starting folder on the command-line:

Now admittedly, my findstr app has only the most basic functionality, but hopefully it does illustrate how easy it is to create a simple Console UWP app that consumes both standard C++ library APIs and WinRT APIs.
For anyone who has already started experimenting with Console UWP apps, it’s worth calling out that the original version of the VS templates had a couple of bugs (or, arguably, a bug and an anomaly), which were fixed in version 1.4. The issues do not prevent the app from building and executing, but they do prevent F5 debugging and also correct packaging and store publication. If you have already created projects using the old templates, you can apply the fixes by making the same changes in the .vcxproj and package.appxmanifest files manually (for both C++/CX and C++/WinRT).
First, the bug. In the package.appxmanifest file, v1.4 added iot2 to the ignorable XML namespaces:

IgnorableNamespaces="uap mp uap5 iot2 desktop4">

Of course, if you’re not targeting IoT devices, then you can instead delete this, and also delete the IoT namespace declaration itself:

xmlns:iot2="http://schemas.microsoft.com/appx/manifest/iot/windows10/2"

…as well as the iot2-scoped Subsystem declarations in both the Application and AppExecutionAlias nodes:

iot2:Subsystem="console"

Now for the anomaly: v1.3 of the template included declarations in the .vcxproj file that are specific to .NET Native. These are required if your app includes say a C# WinRT component, where .NET Native is used. However, if your app doesn’t include such a component then the declarations will prevent correct packaging. In v1.4 of the template, these have been removed – both the target framework declarations at the top of the file:

<TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>

…and also multiple instances of the following:

<PlatformToolset>v141</PlatformToolset>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>

Please also note that all C++/WinRT templates are still experimental at this stage, and subject to change.
Apologies for any inconvenience caused by the bugs – and please do let us know if you have any feedback on the templates, or on the Console UWP feature.
For documentation, see Create a Universal Windows Platform Console app and File access permissions.

Automate UI testing with WinAppDriver – now supporting Pen input

Windows Application Driver (WinAppDriver) is continuing Microsoft’s investment in UI test automation tools for Windows 10, and now, we’re excited to announce the next release of WinAppDriver—version 1.1!
A preview is available today— bringing support for Pen automation. The full v1.1 release is also on the horizon and will feature support for Multi-Touch in addition to Pen.

What is WinAppDriver?
For those of you who aren’t familiar with WinAppDriver or UI automation, WinAppDriver is an open-standards based UI automation service designed to work with all kinds of Windows 10 applications including WPF, WinForms, legacy Win32, and UWP. By complying with an open-standard, WinAppDriver users will be able to leverage the robust UI automation ecosystem already provided by Appium and Selenium.
What’s new in the v1.1 Preview
In v1.1, we’re aligning with the W3C WebDriver standard, and as a result, implementing the Actions API to bring in advanced input device support.
The Preview release of v1.1 includes the following:
WinAppDriver updated for Pen, including support for advanced Pen functionality:
Pressure
Tilt X & Tilt Y
Twist
Barrel button
Eraser support

Appium-Dotnet-Driver NuGet Package
This is a preview Nuget package with updated bindings to enable Pen automation on WinAppDriver.

Samples & Documentation on GitHub
Note that the full release will also include support for Multi-Touch – more details on that below.
Getting Started with Pen
You can download the preview version of WinAppDriver on our GitHub page here: https://github.com/Microsoft/WinAppDriver/releases.
To get started on using Pen, we highly recommend checking out our new Sticky Notes sample here.
Let’s sketch out a quick smile
To demonstrate something a little more complex than a few strokes on a sticky note, we tried drawing out the following smiley face through the following steps–
Step 1 – Using Pen to draw a basic Circle 

//Initiate a Pen object using the custom Dotnet Driver Bindings.
PointerInputDevice penDevice = new PointerInputDevice(PointerKind.Pen);
ActionSequence drawSequence = new ActionSequence(penDevice, 0);

//Set starting position of circle by its center point.
var centerX = canvasCoordinate.X + canvasSize.Width / 5 + 285;
var centerY = canvasCoordinate.Y + canvasSize.Height / 5 + 270;
//Radius of circle.
var radius = 200;
/* This value will dictate the granularity of the number of stokes to complete the strokes. The more steps, the less blocky the circle will be. Note: Sticky Notes will interpolate between the steps anyway, so it will not appear blocky if Pen is not lifted. */
var steps = 50;
// These two variables will calculate either the X or Y coordinate around the center of the circle for a given step.
int xValue = (int)(centerX + radius * Math.Cos(2 * Math.PI * 0 / steps));
int yValue = (int)(centerY + radius * Math.Sin(2 * Math.PI * 0 / steps));
drawSequence.AddAction(penDevice.CreatePointerMove(CoordinateOrigin.Viewport, xValue, yValue, TimeSpan.Zero));
drawSequence.AddAction(penDevice.CreatePointerUp(PointerButton.PenFrontTip));
/* Function to draw circle by calculating coordinates around center point and brushing through them. */
for (var i = 0; i &lt;= steps; i++) {
xValue = (int)(centerX + radius * Math.Cos(2 * Math.PI * i / steps));
yValue = (int)(centerY + radius * Math.Sin(2 * Math.PI * i / steps)); drawSequence.AddAction(penDevice.CreatePointerDown(PointerButton.PenContact));
drawSequence.AddAction(penDevice.CreatePointerMove(CoordinateOrigin.Viewport, xValue, yValue, TimeSpan.Zero));
}
//Lifting pen up once Circle is drawn. drawSequence.AddAction(penDevice.CreatePointerUp(PointerButton.PenContact));
//Final step would be to execute the sequence.
newStickyNoteSession.PerformActions(new List&lt;ActionSequence&gt; { drawSequence });

Step 2 – Adding in the smile
We’ll have to get a little clever with this part, and modify the original for-loop from step 1 and add supplementary code following it. This will continue the same sequence.

/* Loop modified to iterate past opening step and closing step of circle. This will create an opening for the smiley ìmouthî. */
for (var i = 0; i &lt; steps; i++) {
xValue = (int)(centerX + radius * Math.Cos(2 * Math.PI * i / steps));
yValue = (int)(centerY + radius * Math.Sin(2 * Math.PI * i / steps));
if (i &gt; 1){
drawSequence.AddAction(penDevice.CreatePointerDown(PointerButton.PenContact));

} drawSequence.AddAction(penDevice.CreatePointerDown(PointerButton.PenContact));
drawSequence.AddAction(penDevice.CreatePointerMove(CoordinateOrigin.Viewport, xValue, yValue, TimeSpan.Zero));
}
drawSequence.AddAction(penDevice.CreatePointerUp(PointerButton.PenContact));
/* The following vars will calculate X &amp; Y coordinates for start and end point of the smile. */
var xSmile = (int)(centerX + radius * Math.Cos(2 * Math.PI * 1 / steps));
var ySmile = (int)(centerY + radius * Math.Sin(2 * Math.PI * 1 / steps));
var xSmile2 = (int)(centerX + radius * Math.Cos(2 * Math.PI * (steps – 1) / steps));
var ySmile2 = (int)(centerY + radius * Math.Sin(2 * Math.PI * (steps – 1) / steps));

/* Continue previous sequence and execute the Pen actions. */
drawSequence.AddAction(penDevice.CreatePointerMove(CoordinateOrigin.Viewport, xSmile, ySmile, TimeSpan.Zero));
drawSequence.AddAction(penDevice.CreatePointerDown(PointerButton.PenContact));
drawSequence.AddAction(penDevice.CreatePointerMove(CoordinateOrigin.Viewport, centerX, centerY, TimeSpan.FromMilliseconds(400), new PenInfo { Pressure = .600f }));
drawSequence.AddAction(penDevice.CreatePointerUp(PointerButton.PenContact));
drawSequence.AddAction(penDevice.CreatePointerDown(PointerButton.PenContact));
drawSequence.AddAction(penDevice.CreatePointerMove(CoordinateOrigin.Viewport, xSmile2, ySmile2, TimeSpan.FromMilliseconds(400)));

// Execute sequence.
newStickyNoteSession.PerformActions(new List&lt;ActionSequence&gt; { drawSequence });

The additional pressure applied to the “smile strokes”—this is to add depth to the smile. The sketch should appear as the following:Step 3 – Eyes
If we wanted to finish up and add eyes, it would look something like the following:There’s a lot of clever ways you can go on about adding the eyes, so we’ll let you decide which way is best. The full code for our design will be included as part of the Sticky Notes sample on GitHub!
Details on full 1.1
The full release of v1.1 will come with the following additions:
WinAppDriver
Pen—support for Pen will be carried over to full 1.1 release from the Preview.
Multi-Touch—support for Multi-Touch will be added in as well through the Actions API. The following touch modifiers will be supported:
Pressure
Twist

New Samples & Bindings
Samples from the Preview will be further expanded to demonstrate Pen and Multi-Touch functionality. The samples will incorporate a private Appium-Dotnet-Driver Nuget feed that will enable Actions implementation via the new bindings. We’re looking into having these changes be merged into the official Appium .Net Driver, and eventually be rolled-up to the Selenium Namespace in the future.
Release Date
We’re targeting this June for the full release of v1.1—stay tuned to our GitHub board for more info!
Moving Forward
The WinAppDriver team will continue to work on adding new features, resolving bugs, and improving performance. We’ve been looking into popular community requests, and as such, have a couple of cool things in the pipeline for 1.2 and beyond—one in particular being to improve performance with XPath handling.
We’ll also be releasing a new tool for the community – more details on this to follow in the coming weeks. Stay tuned!
How do I provide feedback?
Please provide feedback on our Github issue board – we look forward to hearing about any suggestions, feature requests, or bug reports!
https://github.com/Microsoft/WinAppDriver/issues
If you have any cool sketches done through v1.1 that you’d like to share—do so on the GitHub board! It may even be featured in a future blog post!
Stay Informed
To stay up to date with WinAppDriver news follow @mrhassanuz.
Summary
The v1.1 Preview is available now—enabling users to automate Pen scenarios. Full release for v1.1 to follow, and with it will bring support for Multi-Touch as well. Head over to our releases page on GitHub to download the preview, and get a jump-start on Pen automation by reviewing our updated samples.

Previewing support for same-site cookies in Microsoft Edge

Yesterday’s Windows Insider Preview build (build 17672) introduces support for the SameSite cookies standard in Microsoft Edge, ahead of a planned rollout in Microsoft Edge and Internet Explorer. Same-site cookies enable more protection for users against cross-site request forgery (CSRF) attacks.
Historically, sites such as example.com that make “cross-origin” requests to other domains such as microsoft.com have generally caused the browser to send microsoft.com’s cookies as part of the request. Normally, the user benefits by being able to reuse some state (e.g., login state) across sites no matter from where that request originated. Unfortunately, this can be abused, as in CSRF attacks. Same-site cookies are a valuable addition to the defense in depth against CSRF attacks.
Sites can now set the SameSite attribute on cookies of their choosing via the Set-Cookie header or by using the document.cookie JavaScript property, thus preventing the default browser behavior of sending cookies in cross-site requests either in all cross-site requests (via the “strict” value) or only in some less sensitive requests (via the “lax” value).
More specifically, if the strict attribute is specified for when a same-site cookie is set, it will not be sent for any cross-site request, which includes clicking on links from external sites. Since the logged-in state is stored as a SameSite=Strict cookie, when a user clicks such a link it will initially appear as if the user is not logged in.
On the other hand, if the lax attribute is specified for when a same-site cookie is set, it will not be sent for cross-origin sub-resource requests such as images. However, the SameSite=Lax cookies will be sent when navigating from an external site, such as when a link is clicked.
This feature is backwards compatible―that is, browsers that don’t support same-site cookies will safely ignore the additional attribute and will simply use the cookie as a regular cookie.
We continuously work to improve our support of standards towards a more interoperable web. Although same-site cookies is not yet a finalized standard at the Internet Engineering Task Force (IETF), we believe the feature is stable and compelling enough to warrant an early implementation as the standardization process progresses.
To broaden the security benefits of this feature, we plan to service Microsoft Edge and Internet Explorer 11 on the Windows 10 Creators Update and newer to support same-site cookies as well, allowing sites to rely on same-site cookies as a defense against CSRF and other related cross-site timing and cross-site information-leakage attacks.
— Ali Alabbas, Program Manager, Microsoft Edge
— Gabriel Montenegro, Program Manager, Windows Networking
— Brent Mills, Program Manager, Internet Explorer

Announcing the Xbox Adaptive Controller for accessible gaming

Here are some of the highlights from Phil’s post:
“We have been on a journey of inclusive design, which celebrates and draws inspiration from people who are often overlooked in the typical design process.
For gamers with limited mobility, finding controller solutions to fit their individual needs has been challenging. The solutions that exist today are often expensive, hard to find, or require significant technical skill to create. A number of individuals and organizations are creating custom solutions, but it has been often difficult for them to scale when most rigs need to be so personalized.
Joining the Xbox family of controllers and devices, the Xbox Adaptive Controller was created to address these challenges and remove barriers to gaming by being adaptable to more gamers’ needs.  It was developed in partnership with organizations around the world, including The AbleGamers Foundation, The Cerebral Palsy Foundation, Craig Hospital, SpecialEffect, and Warfighter Engaged. We worked closely with them and directly with gamers who have limited mobility to assist in our development.
Our goal was to make the device as adaptable as possible, so gamers can create a setup that works for them in a way that is plug-and-play, extensible, and affordable.  In addition to working with common adaptive switches that gamers with limited mobility may already own, it has two large buttons built in. These buttons can also be reprogrammed to act as any of the standard controller’s button inputs via the Xbox Accessories app.
To make the Xbox Adaptive Controller a viable solution for the widest possible range of gamers with limited mobility, we’ve worked closely with third-party manufacturers to support external inputs which can be plugged in to the new controller. 
At $99.99 USD and available exclusively through Microsoft Store, the Xbox Adaptive Controller will offer significant value over the customized alternatives that exist today. We’re looking forward to sharing more about the Xbox Adaptive Controller in a few weeks at E3. The Xbox Adaptive Controller will be launching later this year, and we’ll share more information soon about pre-order availability.”
To read the full post from Phil Spencer, head over to Xbox Wire, and learn more about accessibility at Microsoft here.

Celebrating Global Accessibility Awareness Day

At Microsoft, we want to empower every person and every organization to achieve more. We deeply believe everyone should have the opportunity to reach their potential and we can help by empowering all people, regardless of their abilities. Global Accessibility Awareness Day gives us the chance to celebrate our differences and reflect on the ways in which we continue to strive to make Windows more accessible to everyone in their everyday life.

Windows for each of us.
Inclusion starts with embracing what makes each of us unique. And it’s this belief that drives our passion to create technology that reflects the diversity of our customers. We have teams dedicated to discovering ways to make technology more accessible, developing products such as the recently updated Narrator, a built-in screen reader that empowers people with low or no vision to navigate and use their computers. Narrator helps people who are blind or have a visual impairment to read the text that is displayed on the computer screen with a speech synthesizer or braille display.
This feature is invaluable to many of our customers, including Nori, who has had a visual impairment since birth. Narrator has helped her pursue her passion for Japanese culture and public speaking. She’s a fan of using it to prepare for Japanese oratory competitions (which she has won five years in a row!). We’re grateful to have Nori in our Windows Insider program—her insights help us continue to develop tools to reflect the diverse needs of our customers.

Windows adapts to you.
Windows is designed to adapt to you whether you have a disability, a personal preference, or a unique work style. There are simple ways to enhance Windows to make it easier for you to see, hear, use, and focus on what’s in front of you. Here are some of the accessibility features our Windows customers tell us they like the most:
1. Magnifier enlarges words and images with custom settings you can use on all or part of the screen.

2. Color Filters enable you to boost contrast, or remove color entirely—whether you have colorblindness, light sensitivity, or a visual preference, you can customize your screen’s color palette.

3. High Contrast lets you increase the color contrast of text and images on your screen, making them easier to identify. Each high contrast theme can be customized to suit your needs and tastes.

4. Narrator is a screen-reading app, offering simplified navigation and intelligent image description so you can easily explore a page without missing anything. Learn more about how someone who is blind uses a computer, as well as the team that works on making Windows more inclusive.

5. Learning tools in Microsoft Edge make it easier for people with dyslexia to consume written information. New built-in grammar tools break down syllables and highlight parts of speech, and the Read aloud feature works with ePubs, PDFs and websites.

In my post about the new Windows 10 April 2018 Update, I talk about two of my own personal favorite features: Focus Assist and Dictation. These are great options for people who want to get things done without distractions or create more naturally with their voice. If you’d like to see some of these features in person, please join us at your local Microsoft Store for Ability Week, a five-day experience starting May 29 through June 2. We will be showcasing hearing, vision, mobility, and cognitive assistive technologies that empower people with accessibility needs.
We believe that when we build tools that empower each of us, we all will benefit. Thank you for joining us in supporting Global Accessibility Awareness Day.
Yusuf

Announcing Windows 10 Insider Preview Build 17672

Hello Windows Insiders!
Today, we are releasing Windows 10 Insider Preview Build 17672 (RS5) to Windows Insiders in the Fast ring in addition to those who opted in to Skip Ahead.
Microsoft Build 2018 Recap

We’re still reeling from how awesome the Microsoft Build conference was this year. Our team and our friends from Deployment, Feedback and Flighting manned Windows Insider booth all 3 days and circulated through the conference learning all the cool new tech. We had over 800 people come by our booth and we had the opportunity to share what’s next for the program AND learn what we can be doing better to create a better Insider program.
We also had the pleasure of having three of our most passionate Insiders as our guests.

Ange Uwambajimana, Irving Amukasa and Raymond Dillion were chosen to attend the conference and present on stage with us because of their impactful work using technologies in their local communities. Ange has created an IOT IV Drip solution to account for the lack of enough nurses in her home country of Rwanda who look after patients who are re-receiving. Her story is based on a near-tragedy involving her brother who suffers from epilepsy.  Irving has created SophieBot, a “Cortana for reproductive health questions” to account for the fact that in many parts of the world, talking about sexual and reproductive health is taboo.  Raymond is working to digitally transform Ireland, get them out of the paper records business AND grow the next generation of tech enthusiasts.
These Insiders had a chance to meet many of our upper management, including Satya! Satya asked them quite a few detailed questions about how they were using our tech, what more we could do to make it easier to use. The best moment was when THEY started asking Satya some hard questions about AI. Each of the Insiders walked away with homework too.

We had three sessions talking about the benefits of being an Insider and a developer.
Insiders

Windows 10 SDK Preview Build 17666 now available!

Today, we released a new Windows 10 Preview Build of the SDK to be used in conjunction with Windows 10 Insider Preview (Build 17666 or greater). The Preview SDK Build 17666 contains bug fixes and under development changes to the API surface area.
The Preview SDK can be downloaded from developer section on Windows Insider.
For feedback and updates to the known issues, please see the developer forum. For new developer feature requests, head over to our Windows Platform UserVoice.
Things to note:
This build works in conjunction with previously released SDKs and Visual Studio 2017. You can install this SDK and still also continue to submit your apps that target Windows 10 Creators build or earlier to the Store.
The Windows SDK will now formally only be supported by Visual Studio 2017 and greater. You can download the Visual Studio 2017 here.
This build of the Windows SDK will install on Windows 10 Insider Preview and supported Windows operating systems.
Known Issues
Installation on an operating system that is not a Windows 10 Insider Preview build is not supported and may fail.
The contract Windows.System.SystemManagementContract is not included in this release. In order to access the following APIs, please use a previous Windows IoT extension SDK with your project.
This bug will be fixed in a future preview build of the SDK.
The following APIs are affected by this bug:

namespace Windows.Services.Cortana {
public sealed class CortanaSettings
}
namespace Windows.System {
public enum AutoUpdateTimeZoneStatus
public static class DateTimeSettings
public enum PowerState
public static class ProcessLauncher
public sealed class ProcessLauncherOptions
public sealed class ProcessLauncherResult
public enum ShutdownKind
public static class ShutdownManager
public struct SystemManagementContract
public static class TimeZoneSettings
}

API Spot Light:
Check out LauncherOptions.GroupingPreference.

namespace Windows.System {
public sealed class FolderLauncherOptions : ILauncherViewOptions {
ViewGrouping GroupingPreference { get; set; }
}
public sealed class LauncherOptions : ILauncherViewOptions {
ViewGrouping GroupingPreference { get; set; }
}

This release contains the new LauncherOptions.GroupingPreference property to assist your app in tailoring its behavior for Sets. Watch the presentation here.

What’s New:
MC.EXE
We’ve made some important changes to the C/C++ ETW code generation of mc.exe (Message Compiler):
The “-mof” parameter is deprecated. This parameter instructs MC.exe to generate ETW code that is compatible with Windows XP and earlier. Support for the “-mof” parameter will be removed in a future version of mc.exe.
As long as the “-mof” parameter is not used, the generated C/C++ header is now compatible with both kernel-mode and user-mode, regardless of whether “-km” or “-um” was specified on the command line. The header will use the _ETW_KM_ macro to automatically determine whether it is being compiled for kernel-mode or user-mode and will call the appropriate ETW APIs for each mode.
The only remaining difference between “-km” and “-um” is that the EventWrite[EventName] macros generated with “-km” have an Activity ID parameter while the EventWrite[EventName] macros generated with “-um” do not have an Activity ID parameter.
The EventWrite[EventName] macros now default to calling EventWriteTransfer (user mode) or EtwWriteTransfer (kernel mode). Previously, the EventWrite[EventName] macros defaulted to calling EventWrite (user mode) or EtwWrite (kernel mode).
The generated header now supports several customization macros. For example, you can set the MCGEN_EVENTWRITETRANSFER macro if you need the generated macros to call something other than EventWriteTransfer.
The manifest supports new attributes.
Event “name”: non-localized event name.
Event “attributes”: additional key-value metadata for an event such as filename, line number, component name, function name.
Event “tags”: 28-bit value with user-defined semantics (per-event).
Field “tags”: 28-bit value with user-defined semantics (per-field – can be applied to “data” or “struct” elements).

You can now define “provider traits” in the manifest (e.g. provider group). If provider traits are used in the manifest, the EventRegister[ProviderName] macro will automatically register them.
MC will now report an error if a localized message file is missing a string. (Previously MC would silently generate a corrupt message resource.)
MC can now generate Unicode (utf-8 or utf-16) output with the “-cp utf-8” or “-cp utf-16” parameters.
API Updates and Additions
When targeting new APIs, consider writing your app to be adaptive in order to run correctly on the widest number of Windows 10 devices. Please see Dynamically detecting features with API contracts (10 by 10) for more information.
The following APIs have been added to the platform since the release of 17134.

namespace Windows.ApplicationModel {
public sealed class AppInstallerFileInfo
public sealed class LimitedAccessFeatureRequestResult
public static class LimitedAccessFeatures
public enum LimitedAccessFeatureStatus
public sealed class Package {
IAsyncOperation<PackageUpdateAvailabilityResult> CheckUpdateAvailabilityAsync();
AppInstallerFileInfo GetAppInstallerFileInfo();
}
public enum PackageUpdateAvailability
public sealed class PackageUpdateAvailabilityResult
}
namespace Windows.ApplicationModel.Calls {
public sealed class VoipCallCoordinator {
IAsyncOperation<VoipPhoneCallResourceReservationStatus> ReserveCallResourcesAsync();
}
}
namespace Windows.ApplicationModel.Store.Preview.InstallControl {
public enum AppInstallationToastNotificationMode
public sealed class AppInstallItem {
AppInstallationToastNotificationMode CompletedInstallToastNotificationMode { get; set; }
AppInstallationToastNotificationMode InstallInProgressToastNotificationMode { get; set; }
bool PinToDesktopAfterInstall { get; set; }
bool PinToStartAfterInstall { get; set; }
bool PinToTaskbarAfterInstall { get; set; }
}
public sealed class AppInstallManager {
bool CanInstallForAllUsers { get; }
}
public sealed class AppInstallOptions {
AppInstallationToastNotificationMode CompletedInstallToastNotificationMode { get; set; }
bool InstallForAllUsers { get; set; }
AppInstallationToastNotificationMode InstallInProgressToastNotificationMode { get; set; }
bool PinToDesktopAfterInstall { get; set; }
bool PinToStartAfterInstall { get; set; }
bool PinToTaskbarAfterInstall { get; set; }
bool StageButDoNotInstall { get; set; }
}
public sealed class AppUpdateOptions {
bool AutomaticallyDownloadAndInstallUpdateIfFound { get; set; }
}
}
namespace Windows.Devices.Enumeration {
public sealed class DeviceInformationPairing {
public static bool TryRegisterForAllInboundPairingRequestsWithProtectionLevel(DevicePairingKinds pairingKindsSupported, DevicePairingProtectionLevel minProtectionLevel);
}
}
namespace Windows.Devices.Lights {
public sealed class LampArray
public enum LampArrayKind
public sealed class LampInfo
public enum LampPurpose : uint
}
namespace Windows.Devices.Sensors {
public sealed class SimpleOrientationSensor {
public static IAsyncOperation<SimpleOrientationSensor> FromIdAsync(string deviceId);
public static string GetDeviceSelector();
}
}
namespace Windows.Devices.SmartCards {
public static class KnownSmartCardAppletIds
public sealed class SmartCardAppletIdGroup {
string Description { get; set; }
IRandomAccessStreamReference Logo { get; set; }
ValueSet Properties { get; }
bool SecureUserAuthenticationRequired { get; set; }
}
public sealed class SmartCardAppletIdGroupRegistration {
string SmartCardReaderId { get; }
IAsyncAction SetPropertiesAsync(ValueSet props);
}
}
namespace Windows.Devices.WiFi {
public enum WiFiPhyKind {
He = 10,
}
}
namespace Windows.Media.Core {
public sealed class MediaStreamSample {
IDirect3DSurface Direct3D11Surface { get; }
public static MediaStreamSample CreateFromDirect3D11Surface(IDirect3DSurface surface, TimeSpan timestamp);
}
}
namespace Windows.Media.Devices.Core {
public sealed class CameraIntrinsics {
public CameraIntrinsics(Vector2 focalLength, Vector2 principalPoint, Vector3 radialDistortion, Vector2 tangentialDistortion, uint imageWidth, uint imageHeight);
}
}
namespace Windows.Media.Streaming.Adaptive {
public enum AdaptiveMediaSourceResourceType {
MediaSegmentIndex = 5,
}
}
namespace Windows.Security.Authentication.Web.Provider {
public sealed class WebAccountProviderInvalidateCacheOperation : IWebAccountProviderBaseReportOperation, IWebAccountProviderOperation
public enum WebAccountProviderOperationKind {
InvalidateCache = 7,
}
public sealed class WebProviderTokenRequest {
string Id { get; }
}
}
namespace Windows.Security.DataProtection {
public enum UserDataAvailability
public sealed class UserDataAvailabilityStateChangedEventArgs
public sealed class UserDataBufferUnprotectResult
public enum UserDataBufferUnprotectStatus
public sealed class UserDataProtectionManager
public sealed class UserDataStorageItemProtectionInfo
public enum UserDataStorageItemProtectionStatus
}
namespace Windows.Services.Cortana {
public sealed class CortanaActionableInsights
public sealed class CortanaActionableInsightsOptions
}
namespace Windows.Services.Store {
public sealed class StoreContext {
IAsyncOperation<StoreRateAndReviewResult> RequestRateAndReviewAppAsync();
}
public sealed class StoreRateAndReviewResult
public enum StoreRateAndReviewStatus
}
namespace Windows.Storage.Provider {
public enum StorageProviderHydrationPolicyModifier : uint {
AutoDehydrationAllowed = (uint)4,
}
}
namespace Windows.System {
public sealed class FolderLauncherOptions : ILauncherViewOptions {
ViewGrouping GroupingPreference { get; set; }
}
public sealed class LauncherOptions : ILauncherViewOptions {
ViewGrouping GroupingPreference { get; set; }
}
namespace Windows.UI.Composition {
public enum CompositionBatchTypes : uint {
AllAnimations = (uint)5,
InfiniteAnimation = (uint)4,
}
public sealed class CompositionGeometricClip : CompositionClip
public sealed class Compositor : IClosable {
CompositionGeometricClip CreateGeometricClip();
}
}
namespace Windows.UI.Notifications {
public sealed class ScheduledToastNotification {
public ScheduledToastNotification(DateTime deliveryTime);
IAdaptiveCard AdaptiveCard { get; set; }
}
public sealed class ToastNotification {
public ToastNotification();
IAdaptiveCard AdaptiveCard { get; set; }
}
}
namespace Windows.UI.Shell {
public sealed class TaskbarManager {
IAsyncOperation<bool> IsSecondaryTilePinnedAsync(string tileId);
IAsyncOperation<bool> RequestPinSecondaryTileAsync(SecondaryTile secondaryTile);
IAsyncOperation<bool> TryUnpinSecondaryTileAsync(string tileId);
}
}
namespace Windows.UI.StartScreen {
public sealed class StartScreenManager {
IAsyncOperation<bool> ContainsSecondaryTileAsync(string tileId);
IAsyncOperation<bool> TryRemoveSecondaryTileAsync(string tileId);
}
}
namespace Windows.UI.ViewManagement {
public sealed class ApplicationView {
bool IsTabGroupingSupported { get; }
}
public sealed class ApplicationViewTitleBar {
void SetActiveIconStreamAsync(RandomAccessStreamReference activeIcon);
}
public enum ViewGrouping
public sealed class ViewModePreferences {
ViewGrouping GroupingPreference { get; set; }
}
}
namespace Windows.UI.ViewManagement.Core {
public sealed class CoreInputView {
bool TryHide();
bool TryShow();
bool TryShow(CoreInputViewKind type);
}
public enum CoreInputViewKind
}
namespace Windows.UI.Xaml.Controls {
public class NavigationView : ContentControl {
bool IsTopNavigationForcedHidden { get; set; }
NavigationViewOrientation Orientation { get; set; }
UIElement TopNavigationContentOverlayArea { get; set; }
UIElement TopNavigationLeftHeader { get; set; }
UIElement TopNavigationMiddleHeader { get; set; }
UIElement TopNavigationRightHeader { get; set; }
}
public enum NavigationViewOrientation
public sealed class PasswordBox : Control {
bool CanPasteClipboardContent { get; }
public static DependencyProperty CanPasteClipboardContentProperty { get; }
void PasteFromClipboard();
}
public class RichEditBox : Control {
RichEditTextDocument RichEditDocument { get; }
}
public sealed class RichTextBlock : FrameworkElement {
void CopySelectionToClipboard();
}
public class SplitButton : ContentControl
public sealed class SplitButtonClickEventArgs
public enum SplitButtonOrientation
public sealed class TextBlock : FrameworkElement {
void CopySelectionToClipboard();
}
public class TextBox : Control {
bool CanPasteClipboardContent { get; }
public static DependencyProperty CanPasteClipboardContentProperty { get; }
bool CanRedo { get; }
public static DependencyProperty CanRedoProperty { get; }
bool CanUndo { get; }
public static DependencyProperty CanUndoProperty { get; }
void CopySelectionToClipboard();
void CutSelectionToClipboard();
void PasteFromClipboard();
void Redo();
void Undo();
}
public sealed class WebView : FrameworkElement {
event TypedEventHandler<WebView, WebViewWebResourceRequestedEventArgs> WebResourceRequested;
}
public sealed class WebViewWebResourceRequestedEventArgs
}
namespace Windows.UI.Xaml.Controls.Primitives {
public class FlyoutBase : DependencyObject {
FlyoutShowMode ShowMode { get; set; }
public static DependencyProperty ShowModeProperty { get; }
public static DependencyProperty TargetProperty { get; }
void Show(FlyoutShowOptions showOptions);
}
public enum FlyoutPlacementMode {
BottomLeftJustified = 7,
BottomRightJustified = 8,
LeftBottomJustified = 10,
LeftTopJustified = 9,
RightBottomJustified = 12,
RightTopJustified = 11,
TopLeftJustified = 5,
TopRightJustified = 6,
}
public enum FlyoutShowMode
public sealed class FlyoutShowOptions : DependencyObject
}
namespace Windows.UI.Xaml.Hosting {
public sealed class XamlBridge : IClosable
}
namespace Windows.UI.Xaml.Markup {
public sealed class FullXamlMetadataProviderAttribute : Attribute
}

Announcing Windows Server 2019 Insider Preview Build 17666

Hello Windows Insiders!
Today we are pleased to release a new build of the Windows Server vNext Long-Term Servicing Channel (LTSC) release that contains both the Desktop Experience as well as Server Core in all 18 server languages, as well as a new build of the next Windows Server Semi-Annual Channel release.
There are two major areas that we would like you to try out in each preview release and report back any issues:
In-place OS Upgrade (from Windows Server 2012 R2, Windows Server 2016)
Application compatibility – please let us know if any server roles or applications stops working or fails to function as it used to
What’s New in the Latest Build
Click here to see the full list of new features introduced in earlier builds.
Performance history for Storage Spaces Direct
This build improves the Get-ClusterPerformanceHistory cmdlet to be more scripting-friendly. It’s now convenient to pipe performance history into utility cmdlets like Sort-Object, Where-Object, and Measure-Object so you can quickly find the average or peak value, filter values, plot trend lines, run outlier detection, and more. You can see examples with these cmdlets in the topics linked under “Insider Preview content” on aka.ms/StorageSpacesDirect.
This build adds performance history for the Storage Spaces Direct cache for reads (% hit rate) and writes (% full), as well as the CSV in-memory read cache (% hit rate). These new series are available per-server and in aggregate.
Some performance history series have changed names in this build for greater clarity and consistency—for example, Node.Cpu.Usage is now ClusterNode.Cpu.Usage. Note that this change will result in some blank charts in Windows Admin Center until its next update.
Delimit volume allocation with Storage Spaces Direct
New cmdlets, provided in this build, simplify the management of volumes with delimited allocation. Use Get-StorageScaleUnit to see fault domains; follow associations to/from Get-VirtualDisk to see the current allocation; and set or modify allocation by using friendly names for fault domains. For more details, see the links under “Insider Preview content” on aka.ms/StorageSpacesDirect.
Available Content
Windows Server 2019 Preview is available in ISO format in 18 languages, and in VHDX format in English only. This build and all future pre-release builds will require the use of activation keys during setup. The following keys allow for unlimited activations:
Datacenter Edition
 6XBNX-4JQGW-QX6QG-74P76-72V67
Standard Edition
 MFY9F-XBN2F-TYFMP-CCV49-RMYVH
Windows Server vNext Semi-Annual Preview The Server Core Edition is available in English only, in ISO or VHDX format. The images are pre-keyed –  no need to enter a key during setup.
Symbols are available on the public symbol server – see Update on Microsoft’s Symbol Server blog post and Using the Microsoft Symbol Server. As before, matching Windows Server container images will be available via Docker Hub. For more information about Windows Server containers and Insider builds, click here.
This build will expire December 14th, 2018.
How to Download 
To obtain the Insider software downloads, registered Insiders may navigate directly to the Windows Server Insider Preview download page.  If you have not yet registered as an Insider, see GETTING STARTED WITH SERVER on the Windows Insiders for Business portal.
We value your feedback!
Use your registered Windows 10 Insider device and use the Feedback Hub application. In the app, choose the Server category and then the appropriate subcategory for your feedback. Please indicate what build number you are providing feedback on. We also encourage you to visit the Windows Server Insiders space on the Microsoft Tech Communities forum to collaborate, share and learn from experts.
Known Issues
The size of a file according to NTFS and a stream control block can become different from the size according to Cache Manager. This might cause a bug check if a read operation is out of bounds for the file size that Cache Manager has stored.
Inplace OS upgrade: Domain Controllers. During an in-place OS upgrade, Active Directory (AD) Domain Controllers (DC) might not be upgraded correctly. So, back up any AD DCs before performing an in-place OS upgrade.
Editing or creating policies for AppLocker can cause the MMC snap-in to crash when generated rules for a packaged app.
After upgrading the operating system, the AppX database may have corrupted entries, which causes problems for components that use those entries.
Terms of Use
This is pre-release software – it is provided for use “as-is” and is not supported in production environments. Users are responsible for installing any updates made available from Windows Update for as long as this build is available   All pre-release software made available to you via the Windows Server Insider Program are governed by the Insider Terms of Use, which takes precedence over any license agreement that may be in the product.
No downtime for Hustle-As-A-Service,
Dona

Announcing the Insider Dev Tour 2018!

Hello friends!
Yes, the rumor-mill was right (this time!). It’s time for the Insider Dev Tour.
Each year after Build, we run a world-wide event tour to bring all the latest technology to you, in person. This year we’ve extended the event to even more locations through our partnerships with Windows, the Windows Insider program, and our developer and Insider MVPs.

The Insider Dev Tour is for developers and code curious folks interested in building intelligent experiences today using the latest Microsoft technologies. It’s also for those who want a peek into the future of what kinds of tech will be super-important in every industry. This event is open to anyone who can read code or WANTS to read code– beginner, expert, student, or hobbyist developer.
You’ll learn about Artificial Intelligence, the latest for desktop development, Microsoft 365, Progressive Web Apps, Office for developers, Mixed Reality, Microsoft Graph, and much more. You’ll learn little-known tricks and tips that will help you be more efficient and awesome in your careers, no matter what those careers might be.
The tour is an opportunity to connect directly with leads and engineers from Redmond, as well as regional industry leads and Microsoft Developer MVPs. We’re excited to meet you in person.
The event agenda and session details are all posted on the registration site. We hope to see you there!
Find your local city and Register Now! 
Thank you—and see you there!
Pete & Dona
#InsiderDevTour