diff --git a/DevHome.sln b/DevHome.sln
index dac61696af..c02985c1ea 100644
--- a/DevHome.sln
+++ b/DevHome.sln
@@ -122,6 +122,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevSetupAgent.Test", "exten
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HyperVExtension.HostGuestCommunication", "extensions\HyperVExtension\src\HyperVExtension.HostGuestCommunication\HyperVExtension.HostGuestCommunication.csproj", "{D759CD66-494C-4A00-8075-8B65A9891349}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevHome.PI", "tools\PI\DevHome.PI\DevHome.PI.csproj", "{CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PI", "PI", "{DB3D0F2C-1A7F-44B4-B408-B21A56212985}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Customization", "Customization", "{623998FD-B0A6-4980-95D5-A5072301CA10}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevHome.Customization", "tools\Customization\DevHome.Customization\DevHome.Customization.csproj", "{AF527EA4-6A24-4BD6-BC6E-A5863DC3489C}"
@@ -614,6 +618,18 @@ Global
{D759CD66-494C-4A00-8075-8B65A9891349}.Release|x64.Build.0 = Release|x64
{D759CD66-494C-4A00-8075-8B65A9891349}.Release|x86.ActiveCfg = Release|x86
{D759CD66-494C-4A00-8075-8B65A9891349}.Release|x86.Build.0 = Release|x86
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Debug|arm64.ActiveCfg = Debug|ARM64
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Debug|arm64.Build.0 = Debug|ARM64
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Debug|x64.ActiveCfg = Debug|x64
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Debug|x64.Build.0 = Debug|x64
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Debug|x86.ActiveCfg = Debug|x86
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Debug|x86.Build.0 = Debug|x86
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Release|arm64.ActiveCfg = Release|ARM64
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Release|arm64.Build.0 = Release|ARM64
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Release|x64.ActiveCfg = Release|x64
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Release|x64.Build.0 = Release|x64
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Release|x86.ActiveCfg = Release|x86
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725}.Release|x86.Build.0 = Release|x86
{AF527EA4-6A24-4BD6-BC6E-A5863DC3489C}.Debug|arm64.ActiveCfg = Debug|arm64
{AF527EA4-6A24-4BD6-BC6E-A5863DC3489C}.Debug|arm64.Build.0 = Debug|arm64
{AF527EA4-6A24-4BD6-BC6E-A5863DC3489C}.Debug|x64.ActiveCfg = Debug|x64
@@ -745,6 +761,8 @@ Global
{F4095FD3-6A3F-490B-966D-E63059612EE6} = {3E3791DF-070D-4ADE-96E8-93D6FBD53953}
{0E05A442-BDC7-43D4-A000-F8C986826716} = {3E3791DF-070D-4ADE-96E8-93D6FBD53953}
{D759CD66-494C-4A00-8075-8B65A9891349} = {81AACED5-CFB5-47A6-AFD6-4625AADCFFA3}
+ {CAAC0CDF-9AB8-4F43-A3EB-38D785AF5725} = {DB3D0F2C-1A7F-44B4-B408-B21A56212985}
+ {DB3D0F2C-1A7F-44B4-B408-B21A56212985} = {A972EC5B-FC61-4964-A6FF-F9633EB75DFD}
{623998FD-B0A6-4980-95D5-A5072301CA10} = {A972EC5B-FC61-4964-A6FF-F9633EB75DFD}
{AF527EA4-6A24-4BD6-BC6E-A5863DC3489C} = {623998FD-B0A6-4980-95D5-A5072301CA10}
{FAB6FAA7-ADF4-4B65-9831-0C819915E6E1} = {A972EC5B-FC61-4964-A6FF-F9633EB75DFD}
diff --git a/common/DevHome.Common.csproj b/common/DevHome.Common.csproj
index 5e046bf8ec..8898b85f83 100644
--- a/common/DevHome.Common.csproj
+++ b/common/DevHome.Common.csproj
@@ -55,7 +55,7 @@
-
+
diff --git a/common/Helpers/RuntimeHelper.cs b/common/Helpers/RuntimeHelper.cs
index 7ab541f6f2..1fb3af8d43 100644
--- a/common/Helpers/RuntimeHelper.cs
+++ b/common/Helpers/RuntimeHelper.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
using System;
+using System.Security.Principal;
using Windows.Win32;
using Windows.Win32.Foundation;
@@ -27,4 +28,10 @@ public static bool IsOnWindows11
return version.Major >= 10 && version.Build >= 22000;
}
}
+
+ public static bool IsCurrentProcessRunningAsAdmin()
+ {
+ var identity = WindowsIdentity.GetCurrent();
+ return identity.Owner?.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) ?? false;
+ }
}
diff --git a/common/Services/StringResource.cs b/common/Services/StringResource.cs
index 068f7b5f78..c4628b65f2 100644
--- a/common/Services/StringResource.cs
+++ b/common/Services/StringResource.cs
@@ -48,7 +48,12 @@ public string GetLocalized(string key, params object[] args)
try
{
value = _resourceLoader.GetString(key);
- value = string.Format(CultureInfo.CurrentCulture, value, args);
+
+ // only replace the placeholders if args is not empty
+ if (args.Length > 0)
+ {
+ value = string.Format(CultureInfo.CurrentCulture, value, args);
+ }
}
catch
{
diff --git a/settings/DevHome.Settings/Strings/en-us/Resources.resw b/settings/DevHome.Settings/Strings/en-us/Resources.resw
index 812608237b..f13444365a 100644
--- a/settings/DevHome.Settings/Strings/en-us/Resources.resw
+++ b/settings/DevHome.Settings/Strings/en-us/Resources.resw
@@ -1,17 +1,17 @@
-
@@ -547,11 +547,19 @@
Quiet background processes
- Name of experimental feature 'Quiet background processes' on the 'Settings -> Experiments' page where you enable it.
+ Name of experimental feature 'Quiet background processes' on the 'Settings -> Experiments' page where you enable it.
Quiet background processes allows you to free up resources while developing
- Inline description of the Quiet background processes experimental feature on the 'Settings -> Experiments' page where you enable it.
+ Inline description of the Quiet background processes experimental feature on the 'Settings -> Experiments' page where you enable it.
+
+
+ Project Ironsides
+ Name of experimental feature 'Project Ironsides' on the 'Settings -> Experiments' page where you enable it.
+
+
+ Project Ironsides is a utlity to provide deeper insights into your applications
+ Inline description of the Project Ironsides experimental feature on the 'Settings -> Experiments' page where you enable it.
Quickstart Playground
diff --git a/src/App.xaml.cs b/src/App.xaml.cs
index bcaf2fa4ab..49dd47ec9a 100644
--- a/src/App.xaml.cs
+++ b/src/App.xaml.cs
@@ -209,6 +209,8 @@ await Task.WhenAll(
private async void OnActivated(object? sender, AppActivationArguments args)
{
+ ShowMainWindow();
+
// Note: Keep the reference to 'args.Data' object, as 'args' may be
// disposed before the async operation completes (RpcCallFailed: 0x800706be)
var localArgsDataReference = args.Data;
diff --git a/src/DevHome.csproj b/src/DevHome.csproj
index 2185386a5a..18555a5eb2 100644
--- a/src/DevHome.csproj
+++ b/src/DevHome.csproj
@@ -77,7 +77,7 @@
-
+
@@ -86,6 +86,7 @@
+
diff --git a/src/NavConfig.jsonc b/src/NavConfig.jsonc
index 948f31682c..3c47f1a159 100644
--- a/src/NavConfig.jsonc
+++ b/src/NavConfig.jsonc
@@ -86,6 +86,27 @@
"visible": true
}
]
+ },
+ {
+ "identity": "ProjectIronsidesExperiment",
+ "enabledByDefault": false,
+ "buildTypeOverrides": [
+ {
+ "buildType": "dev",
+ "enabledByDefault": true,
+ "visible": true
+ },
+ {
+ "buildType": "canary",
+ "enabledByDefault": true,
+ "visible": true
+ },
+ {
+ "buildType": "stable",
+ "enabledByDefault": false,
+ "visible": true
+ }
+ ]
}
]
}
diff --git a/src/Package.appxmanifest b/src/Package.appxmanifest
index 9d26a5e0c8..66de1e44c5 100644
--- a/src/Package.appxmanifest
+++ b/src/Package.appxmanifest
@@ -286,6 +286,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Program.cs b/src/Program.cs
index 259b62e784..aa96561bed 100644
--- a/src/Program.cs
+++ b/src/Program.cs
@@ -1,17 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
+using System.Diagnostics;
+using DevHome.Services;
+using Microsoft.Extensions.Configuration;
using Microsoft.UI.Dispatching;
+using Serilog;
namespace DevHome;
public static class Program
{
+ private static readonly ILogger _log = Log.ForContext("SourceContext", nameof(Program));
private static App? _app;
[STAThread]
public static void Main(string[] args)
{
+ // Be sure to parse these args in this instance of the exe... don't redirect this to another instance for parsing which
+ // may be running in a different security context.
+ ParseCommandLine(args);
+
WinRT.ComWrappersSupport.InitializeComWrappers();
var isRedirect = DecideRedirection().GetAwaiter().GetResult();
@@ -34,11 +43,7 @@ private static async Task DecideRedirection()
var activatedEventArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
var isRedirect = false;
- if (mainInstance.IsCurrent)
- {
- mainInstance.Activated += OnActivated;
- }
- else
+ if (!mainInstance.IsCurrent)
{
// Redirect the activation (and args) to the "main" instance, and exit.
await mainInstance.RedirectActivationToAsync(activatedEventArgs);
@@ -48,8 +53,38 @@ private static async Task DecideRedirection()
return isRedirect;
}
- private static void OnActivated(object? sender, Microsoft.Windows.AppLifecycle.AppActivationArguments e)
+ // Currently DevHome supports one set of command line arguments, most useful when debugging different apps within the Dev Home package.
+ //
+ // For example:
+ // --utilitylaunch DevHome.PI.Exe --utilityLaunchArgs "--application problemapp2"
+ //
+ // --utilityLaunch is the name of the utility to launch
+ // --utilityLaunchArgs are the arguments to pass to the utility. This is optional, but be sure to include the quotes if you have spaces in the arguments.
+ private static void ParseCommandLine(string[] args)
{
- _app?.ShowMainWindow();
+ var builder = new ConfigurationBuilder();
+ builder.AddCommandLine(args);
+ var config = builder.Build();
+
+ var utilityToLaunch = config["utilitylaunch"];
+ var utilityLaunchArgs = config["utilitylaunchargs"];
+
+ if (!string.IsNullOrEmpty(utilityToLaunch))
+ {
+ try
+ {
+ var processStartInfo = new ProcessStartInfo
+ {
+ FileName = utilityToLaunch,
+ Arguments = utilityLaunchArgs,
+ };
+
+ Process.Start(processStartInfo);
+ }
+ catch (Exception ex)
+ {
+ _log.Error(ex, $"Error launching utility: {ex.Message}");
+ }
+ }
}
}
diff --git a/src/Strings/en-us/Resources.resw b/src/Strings/en-us/Resources.resw
index 1e15ef3671..a03ca81571 100644
--- a/src/Strings/en-us/Resources.resw
+++ b/src/Strings/en-us/Resources.resw
@@ -1,17 +1,17 @@
-
diff --git a/tools/PI/DevHome.PI/App.config b/tools/PI/DevHome.PI/App.config
new file mode 100644
index 0000000000..a0e35ba70a
--- /dev/null
+++ b/tools/PI/DevHome.PI/App.config
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 50
+ 350
+ 964
+ 680
+
+
+
+
+ Default
+
+
+ True
+
+
+ False
+
+
+
+
+ 70
+ 942
+ 640
+ 222
+
+
+
+
+ True
+
+
+
+
+ DevHome.PI
+ DevEnv
+
+
+
+
+ 0, 0
+
+
+
+
\ No newline at end of file
diff --git a/tools/PI/DevHome.PI/Assets/LargeTile.scale-100.png b/tools/PI/DevHome.PI/Assets/LargeTile.scale-100.png
new file mode 100644
index 0000000000..21b4ce23b0
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/LargeTile.scale-100.png differ
diff --git a/tools/PI/DevHome.PI/Assets/LargeTile.scale-125.png b/tools/PI/DevHome.PI/Assets/LargeTile.scale-125.png
new file mode 100644
index 0000000000..a220a5c00b
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/LargeTile.scale-125.png differ
diff --git a/tools/PI/DevHome.PI/Assets/LargeTile.scale-150.png b/tools/PI/DevHome.PI/Assets/LargeTile.scale-150.png
new file mode 100644
index 0000000000..e371b9c48c
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/LargeTile.scale-150.png differ
diff --git a/tools/PI/DevHome.PI/Assets/LargeTile.scale-200.png b/tools/PI/DevHome.PI/Assets/LargeTile.scale-200.png
new file mode 100644
index 0000000000..2e0bc6d103
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/LargeTile.scale-200.png differ
diff --git a/tools/PI/DevHome.PI/Assets/LargeTile.scale-400.png b/tools/PI/DevHome.PI/Assets/LargeTile.scale-400.png
new file mode 100644
index 0000000000..20aae7a3ac
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/LargeTile.scale-400.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SmallTile.scale-100.png b/tools/PI/DevHome.PI/Assets/SmallTile.scale-100.png
new file mode 100644
index 0000000000..4fb43db6c9
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SmallTile.scale-100.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SmallTile.scale-125.png b/tools/PI/DevHome.PI/Assets/SmallTile.scale-125.png
new file mode 100644
index 0000000000..d6fb697270
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SmallTile.scale-125.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SmallTile.scale-150.png b/tools/PI/DevHome.PI/Assets/SmallTile.scale-150.png
new file mode 100644
index 0000000000..94ae71b65e
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SmallTile.scale-150.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SmallTile.scale-200.png b/tools/PI/DevHome.PI/Assets/SmallTile.scale-200.png
new file mode 100644
index 0000000000..d3f373fa7f
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SmallTile.scale-200.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SmallTile.scale-400.png b/tools/PI/DevHome.PI/Assets/SmallTile.scale-400.png
new file mode 100644
index 0000000000..4207b09585
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SmallTile.scale-400.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SplashScreen.scale-100.png b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-100.png
new file mode 100644
index 0000000000..419dc47eb8
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-100.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SplashScreen.scale-125.png b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-125.png
new file mode 100644
index 0000000000..964d494333
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-125.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SplashScreen.scale-150.png b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-150.png
new file mode 100644
index 0000000000..88f5a5c310
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-150.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SplashScreen.scale-200.png b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-200.png
new file mode 100644
index 0000000000..ca6ba21537
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-200.png differ
diff --git a/tools/PI/DevHome.PI/Assets/SplashScreen.scale-400.png b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-400.png
new file mode 100644
index 0000000000..cc930ad3fe
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/SplashScreen.scale-400.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-100.png b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-100.png
new file mode 100644
index 0000000000..b245597f1f
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-100.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-125.png b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-125.png
new file mode 100644
index 0000000000..d089b82dd5
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-125.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-150.png b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-150.png
new file mode 100644
index 0000000000..d3494b147b
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-150.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-200.png b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-200.png
new file mode 100644
index 0000000000..e1fd5f5f3e
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-200.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-400.png b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-400.png
new file mode 100644
index 0000000000..5025a1dabd
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square150x150Logo.scale-400.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png
new file mode 100644
index 0000000000..79240cc51b
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png
new file mode 100644
index 0000000000..0184e07313
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png
new file mode 100644
index 0000000000..516a72eff2
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png
new file mode 100644
index 0000000000..ccd38cb652
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png
new file mode 100644
index 0000000000..5ecd627b82
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-16.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-16.png
new file mode 100644
index 0000000000..79240cc51b
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-16.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-24.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-24.png
new file mode 100644
index 0000000000..0184e07313
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-24.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-256.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-256.png
new file mode 100644
index 0000000000..516a72eff2
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-256.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-32.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-32.png
new file mode 100644
index 0000000000..ccd38cb652
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-32.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-48.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-48.png
new file mode 100644
index 0000000000..5ecd627b82
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.altform-unplated_targetsize-48.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-100.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-100.png
new file mode 100644
index 0000000000..54a7ca03ab
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-100.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-125.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-125.png
new file mode 100644
index 0000000000..6b82c206cf
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-125.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-150.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-150.png
new file mode 100644
index 0000000000..bfd92e92f3
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-150.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-200.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-200.png
new file mode 100644
index 0000000000..a85794002f
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-200.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-400.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-400.png
new file mode 100644
index 0000000000..a6790f198a
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.scale-400.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-16.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-16.png
new file mode 100644
index 0000000000..b348a6af40
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-16.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-24.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-24.png
new file mode 100644
index 0000000000..d0ec86e550
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-24.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-256.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-256.png
new file mode 100644
index 0000000000..bd28ced589
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-256.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-32.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-32.png
new file mode 100644
index 0000000000..b922287fed
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-32.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-48.png b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-48.png
new file mode 100644
index 0000000000..3f1d8537ba
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Square44x44Logo.targetsize-48.png differ
diff --git a/tools/PI/DevHome.PI/Assets/StoreLogo.backup.png b/tools/PI/DevHome.PI/Assets/StoreLogo.backup.png
new file mode 100644
index 0000000000..7385b56c0e
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/StoreLogo.backup.png differ
diff --git a/tools/PI/DevHome.PI/Assets/StoreLogo.scale-100.png b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-100.png
new file mode 100644
index 0000000000..09db289b3b
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-100.png differ
diff --git a/tools/PI/DevHome.PI/Assets/StoreLogo.scale-125.png b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-125.png
new file mode 100644
index 0000000000..07e090f005
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-125.png differ
diff --git a/tools/PI/DevHome.PI/Assets/StoreLogo.scale-150.png b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-150.png
new file mode 100644
index 0000000000..88a2abfb0f
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-150.png differ
diff --git a/tools/PI/DevHome.PI/Assets/StoreLogo.scale-200.png b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-200.png
new file mode 100644
index 0000000000..f8820d9109
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-200.png differ
diff --git a/tools/PI/DevHome.PI/Assets/StoreLogo.scale-400.png b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-400.png
new file mode 100644
index 0000000000..027cfdd182
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/StoreLogo.scale-400.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-100.png b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-100.png
new file mode 100644
index 0000000000..e0be5f18a9
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-100.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-125.png b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-125.png
new file mode 100644
index 0000000000..54eca79a0e
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-125.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-150.png b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-150.png
new file mode 100644
index 0000000000..7e72f1e000
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-150.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-200.png b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-200.png
new file mode 100644
index 0000000000..419dc47eb8
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-200.png differ
diff --git a/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-400.png b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-400.png
new file mode 100644
index 0000000000..ca6ba21537
Binary files /dev/null and b/tools/PI/DevHome.PI/Assets/Wide310x150Logo.scale-400.png differ
diff --git a/tools/PI/DevHome.PI/BarWindow.xaml b/tools/PI/DevHome.PI/BarWindow.xaml
new file mode 100644
index 0000000000..44799e8737
--- /dev/null
+++ b/tools/PI/DevHome.PI/BarWindow.xaml
@@ -0,0 +1,159 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/PI/DevHome.PI/BarWindow.xaml.cs b/tools/PI/DevHome.PI/BarWindow.xaml.cs
new file mode 100644
index 0000000000..0a25336942
--- /dev/null
+++ b/tools/PI/DevHome.PI/BarWindow.xaml.cs
@@ -0,0 +1,722 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using DevHome.Common.Extensions;
+using DevHome.PI.Controls;
+using DevHome.PI.Helpers;
+using DevHome.PI.Models;
+using DevHome.PI.Properties;
+using DevHome.PI.Telemetry;
+using DevHome.PI.ViewModels;
+using Microsoft.UI;
+using Microsoft.UI.Windowing;
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Xaml.Input;
+using Windows.UI.WindowManagement;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.Accessibility;
+using Windows.Win32.UI.WindowsAndMessaging;
+using WinRT.Interop;
+using WinUIEx;
+using static DevHome.PI.Helpers.WindowHelper;
+
+namespace DevHome.PI;
+
+public partial class BarWindow : WindowEx, INotifyPropertyChanged
+{
+ private readonly Settings settings = Settings.Default;
+ private readonly string errorTitleText = CommonHelper.GetLocalizedString("ToolLaunchErrorTitle");
+ private readonly string errorMessageText = CommonHelper.GetLocalizedString("ToolLaunchErrorMessage");
+ private readonly BarWindowViewModel viewModel = new();
+
+ // Constants that control window sizes
+ private const int WindowPositionOffsetY = 30;
+ private const int FloatingHorizontalBarWidth = 700;
+ private const int FloatingHorizontalBarHeight = 70;
+ private const int FloatingVerticalBarWidth = 70;
+ private const int FloatingVerticalBarHeight = 700;
+ private const int DefaultExpandedViewTop = 30;
+ private const int DefaultExpandedViewLeft = 100;
+ private const int RightSideGap = 10;
+
+ private readonly GridLength _gridLengthStar = new(1, GridUnitType.Star);
+ private int cursorPosX; // = 0;
+ private int cursorPosY; // = 0;
+ private int appWindowPosX; // = 0;
+ private int appWindowPosY; // = 0;
+ private bool isWindowMoving; // = false;
+
+ private Orientation _barOrientation = Orientation.Horizontal;
+
+ public Orientation BarOrientation
+ {
+ get => _barOrientation;
+ set
+ {
+ _barOrientation = value;
+
+ if (value == Orientation.Horizontal)
+ {
+ SBarHorizontal.Visibility = Visibility.Visible;
+ SBarVertical.Visibility = Visibility.Collapsed;
+ ExternalToolsRepeater.Layout = Application.Current.Resources["ExternalToolsHorizontalLayout"] as StackLayout;
+ MainPanelMiddleRowDefinition.Height = GridLength.Auto;
+ MainPanelLastRowDefinition.Height = _gridLengthStar;
+ SystemResourceStackPanel.SetValue(Grid.RowProperty, 0);
+ SystemResourceStackPanel.SetValue(Grid.ColumnProperty, 2);
+ TopGrid.HorizontalAlignment = HorizontalAlignment.Stretch;
+ }
+ else
+ {
+ SBarHorizontal.Visibility = Visibility.Collapsed;
+ SBarVertical.Visibility = Visibility.Visible;
+ ExternalToolsRepeater.Layout = Application.Current.Resources["ExternalToolsVerticalLayout"] as StackLayout;
+ MainPanelMiddleRowDefinition.Height = _gridLengthStar;
+ MainPanelLastRowDefinition.Height = GridLength.Auto;
+ SystemResourceStackPanel.SetValue(Grid.RowProperty, 2);
+ SystemResourceStackPanel.SetValue(Grid.ColumnProperty, 0);
+ TopGrid.HorizontalAlignment = HorizontalAlignment.Center;
+ }
+
+ OnPropertyChanged(nameof(BarOrientation));
+ }
+ }
+
+ private RECT monitorRect;
+
+ private RestoreState restoreState = new()
+ {
+ Top = DefaultExpandedViewTop,
+ Left = DefaultExpandedViewLeft,
+ BarOrientation = Orientation.Horizontal,
+ IsLargePanelVisible = true,
+ };
+
+ private const int UnsnapGap = 9;
+ private double dpiScale = 1.0;
+
+ private bool _isSnapped;
+
+ private bool IsSnapped
+ {
+ get => _isSnapped;
+ set
+ {
+ _isSnapped = value;
+ SBarHorizontal.IsSnapped = value;
+ SBarVertical.IsSnapped = value;
+ }
+ }
+
+ private bool _isMaximized;
+
+ private bool IsMaximized
+ {
+ get => _isMaximized;
+ set
+ {
+ _isMaximized = value;
+ SBarHorizontal.IsMaximized = value;
+ SBarVertical.IsMaximized = value;
+
+ if (value)
+ {
+ WindowState = WindowState.Maximized;
+ }
+ }
+ }
+
+ private readonly ObservableCollection