diff --git a/.github/workflows/deploy-preview-legacy.yml b/.github/workflows/deploy-preview-legacy.yml
index cf3c6cc7572b..904117f8b793 100644
--- a/.github/workflows/deploy-preview-legacy.yml
+++ b/.github/workflows/deploy-preview-legacy.yml
@@ -48,6 +48,12 @@ jobs:
$xmlDoc.Package.Identity.Publisher="$env:SIDELOAD_PUBLISHER_SECRET"
$xmlDoc.Package.Properties.DisplayName="Files - Preview"
$xmlDoc.Package.Applications.Application.VisualElements.DisplayName="Files - Preview"
+ $nsmgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
+ $nsmgr.AddNamespace("pkg", "http://schemas.microsoft.com/appx/manifest/foundation/windows10")
+ $alias = $xmlDoc.SelectSingleNode("/pkg:Package/pkg:Applications/pkg:Application/pkg:Extensions/uap5:Extension[@Name='windows.protocol']", $nsmgr)
+ $alias.Value="files-pre.exe"
+ $uriScheme = $xmlDoc.SelectSingleNode("/pkg:Package/pkg:Applications/pkg:Application/pkg:Extensions/uap5:Extension[@Name='windows.appExecutionAlias']", $nsmgr)
+ $uriScheme.Value="files-pre:"
$xmlDoc.Save("$env:PACKAGE_PROJECT_DIR\Package.appxmanifest")
env:
SIDELOAD_PUBLISHER_SECRET: ${{ secrets.SIDELOAD_PUBLISHER_SECRET }}
@@ -94,6 +100,26 @@ jobs:
env:
GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
+ - name: Inject the application execution alias
+ run: |
+ Get-ChildItem "$env:WORKING_DIR\src" -Include *.cs -recurse | ForEach-Object -Process `
+ { `
+ (Get-Content $_ -Raw | ForEach-Object -Process { $_ -replace "files.alias.key", "files-pre.exe" }) | `
+ Set-Content $_ -NoNewline `
+ }
+ env:
+ GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
+
+ - name: Inject the application URI scheme
+ run: |
+ Get-ChildItem "$env:WORKING_DIR\src" -Include *.cs -recurse | ForEach-Object -Process `
+ { `
+ (Get-Content $_ -Raw | ForEach-Object -Process { $_ -replace "files.urischeme.key", "files-pre:" }) | `
+ Set-Content $_ -NoNewline `
+ }
+ env:
+ GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
+
- name: Use Windows SDK Preview
shell: cmd
run: |
diff --git a/.github/workflows/deploy-stable-legacy.yml b/.github/workflows/deploy-stable-legacy.yml
index 64dc136979d9..59ca264691b5 100644
--- a/.github/workflows/deploy-stable-legacy.yml
+++ b/.github/workflows/deploy-stable-legacy.yml
@@ -48,6 +48,12 @@ jobs:
$xmlDoc.Package.Identity.Publisher="$env:SIDELOAD_PUBLISHER_SECRET"
$xmlDoc.Package.Properties.DisplayName="Files"
$xmlDoc.Package.Applications.Application.VisualElements.DisplayName="Files"
+ $nsmgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
+ $nsmgr.AddNamespace("pkg", "http://schemas.microsoft.com/appx/manifest/foundation/windows10")
+ $alias = $xmlDoc.SelectSingleNode("/pkg:Package/pkg:Applications/pkg:Application/pkg:Extensions/uap5:Extension[@Name='windows.appExecutionAlias']", $nsmgr)
+ $alias.Value="files.exe"
+ $alias = $xmlDoc.SelectSingleNode("/pkg:Package/pkg:Applications/pkg:Application/pkg:Extensions/uap5:Extension[@Name='windows.protocol']", $nsmgr)
+ $alias.Value="files-pre.exe"
$xmlDoc.Save("$env:PACKAGE_PROJECT_DIR\Package.appxmanifest")
env:
SIDELOAD_PUBLISHER_SECRET: ${{ secrets.SIDELOAD_PUBLISHER_SECRET }}
@@ -94,6 +100,26 @@ jobs:
env:
GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
+ - name: Inject the application execution alias
+ run: |
+ Get-ChildItem "$env:WORKING_DIR\src" -Include *.cs -recurse | ForEach-Object -Process `
+ { `
+ (Get-Content $_ -Raw | ForEach-Object -Process { $_ -replace "files.alias.key", "files.exe" }) | `
+ Set-Content $_ -NoNewline `
+ }
+ env:
+ GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
+
+ - name: Inject the application URI scheme
+ run: |
+ Get-ChildItem "$env:WORKING_DIR\src" -Include *.cs -recurse | ForEach-Object -Process `
+ { `
+ (Get-Content $_ -Raw | ForEach-Object -Process { $_ -replace "files.urischeme.key", "files:" }) | `
+ Set-Content $_ -NoNewline `
+ }
+ env:
+ GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
+
- name: Use Windows SDK Preview
shell: cmd
run: |
diff --git a/src/Files.App (Package)/Package.appxmanifest b/src/Files.App (Package)/Package.appxmanifest
index 1fa1a0246ad8..360342ce8472 100644
--- a/src/Files.App (Package)/Package.appxmanifest
+++ b/src/Files.App (Package)/Package.appxmanifest
@@ -119,12 +119,12 @@
-
+
-
+
diff --git a/src/Files.App/Actions/Navigation/OpenInNewWindowItemAction.cs b/src/Files.App/Actions/Navigation/OpenInNewWindowItemAction.cs
index 0731ac707b3d..66949bb597e1 100644
--- a/src/Files.App/Actions/Navigation/OpenInNewWindowItemAction.cs
+++ b/src/Files.App/Actions/Navigation/OpenInNewWindowItemAction.cs
@@ -48,7 +48,7 @@ public async Task ExecuteAsync(object? parameter = null)
foreach (ListedItem listedItem in items)
{
var selectedItemPath = (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath;
- var folderUri = new Uri($"files-uwp:?folder={@selectedItemPath}");
+ var folderUri = new Uri(Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable + $"?folder={@selectedItemPath}");
await Launcher.LaunchUriAsync(folderUri);
}
diff --git a/src/Files.App/Constants.cs b/src/Files.App/Constants.cs
index 92dbb2a85660..ddec4461fbd7 100644
--- a/src/Files.App/Constants.cs
+++ b/src/Files.App/Constants.cs
@@ -26,6 +26,27 @@ public static class AutomatedWorkflowInjectionKeys
public const string GitHubClientId = "githubclientid.secret";
public const string BingMapsSecret = "bingmapskey.secret";
+
+ public const string FilesExecutionAliasVariable = "files.alias.key";
+
+ public const string FilesExecutionAliasVariableEscaped = "files/alias/key";
+
+ public const string FilesExecutionAliasStaticStable = "files.exe";
+
+ public const string FilesExecutionAliasStaticPreview = "files-pre.exe";
+
+ public const string FilesExecutionAliasStaticDev = "files-dev.exe";
+
+ public const string FilesUriSchemaVariable = "files.urischeme.key";
+
+ public const string FilesUriSchemaVariableEscaped = "files/urischeme/key";
+
+ public const string FilesUriSchemaStaticStable = "files:";
+
+ public const string FilesUriSchemaStaticPreview = "files-pre:";
+
+ public const string FilesUriSchemaStaticDev = "files-dev:";
+
}
public static class KnownImageFormats
diff --git a/src/Files.App/Helpers/Application/AppLifecycleHelper.cs b/src/Files.App/Helpers/Application/AppLifecycleHelper.cs
index 67fb24dc9542..6b03c0dcbb9c 100644
--- a/src/Files.App/Helpers/Application/AppLifecycleHelper.cs
+++ b/src/Files.App/Helpers/Application/AppLifecycleHelper.cs
@@ -58,6 +58,16 @@ public static class AppLifecycleHelper
_ => Constants.AssetPaths.StableLogo
});
+ public static string AppExecutionAlias { get; } =
+ Constants.AutomatedWorkflowInjectionKeys.FilesExecutionAliasVariable == Constants.AutomatedWorkflowInjectionKeys.FilesExecutionAliasVariableEscaped.Replace('/', '.')
+ ? Constants.AutomatedWorkflowInjectionKeys.FilesExecutionAliasStaticDev
+ : Constants.AutomatedWorkflowInjectionKeys.FilesExecutionAliasVariable;
+
+ public static string AppURIScheme { get; } =
+ Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable == Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariableEscaped.Replace('/', '.')
+ ? Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaStaticDev
+ : Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable;
+
///
/// Initializes the app components.
///
@@ -359,7 +369,7 @@ public static void HandleAppUnhandledException(Exception? ex, bool showToastNoti
// Try to re-launch and start over
MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(async () =>
{
- await Launcher.LaunchUriAsync(new Uri("files-uwp:"));
+ await Launcher.LaunchUriAsync(new Uri(Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable));
})
.Wait(100);
}
diff --git a/src/Files.App/Helpers/Navigation/NavigationHelpers.cs b/src/Files.App/Helpers/Navigation/NavigationHelpers.cs
index 0e962f49b3ae..37c8b4b5d3f0 100644
--- a/src/Files.App/Helpers/Navigation/NavigationHelpers.cs
+++ b/src/Files.App/Helpers/Navigation/NavigationHelpers.cs
@@ -250,14 +250,14 @@ public static Task OpenPathInNewWindowAsync(string? path)
if (string.IsNullOrWhiteSpace(path))
return Task.FromResult(false);
- var folderUri = new Uri($"files-uwp:?folder={Uri.EscapeDataString(path)}");
+ var folderUri = new Uri(Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable + $"?folder={Uri.EscapeDataString(path)}");
return Launcher.LaunchUriAsync(folderUri).AsTask();
}
public static Task OpenTabInNewWindowAsync(string tabArgs)
{
- var folderUri = new Uri($"files-uwp:?tab={Uri.EscapeDataString(tabArgs)}");
+ var folderUri = new Uri(Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable + $"?tab={Uri.EscapeDataString(tabArgs)}");
return Launcher.LaunchUriAsync(folderUri).AsTask();
}
@@ -271,7 +271,7 @@ public static void OpenInSecondaryPane(IShellPage associatedInstance, ListedItem
public static Task LaunchNewWindowAsync()
{
- var filesUWPUri = new Uri("files-uwp:?window=");
+ var filesUWPUri = new Uri(Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable + $"?window=");
return Launcher.LaunchUriAsync(filesUWPUri).AsTask();
}
diff --git a/src/Files.App/MainWindow.xaml.cs b/src/Files.App/MainWindow.xaml.cs
index b6bfcceb6f9d..3d3972c9127b 100644
--- a/src/Files.App/MainWindow.xaml.cs
+++ b/src/Files.App/MainWindow.xaml.cs
@@ -71,7 +71,7 @@ public async Task InitializeApplicationAsync(object activatedEventArgs)
{
case ILaunchActivatedEventArgs launchArgs:
if (launchArgs.Arguments is not null &&
- (CommandLineParser.SplitArguments(launchArgs.Arguments, true)[0].EndsWith($"files.exe", StringComparison.OrdinalIgnoreCase)
+ (CommandLineParser.SplitArguments(launchArgs.Arguments, true)[0].EndsWith(Constants.AutomatedWorkflowInjectionKeys.FilesExecutionAliasVariable, StringComparison.OrdinalIgnoreCase)
|| CommandLineParser.SplitArguments(launchArgs.Arguments, true)[0].EndsWith($"files", StringComparison.OrdinalIgnoreCase)))
{
// WINUI3: When launching from commandline the argument is not ICommandLineActivatedEventArgs (#10370)
@@ -101,7 +101,7 @@ public async Task InitializeApplicationAsync(object activatedEventArgs)
break;
case IProtocolActivatedEventArgs eventArgs:
- if (eventArgs.Uri.AbsoluteUri == "files-uwp:")
+ if (eventArgs.Uri.AbsoluteUri == Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable)
{
rootFrame.Navigate(typeof(MainPage), null, new SuppressNavigationTransitionInfo());
diff --git a/src/Files.App/Program.cs b/src/Files.App/Program.cs
index 69a4cb1e7993..daea5d9cf2b0 100644
--- a/src/Files.App/Program.cs
+++ b/src/Files.App/Program.cs
@@ -217,7 +217,7 @@ static bool ProcessPathPredicate(Process p)
var cmdLaunchArgs = activatedArgs.Data is ILaunchActivatedEventArgs launchArgs &&
launchArgs.Arguments is not null &&
CommandLineParser.SplitArguments(launchArgs.Arguments, true).FirstOrDefault() is string arg0 &&
- (arg0.EndsWith($"files.exe", StringComparison.OrdinalIgnoreCase) ||
+ (arg0.EndsWith(Constants.AutomatedWorkflowInjectionKeys.FilesExecutionAliasVariable, StringComparison.OrdinalIgnoreCase) ||
arg0.EndsWith($"files", StringComparison.OrdinalIgnoreCase)) ? launchArgs.Arguments : null;
var cmdProtocolArgs = activatedArgs.Data is IProtocolActivatedEventArgs protocolArgs &&
protocolArgs.Uri.Query.TrimStart('?').Split('=') is string[] parsedArgs &&
diff --git a/src/Files.App/Utils/Taskbar/SystemTrayIcon.cs b/src/Files.App/Utils/Taskbar/SystemTrayIcon.cs
index e94566279925..0f7f25a516a9 100644
--- a/src/Files.App/Utils/Taskbar/SystemTrayIcon.cs
+++ b/src/Files.App/Utils/Taskbar/SystemTrayIcon.cs
@@ -264,7 +264,7 @@ private void OnLeftClicked()
{
_lastLaunchDate = DateTime.Now;
- _ = Launcher.LaunchUriAsync(new Uri("files-uwp:"));
+ _ = Launcher.LaunchUriAsync(new Uri(Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable));
}
else
MainWindow.Instance.Activate();
diff --git a/src/Files.App/ViewModels/Settings/GeneralViewModel.cs b/src/Files.App/ViewModels/Settings/GeneralViewModel.cs
index cfa12ba59c89..d475717b4d3f 100644
--- a/src/Files.App/ViewModels/Settings/GeneralViewModel.cs
+++ b/src/Files.App/ViewModels/Settings/GeneralViewModel.cs
@@ -121,7 +121,7 @@ private async void DoRestartAsync()
AppLifecycleHelper.SaveSessionTabs();
// Launches a new instance of Files
- await Launcher.LaunchUriAsync(new Uri("files-uwp:"));
+ await Launcher.LaunchUriAsync(new Uri(Constants.AutomatedWorkflowInjectionKeys.FilesUriSchemaVariable));
// Closes the current instance
Process.GetCurrentProcess().Kill();