From 768c44567ada5bbfdbdecaa850efa9ad75946767 Mon Sep 17 00:00:00 2001
From: DB p
Date: Tue, 20 Sep 2022 19:22:13 +0900
Subject: [PATCH 01/36] Add Checkboxes and Adjust layout
---
Flow.Launcher.sln | 5 +-
.../Languages/en.xaml | 1 +
.../Views/SettingsControl.xaml | 69 +++++++++++--------
.../Views/SettingsControl.xaml.cs | 13 +++-
4 files changed, 55 insertions(+), 33 deletions(-)
diff --git a/Flow.Launcher.sln b/Flow.Launcher.sln
index ec4a29ee7..f8457dd1a 100644
--- a/Flow.Launcher.sln
+++ b/Flow.Launcher.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29806.167
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32901.215
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Test", "Flow.Launcher.Test\Flow.Launcher.Test.csproj", "{FF742965-9A80-41A5-B042-D6C7D3A21708}"
ProjectSection(ProjectDependencies) = postProject
@@ -80,7 +80,6 @@ Global
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x64.ActiveCfg = Debug|Any CPU
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x64.Build.0 = Debug|Any CPU
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x86.ActiveCfg = Debug|Any CPU
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
index 8f5396dd7..7c88708f5 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Languages/en.xaml
@@ -21,4 +21,5 @@
Data Directory Path
Add
Delete
+ Others
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
index 09ad2101b..a614cbfc2 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
@@ -8,40 +8,51 @@
d:DesignWidth="500"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+ BorderBrush="DarkGray"
+ BorderThickness="1"
+ ItemsSource="{Binding Settings.CustomChromiumBrowsers}"
+ MouseDoubleClick="MouseDoubleClickOnSelectedCustomBrowser"
+ SelectedItem="{Binding SelectedCustomBrowser}"
+ Style="{StaticResource {x:Static GridView.GridViewStyleKey}}">
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
index 5f5d3246c..e67c73923 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml.cs
@@ -1,7 +1,8 @@
-using System.Windows;
+using System.Windows;
using Flow.Launcher.Plugin.BrowserBookmark.Models;
using System.Windows.Input;
using System.ComponentModel;
+using System.Windows.Controls;
namespace Flow.Launcher.Plugin.BrowserBookmark.Views
{
@@ -59,5 +60,15 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Views
var window = new CustomBrowserSettingWindow(SelectedCustomBrowser);
window.ShowDialog();
}
+ private void Others_Click(object sender, RoutedEventArgs e)
+ {
+
+ if (CustomBrowsersList.Visibility == Visibility.Collapsed)
+ {
+ CustomBrowsersList.Visibility = Visibility.Visible;
+ }
+ else
+ CustomBrowsersList.Visibility = Visibility.Collapsed;
+ }
}
}
From 2189eaaa0ca56f9bbb2e145e8d37d7f3d966766d Mon Sep 17 00:00:00 2001
From: Hongtao Zhang
Date: Wed, 12 Oct 2022 16:11:15 -0500
Subject: [PATCH 02/36] Allow user to disable loading bookmark from certain
browser
---
.../Commands/BookmarkLoader.cs | 29 ++++---
.../Models/Settings.cs | 4 +
.../Views/SettingsControl.xaml | 80 ++++++++++---------
3 files changed, 66 insertions(+), 47 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs
index 40d10b26f..77d9c64a0 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs
@@ -19,21 +19,28 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands
internal static List LoadAllBookmarks(Settings setting)
{
-
- var chromeBookmarks = new ChromeBookmarkLoader();
- var mozBookmarks = new FirefoxBookmarkLoader();
- var edgeBookmarks = new EdgeBookmarkLoader();
-
var allBookmarks = new List();
- // Add Firefox bookmarks
- allBookmarks.AddRange(mozBookmarks.GetBookmarks());
+ if (setting.LoadChromeBookmark)
+ {
+ // Add Chrome bookmarks
+ var chromeBookmarks = new ChromeBookmarkLoader();
+ allBookmarks.AddRange(chromeBookmarks.GetBookmarks());
+ }
- // Add Chrome bookmarks
- allBookmarks.AddRange(chromeBookmarks.GetBookmarks());
+ if (setting.LoadFirefoxBookmark)
+ {
+ // Add Firefox bookmarks
+ var mozBookmarks = new FirefoxBookmarkLoader();
+ allBookmarks.AddRange(mozBookmarks.GetBookmarks());
+ }
- // Add Edge (Chromium) bookmarks
- allBookmarks.AddRange(edgeBookmarks.GetBookmarks());
+ if (setting.LoadEdgeBookmark)
+ {
+ // Add Edge (Chromium) bookmarks
+ var edgeBookmarks = new EdgeBookmarkLoader();
+ allBookmarks.AddRange(edgeBookmarks.GetBookmarks());
+ }
foreach (var browser in setting.CustomChromiumBrowsers)
{
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
index 5080ad301..17b794e03 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Models/Settings.cs
@@ -10,6 +10,10 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Models
public string BrowserPath { get; set; }
+ public bool LoadChromeBookmark { get; set; } = true;
+ public bool LoadFirefoxBookmark { get; set; } = true;
+ public bool LoadEdgeBookmark { get; set; } = true;
+
public ObservableCollection CustomChromiumBrowsers { get; set; } = new();
}
}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
index a614cbfc2..12a84cb5a 100644
--- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
+++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Views/SettingsControl.xaml
@@ -1,57 +1,65 @@
+ x:Class="Flow.Launcher.Plugin.BrowserBookmark.Views.SettingsControl"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ d:DesignHeight="300"
+ d:DesignWidth="500"
+ DataContext="{Binding RelativeSource={RelativeSource Self}}"
+ mc:Ignorable="d">
-
+
-
-
-
-
+
+
+
+
+ Margin="0,0,15,0"
+ Click="Others_Click"
+ Content="{DynamicResource flowlauncher_plugin_browserbookmark_others}"/>
+ Name="CustomBrowsers"
+ Height="auto"
+ Margin="10"
+ BorderBrush="DarkGray"
+ BorderThickness="1"
+ ItemsSource="{Binding Settings.CustomChromiumBrowsers}"
+ MouseDoubleClick="MouseDoubleClickOnSelectedCustomBrowser"
+ SelectedItem="{Binding SelectedCustomBrowser}"
+ Style="{StaticResource {x:Static GridView.GridViewStyleKey}}">
-
-
+
+
+ MinWidth="130"
+ Margin="10"
+ Click="NewCustomBrowser"
+ Content="{DynamicResource flowlauncher_plugin_browserbookmark_addBrowserBookmark}"/>
+ MinWidth="120"
+ Margin="10"
+ Click="DeleteCustomBrowser"
+ Content="{DynamicResource flowlauncher_plugin_browserbookmark_removeBrowserBookmark}"/>
From c5b384e4df3ad2bfdfb223adcb115818fafd32f2 Mon Sep 17 00:00:00 2001
From: DB P
Date: Fri, 25 Nov 2022 19:26:15 +0900
Subject: [PATCH 03/36] Update Flow.Launcher.sln
---
Flow.Launcher.sln | 1 +
1 file changed, 1 insertion(+)
diff --git a/Flow.Launcher.sln b/Flow.Launcher.sln
index f8457dd1a..1d403c5a1 100644
--- a/Flow.Launcher.sln
+++ b/Flow.Launcher.sln
@@ -80,6 +80,7 @@ Global
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x64.ActiveCfg = Debug|Any CPU
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x64.Build.0 = Debug|Any CPU
{FF742965-9A80-41A5-B042-D6C7D3A21708}.Debug|x86.ActiveCfg = Debug|Any CPU
From 0298f17a2bf40d8a670131671f3360acfbd867a0 Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 28 Nov 2022 03:13:28 +0900
Subject: [PATCH 04/36] - Change Preview Item to non-clickable - Fix Margin
when change shadow setting - Change Preview Item Texts to translatable
---
Flow.Launcher/Languages/en.xaml | 8 ++++++++
Flow.Launcher/SettingWindow.xaml | 18 +++++++++++++-----
.../ViewModel/SettingWindowViewModel.cs | 16 ++++++++--------
3 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index cf6199098..01be5ebc8 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -116,6 +116,14 @@
Theme Gallery
How to create a theme
Hi There
+ Explorer
+ Search for files, folders and file contents
+ WebSearch
+ Search the web with different search engine support
+ Program
+ Launch programs as admin or a different user
+ ProcessKiller
+ Terminate unwanted processes
Query Box Font
Result Item Font
Window Mode
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index c364439a0..b1cfe790d 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -443,10 +443,9 @@
Margin="2,2,2,0"
Panel.ZIndex="1"
Background="Transparent"
- IsItemsHost="true"
+ IsItemsHost="true"
LastChildFill="False" />
-
+
@@ -1779,7 +1778,12 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
-
+
@@ -1797,6 +1801,7 @@
@@ -1834,7 +1839,10 @@
-
+
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 858588dae..f63a5e5bf 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -609,26 +609,26 @@ namespace Flow.Launcher.ViewModel
{
new Result
{
- Title = "Explorer",
- SubTitle = "Search for files, folders and file contents",
+ Title = InternationalizationManager.Instance.GetTranslation("SampleTitleExplorer"),
+ SubTitle = InternationalizationManager.Instance.GetTranslation("SampleSubTitleExplorer"),
IcoPath = Path.Combine(Constant.ProgramDirectory, @"Plugins\Flow.Launcher.Plugin.Explorer\Images\explorer.png")
},
new Result
{
- Title = "WebSearch",
- SubTitle = "Search the web with different search engine support",
+ Title = InternationalizationManager.Instance.GetTranslation("SampleTitleWebSearch"),
+ SubTitle = InternationalizationManager.Instance.GetTranslation("SampleSubTitleWebSearch"),
IcoPath = Path.Combine(Constant.ProgramDirectory, @"Plugins\Flow.Launcher.Plugin.WebSearch\Images\web_search.png")
},
new Result
{
- Title = "Program",
- SubTitle = "Launch programs as admin or a different user",
+ Title = InternationalizationManager.Instance.GetTranslation("SampleTitleProgram"),
+ SubTitle = InternationalizationManager.Instance.GetTranslation("SampleSubTitleProgram"),
IcoPath = Path.Combine(Constant.ProgramDirectory, @"Plugins\Flow.Launcher.Plugin.Program\Images\program.png")
},
new Result
{
- Title = "ProcessKiller",
- SubTitle = "Terminate unwanted processes",
+ Title = InternationalizationManager.Instance.GetTranslation("SampleTitleProcessKiller"),
+ SubTitle = InternationalizationManager.Instance.GetTranslation("SampleSubTitleProcessKiller"),
IcoPath = Path.Combine(Constant.ProgramDirectory, @"Plugins\Flow.Launcher.Plugin.ProcessKiller\Images\app.png")
}
};
From afc0946eda2fb9a2f8c2b55b3681577e128f7f27 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 15:51:28 +0800
Subject: [PATCH 05/36] Use winRT api for uwp info and logo
---
.../Programs/UWP.cs | 132 +++++++++++++++++-
1 file changed, 129 insertions(+), 3 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 8a731f5b9..688f112af 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -19,6 +19,8 @@ using Rect = System.Windows.Rect;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.Infrastructure.Logger;
using System.Threading.Channels;
+using Windows.Storage.Streams;
+using System.Xml;
namespace Flow.Launcher.Plugin.Program.Programs
{
@@ -30,7 +32,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
public string FamilyName { get; }
public string Location { get; set; }
- public Application[] Apps { get; set; }
+ public Application[] Apps { get; set; } = Array.Empty();
public PackageVersion Version { get; set; }
@@ -40,7 +42,113 @@ namespace Flow.Launcher.Plugin.Program.Programs
Name = package.Id.Name;
FullName = package.Id.FullName;
FamilyName = package.Id.FamilyName;
- InitializeAppInfo();
+ //InitializeAppInfo();
+ InitAppsInPackage(package);
+ }
+
+ private void InitAppsInPackage(Package package)
+ {
+ var applist = new List();
+ try
+ {
+ var appListEntries = package.GetAppListEntries();
+ int count = appListEntries.Count;
+ foreach (var app in appListEntries)
+ {
+ try
+ {
+ var tmp = new Application()
+ {
+ UserModelId = app.AppUserModelId,
+ UniqueIdentifier = app.AppUserModelId,
+ DisplayName = app.DisplayInfo.DisplayName,
+ Description = app.DisplayInfo.Description,
+ Package = this,
+ Enabled = true,
+ };
+ applist.Add(tmp);
+ tmp.LogoStream = app.DisplayInfo.GetLogo(new Windows.Foundation.Size(44, 44)); // todo too small
+ }
+ catch (Exception e)
+ {
+ // TODO Logging
+ // Seems like logos for all games are missing?
+ }
+ }
+ Apps = applist.ToArray();
+ SetApplicationsCanRunElevated();
+ }
+ catch (Exception e)
+ {
+ // TODO Logging
+ Apps = Array.Empty();
+ }
+ }
+
+ private XmlDocument GetManifestXml()
+ {
+ var manifest = Path.Combine(Location, "AppxManifest.xml");
+ try
+ {
+ var file = File.ReadAllText(manifest);
+ var xmlDoc = new XmlDocument();
+ xmlDoc.LoadXml(file);
+ return xmlDoc;
+ }
+ catch (FileNotFoundException e)
+ {
+ ProgramLogger.LogException("UWP", "GetManifestXml", $"{Location}", "AppxManifest.xml not found.", e);
+ return null;
+ }
+ catch (Exception e)
+ {
+ ProgramLogger.LogException("UWP", "GetManifestXml", $"{Location}", "An unexpected error occured and unable to parse AppxManifest.xml", e);
+ return null;
+ }
+ }
+
+ private void SetApplicationsCanRunElevated()
+ {
+ // From powertoys run
+ var xmlDoc = GetManifestXml();
+ if (xmlDoc == null)
+ {
+ return;
+ }
+
+ var xmlRoot = xmlDoc.DocumentElement;
+ var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
+ namespaceManager.AddNamespace("", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
+ namespaceManager.AddNamespace("rescap", "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities");
+ namespaceManager.AddNamespace("uap10", "http://schemas.microsoft.com/appx/manifest/uap/windows10/10");
+
+ var rescapNode = xmlRoot.SelectSingleNode("//*[local-name()='Capability' and @Name='allowElevation']", namespaceManager);
+
+ if (rescapNode != null)
+ {
+ // For all apps in this package
+ foreach(var app in Apps)
+ {
+ app.CanRunElevated = true;
+ }
+ }
+ else
+ {
+ foreach (var app in Apps)
+ {
+ // According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package
+ // and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
+ var id = app.UserModelId.Split('!')[1];
+ var entryPointNode = xmlRoot.SelectSingleNode($"//*[local-name()='Application' and @Id='{id}' and @EntryPoint]", namespaceManager);
+ var trustLevelNode = xmlRoot.SelectSingleNode($"//*[local-name()='Application' and @Id='{id}' and @uap10:TrustLevel]", namespaceManager);
+
+ if (trustLevelNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL" ||
+ entryPointNode?.Attributes["EntryPoint"]?.Value == "Windows.FullTrustApplication")
+ {
+ app.CanRunElevated = true;
+ }
+ }
+ }
}
private void InitializeAppInfo()
@@ -282,7 +390,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
public string DisplayName { get; set; }
public string Description { get; set; }
public string UserModelId { get; set; }
- public string BackgroundColor { get; set; }
+ public string BackgroundColor { get; set; } = "transparent";
public string EntryPoint { get; set; }
public string Name => DisplayName;
@@ -291,10 +399,16 @@ namespace Flow.Launcher.Plugin.Program.Programs
public bool Enabled { get; set; }
public bool CanRunElevated { get; set; }
+ public bool CanRunElevated { get; set; } = false;
+
public string LogoUri { get; set; }
public string LogoPath { get; set; }
public UWP Package { get; set; }
+ [NonSerialized]
+ private RandomAccessStreamReference logoStream = null;
+ public RandomAccessStreamReference LogoStream { get => logoStream; set => logoStream = value; }
+
public Application() { }
public Result Result(string query, IPublicAPI api)
@@ -677,6 +791,18 @@ namespace Flow.Launcher.Plugin.Program.Programs
return plated;
}
+ public async Task LogoAsync()
+ {
+ var stream = await LogoStream.OpenReadAsync();
+ BitmapImage image = new BitmapImage();
+ image.BeginInit();
+ image.StreamSource = stream.AsStream();
+ image.CacheOption = BitmapCacheOption.OnLoad;
+ image.EndInit();
+ var logo = PlatedImage(image);
+ logo.Freeze();
+ return logo;
+ }
private BitmapImage ImageFromPath(string path)
{
From 6fdf2f101b5a6977cc6358062e768c64024b2258 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 17:48:27 +0800
Subject: [PATCH 06/36] Avoid unnecessary logo finding
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 688f112af..1c8665ed4 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -699,10 +699,14 @@ namespace Flow.Launcher.Plugin.Program.Programs
var logoPath = TryToFindLogo(uri, path);
if (String.IsNullOrEmpty(logoPath))
{
+ var tmp = Path.Combine(Package.Location, "Assets", uri);
+ if (!path.Equals(tmp, StringComparison.OrdinalIgnoreCase))
+ {
// TODO: Don't know why, just keep it at the moment
// Maybe on older version of Windows 10?
// for C:\Windows\MiracastView etc
- return TryToFindLogo(uri, Path.Combine(Package.Location, "Assets", uri));
+ return TryToFindLogo(uri, tmp);
+ }
}
return logoPath;
From e4733207b38c6201ecd332417645e6cfa5bad8e3 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 18:43:56 +0800
Subject: [PATCH 07/36] Use AppListEntry to construct app
---
.../Programs/UWP.cs | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 1c8665ed4..627d6d138 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -411,6 +411,16 @@ namespace Flow.Launcher.Plugin.Program.Programs
public Application() { }
+ public Application(AppListEntry appListEntry)
+ {
+ UserModelId = appListEntry.AppUserModelId;
+ UniqueIdentifier = appListEntry.AppUserModelId;
+ DisplayName = appListEntry.DisplayInfo.DisplayName;
+ Description = appListEntry.DisplayInfo.Description;
+ //Package = package;
+ Enabled = true;
+ }
+
public Result Result(string query, IPublicAPI api)
{
string title;
@@ -604,6 +614,18 @@ namespace Flow.Launcher.Plugin.Program.Programs
return false;
}
+ internal static bool IfAppCanRunElevated(XmlNode appNode, XmlNamespaceManager namespaceManager)
+ {
+ // According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package
+ // and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
+
+ var entryPointNode = appNode.SelectSingleNode($"//*[local-name()='Application' and @EntryPoint]", namespaceManager);
+ var trustLevelNode = appNode.SelectSingleNode($"//*[local-name()='Application' and @uap10:TrustLevel]", namespaceManager);
+
+ return entryPointNode?.Attributes["EntryPoint"]?.Value == "Windows.FullTrustApplication" ||
+ trustLevelNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL";
+ }
+
internal string ResourceFromPri(string packageFullName, string packageName, string rawReferenceValue)
{
if (string.IsNullOrWhiteSpace(rawReferenceValue) || !rawReferenceValue.StartsWith("ms-resource:"))
From e098426f5c524d8924edf07f95a0090e903cc59c Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 18:46:48 +0800
Subject: [PATCH 08/36] Parse Appmanifest.xml
---
.../Programs/UWP.cs | 43 ++++++++++++++-----
1 file changed, 32 insertions(+), 11 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 627d6d138..f8369f462 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -57,17 +57,8 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
try
{
- var tmp = new Application()
- {
- UserModelId = app.AppUserModelId,
- UniqueIdentifier = app.AppUserModelId,
- DisplayName = app.DisplayInfo.DisplayName,
- Description = app.DisplayInfo.Description,
- Package = this,
- Enabled = true,
- };
+ var tmp = new Application(app);
applist.Add(tmp);
- tmp.LogoStream = app.DisplayInfo.GetLogo(new Windows.Foundation.Size(44, 44)); // todo too small
}
catch (Exception e)
{
@@ -76,13 +67,43 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
}
Apps = applist.ToArray();
- SetApplicationsCanRunElevated();
+
+ // From powertoys run
+ var xmlDoc = GetManifestXml();
+ if (xmlDoc == null)
+ {
+ return;
+ }
+
+ var xmlRoot = xmlDoc.DocumentElement;
+ var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
+ namespaceManager.AddNamespace("", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
+ namespaceManager.AddNamespace("rescap", "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities");
+ namespaceManager.AddNamespace("uap10", "http://schemas.microsoft.com/appx/manifest/uap/windows10/10");
+
+ var allowElevationNode = xmlRoot.SelectSingleNode("//*[local-name()='Capability' and @Name='allowElevation']", namespaceManager);
+ bool packageCanElevate = allowElevationNode != null;
+
+ var appsNode = xmlRoot.SelectSingleNode("Applications", namespaceManager);
+ foreach (var app in Apps)
+ {
+ // According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package
+ // and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
+ var id = app.UserModelId.Split('!')[1];
+ var appNode = appsNode.SelectSingleNode($"//*[local-name()='Application' and @Id='{id}']", namespaceManager);
+ if (appNode != null)
+ {
+ //TODO
+ app.CanRunElevated = packageCanElevate || Application.IfAppCanRunElevated(appNode, namespaceManager);
+ }
+ }
}
catch (Exception e)
{
// TODO Logging
Apps = Array.Empty();
}
+
}
private XmlDocument GetManifestXml()
From 97d6b6e234892fac370e4fbcb4a3b63ea4794b9e Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 18:47:27 +0800
Subject: [PATCH 09/36] fix typo
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index f8369f462..37f8dba8e 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -418,8 +418,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
public string Location => Package.Location;
public bool Enabled { get; set; }
- public bool CanRunElevated { get; set; }
-
public bool CanRunElevated { get; set; } = false;
public string LogoUri { get; set; }
From a62ea0e9898615427d6b317a469194d23635de41 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 19:06:16 +0800
Subject: [PATCH 10/36] Remove UWP member in Application
---
.../Programs/UWP.cs | 128 +++++-------------
1 file changed, 33 insertions(+), 95 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 37f8dba8e..b31c67319 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -19,8 +19,8 @@ using Rect = System.Windows.Rect;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.Infrastructure.Logger;
using System.Threading.Channels;
-using Windows.Storage.Streams;
using System.Xml;
+using Windows.ApplicationModel.Core;
namespace Flow.Launcher.Plugin.Program.Programs
{
@@ -57,14 +57,14 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
try
{
- var tmp = new Application(app);
+ var tmp = new Application(app, this);
applist.Add(tmp);
}
catch (Exception e)
{
// TODO Logging
// Seems like logos for all games are missing?
- }
+ }
}
Apps = applist.ToArray();
@@ -128,50 +128,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
}
- private void SetApplicationsCanRunElevated()
- {
- // From powertoys run
- var xmlDoc = GetManifestXml();
- if (xmlDoc == null)
- {
- return;
- }
-
- var xmlRoot = xmlDoc.DocumentElement;
- var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
- namespaceManager.AddNamespace("", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
- namespaceManager.AddNamespace("rescap", "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities");
- namespaceManager.AddNamespace("uap10", "http://schemas.microsoft.com/appx/manifest/uap/windows10/10");
-
- var rescapNode = xmlRoot.SelectSingleNode("//*[local-name()='Capability' and @Name='allowElevation']", namespaceManager);
-
- if (rescapNode != null)
- {
- // For all apps in this package
- foreach(var app in Apps)
- {
- app.CanRunElevated = true;
- }
- }
- else
- {
- foreach (var app in Apps)
- {
- // According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package
- // and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
- var id = app.UserModelId.Split('!')[1];
- var entryPointNode = xmlRoot.SelectSingleNode($"//*[local-name()='Application' and @Id='{id}' and @EntryPoint]", namespaceManager);
- var trustLevelNode = xmlRoot.SelectSingleNode($"//*[local-name()='Application' and @Id='{id}' and @uap10:TrustLevel]", namespaceManager);
-
- if (trustLevelNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL" ||
- entryPointNode?.Attributes["EntryPoint"]?.Value == "Windows.FullTrustApplication")
- {
- app.CanRunElevated = true;
- }
- }
- }
- }
-
private void InitializeAppInfo()
{
var path = Path.Combine(Location, "AppxManifest.xml");
@@ -188,7 +144,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
List _apps = AppxPackageHelper.GetAppsFromManifest(stream);
Apps = _apps.Select(x => new Application(x, this))
- .Where(a => !string.IsNullOrEmpty(a.UserModelId)
+ .Where(a => !string.IsNullOrEmpty(a.UserModelId)
&& !string.IsNullOrEmpty(a.DisplayName))
.ToArray();
}
@@ -377,7 +333,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
PackageChangeChannel.Reader.TryRead(out _);
await Task.Run(Main.IndexUwpPrograms);
}
-
+
}
}
@@ -415,28 +371,23 @@ namespace Flow.Launcher.Plugin.Program.Programs
public string EntryPoint { get; set; }
public string Name => DisplayName;
- public string Location => Package.Location;
+ public string Location { get; set; }
public bool Enabled { get; set; }
public bool CanRunElevated { get; set; } = false;
public string LogoUri { get; set; }
public string LogoPath { get; set; }
- public UWP Package { get; set; }
-
- [NonSerialized]
- private RandomAccessStreamReference logoStream = null;
- public RandomAccessStreamReference LogoStream { get => logoStream; set => logoStream = value; }
public Application() { }
- public Application(AppListEntry appListEntry)
+ public Application(AppListEntry appListEntry, UWP package)
{
UserModelId = appListEntry.AppUserModelId;
UniqueIdentifier = appListEntry.AppUserModelId;
DisplayName = appListEntry.DisplayInfo.DisplayName;
Description = appListEntry.DisplayInfo.Description;
- //Package = package;
+ Location = package.Location;
Enabled = true;
}
@@ -478,7 +429,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
var result = new Result
{
Title = title,
- SubTitle = Main._settings.HideAppsPath ? string.Empty : Package.Location,
+ SubTitle = Main._settings.HideAppsPath ? string.Empty : Location,
Icon = Logo,
Score = matchResult.Score,
TitleHighlightData = matchResult.MatchData,
@@ -525,7 +476,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
Title = api.GetTranslation("flowlauncher_plugin_program_open_containing_folder"),
Action = _ =>
{
- Main.Context.API.OpenDirectory(Package.Location);
+ Main.Context.API.OpenDirectory(Location);
return true;
},
@@ -577,7 +528,8 @@ namespace Flow.Launcher.Plugin.Program.Programs
var info = new ProcessStartInfo(command)
{
- UseShellExecute = true, Verb = "runas",
+ UseShellExecute = true,
+ Verb = "runas",
};
Main.StartProcess(Process.Start, info);
@@ -601,7 +553,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
BackgroundColor = tmpBackgroundColor;
EntryPoint = tmpEntryPoint;
- Package = package;
+ Location = package.Location;
DisplayName = ResourceFromPri(package.FullName, package.Name, DisplayName);
Description = ResourceFromPri(package.FullName, package.Name, Description);
@@ -619,7 +571,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
return true;
}
- var manifest = Package.Location + "\\AppxManifest.xml";
+ var manifest = Location + "\\AppxManifest.xml";
if (File.Exists(manifest))
{
var file = File.ReadAllText(manifest);
@@ -665,15 +617,15 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
else
{
- ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Can't load null or empty result "
- + $"pri {source} in uwp location {Package.Location}", new NullReferenceException());
+ ProgramLogger.LogException($"|UWP|ResourceFromPri|{Location}|Can't load null or empty result "
+ + $"pri {source} in uwp location {Location}", new NullReferenceException());
return string.Empty;
}
}
else
{
var e = Marshal.GetExceptionForHR((int)hResult);
- ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Load pri failed {source} with HResult {hResult} and location {Package.Location}", e);
+ ProgramLogger.LogException($"|UWP|ResourceFromPri|{Location}|Load pri failed {source} with HResult {hResult} and location {Location}", e);
return string.Empty;
}
}
@@ -735,17 +687,17 @@ namespace Flow.Launcher.Plugin.Program.Programs
// windows 8.1 https://msdn.microsoft.com/en-us/library/windows/apps/hh965372.aspx#target_size
// windows 8 https://msdn.microsoft.com/en-us/library/windows/apps/br211475.aspx
- string path = Path.Combine(Package.Location, uri);
+ string path = Path.Combine(Location, uri);
var logoPath = TryToFindLogo(uri, path);
if (String.IsNullOrEmpty(logoPath))
{
- var tmp = Path.Combine(Package.Location, "Assets", uri);
+ var tmp = Path.Combine(Location, "Assets", uri);
if (!path.Equals(tmp, StringComparison.OrdinalIgnoreCase))
{
- // TODO: Don't know why, just keep it at the moment
- // Maybe on older version of Windows 10?
- // for C:\Windows\MiracastView etc
+ // TODO: Don't know why, just keep it at the moment
+ // Maybe on older version of Windows 10?
+ // for C:\Windows\MiracastView etc
return TryToFindLogo(uri, tmp);
}
}
@@ -766,8 +718,8 @@ namespace Flow.Launcher.Plugin.Program.Programs
if (String.IsNullOrEmpty(logoNamePrefix) || String.IsNullOrEmpty(logoDir) || !Directory.Exists(logoDir))
{
// Known issue: Edge always triggers it since logo is not at uri
- ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
- $"|{UserModelId} can't find logo uri for {uri} in package location (logo name or directory not found): {Package.Location}", new FileNotFoundException());
+ ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Location}" +
+ $"|{UserModelId} can't find logo uri for {uri} in package location (logo name or directory not found): {Location}", new FileNotFoundException());
return string.Empty;
}
@@ -785,7 +737,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
var selected = logos.FirstOrDefault();
var closest = selected;
int min = int.MaxValue;
- foreach(var logo in logos)
+ foreach (var logo in logos)
{
var imageStream = File.OpenRead(logo);
@@ -793,7 +745,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
var height = decoder.Frames[0].PixelHeight;
var width = decoder.Frames[0].PixelWidth;
int pixelCountDiff = Math.Abs(height * width - 1936); // 44*44=1936
- if(pixelCountDiff < min)
+ if (pixelCountDiff < min)
{
// try to find the closest to 44x44 logo
closest = logo;
@@ -810,16 +762,16 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
else
{
- ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
- $"|{UserModelId} can't find logo uri for {uri} in package location (can't find specified logo): {Package.Location}", new FileNotFoundException());
+ ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Location}" +
+ $"|{UserModelId} can't find logo uri for {uri} in package location (can't find specified logo): {Location}", new FileNotFoundException());
return string.Empty;
}
}
else
{
- ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
+ ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Location}" +
$"|Unable to find extension from {uri} for {UserModelId} " +
- $"in package location {Package.Location}", new FileNotFoundException());
+ $"in package location {Location}", new FileNotFoundException());
return string.Empty;
}
}
@@ -835,20 +787,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
plated.Freeze();
return plated;
}
-
- public async Task LogoAsync()
- {
- var stream = await LogoStream.OpenReadAsync();
- BitmapImage image = new BitmapImage();
- image.BeginInit();
- image.StreamSource = stream.AsStream();
- image.CacheOption = BitmapCacheOption.OnLoad;
- image.EndInit();
- var logo = PlatedImage(image);
- logo.Freeze();
- return logo;
- }
-
private BitmapImage ImageFromPath(string path)
{
// TODO: Consider using infrastructure.image.imageloader?
@@ -866,7 +804,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
ProgramLogger.LogException($"|UWP|ImageFromPath|{(string.IsNullOrEmpty(path) ? "Not Avaliable" : path)}" +
$"|Unable to get logo for {UserModelId} from {path} and" +
- $" located in {Package.Location}", new FileNotFoundException());
+ $" located in {Location}", new FileNotFoundException());
return new BitmapImage(new Uri(Constant.MissingImgIcon));
}
}
@@ -913,9 +851,9 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
else
{
- ProgramLogger.LogException($"|UWP|PlatedImage|{Package.Location}" +
+ ProgramLogger.LogException($"|UWP|PlatedImage|{Location}" +
$"|Unable to convert background string {BackgroundColor} " +
- $"to color for {Package.Location}", new InvalidOperationException());
+ $"to color for {Location}", new InvalidOperationException());
return new BitmapImage(new Uri(Constant.MissingImgIcon));
}
From 9ba7cb0794af31740c1b9c7b57aab53d6f633161 Mon Sep 17 00:00:00 2001
From: DB p
Date: Mon, 28 Nov 2022 21:51:14 +0900
Subject: [PATCH 11/36] Add 'Installing Plugin' string / Adjust Notification
---
.../Languages/en.xaml | 20 ++++++++++---------
.../PluginsManager.cs | 2 +-
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index a15c50ccf..9915a7b20 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -1,14 +1,16 @@
-
+
-
+
Downloading plugin
Successfully downloaded
Error: Unable to download the plugin
{0} by {1} {2}{3}Would you like to uninstall this plugin? After the uninstallation Flow will automatically restart.
{0} by {1} {2}{3}Would you like to install this plugin? After the installation Flow will automatically restart.
Plugin Install
+ Installing Plugin
Download and install {0}
Plugin Uninstall
Plugin successfully installed. Restarting Flow, please wait...
@@ -27,14 +29,14 @@
Installing from an unknown source
You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings)
-
-
-
+
+
+
Plugins Manager
Management of installing, uninstalling or updating Flow Launcher plugins
Unknown Author
-
+
Open website
Visit the plugin's website
See source code
@@ -44,6 +46,6 @@
Go to Flow's plugins repository
Visit the PluginsManifest repository to see community-made plugin submissions
-
+
Install from unknown source warning
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index 4ca98aeae..b9e6dec99 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -176,7 +176,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
return;
}
- Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_install_title"),
+ Context.API.ShowMsg(Context.API.GetTranslation("plugin_pluginsmanager_installing_plugin"),
Context.API.GetTranslation("plugin_pluginsmanager_install_success_restart"));
Context.API.RestartApp();
From cd801e8ae7ec76128b5121504a8b0ac9abc2be47 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 22:01:16 +0800
Subject: [PATCH 12/36] Get uwp logo from xml
---
.../Programs/UWP.cs | 267 +++++++++---------
1 file changed, 126 insertions(+), 141 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index b31c67319..f141af37d 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -10,14 +10,12 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
-using System.Xml.Linq;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.Program.Logger;
using Rect = System.Windows.Rect;
using Flow.Launcher.Plugin.SharedModels;
-using Flow.Launcher.Infrastructure.Logger;
using System.Threading.Channels;
using System.Xml;
using Windows.ApplicationModel.Core;
@@ -34,7 +32,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
public Application[] Apps { get; set; } = Array.Empty();
- public PackageVersion Version { get; set; }
+ //public PackageVersion Version { get; set; }
public UWP(Package package)
{
@@ -42,32 +40,30 @@ namespace Flow.Launcher.Plugin.Program.Programs
Name = package.Id.Name;
FullName = package.Id.FullName;
FamilyName = package.Id.FamilyName;
- //InitializeAppInfo();
InitAppsInPackage(package);
}
private void InitAppsInPackage(Package package)
{
var applist = new List();
+ // WinRT
+ var appListEntries = package.GetAppListEntries();
+ foreach (var app in appListEntries)
+ {
+ try
+ {
+ var tmp = new Application(app, this);
+ applist.Add(tmp);
+ }
+ catch (Exception e)
+ {
+ // TODO Logging
+ }
+ }
+ Apps = applist.ToArray();
+
try
{
- var appListEntries = package.GetAppListEntries();
- int count = appListEntries.Count;
- foreach (var app in appListEntries)
- {
- try
- {
- var tmp = new Application(app, this);
- applist.Add(tmp);
- }
- catch (Exception e)
- {
- // TODO Logging
- // Seems like logos for all games are missing?
- }
- }
- Apps = applist.ToArray();
-
// From powertoys run
var xmlDoc = GetManifestXml();
if (xmlDoc == null)
@@ -76,32 +72,36 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
var xmlRoot = xmlDoc.DocumentElement;
+ var packageVersion = GetPackageVersionFromManifest(xmlRoot);
+ var logoName = logoNameFromNamespace[packageVersion];
+
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceManager.AddNamespace("", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
namespaceManager.AddNamespace("rescap", "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities");
namespaceManager.AddNamespace("uap10", "http://schemas.microsoft.com/appx/manifest/uap/windows10/10");
- var allowElevationNode = xmlRoot.SelectSingleNode("//*[local-name()='Capability' and @Name='allowElevation']", namespaceManager);
+ var allowElevationNode = xmlRoot.SelectSingleNode("//*[name()='rescap:Capability' and @Name='allowElevation']", namespaceManager);
bool packageCanElevate = allowElevationNode != null;
- var appsNode = xmlRoot.SelectSingleNode("Applications", namespaceManager);
+ var appsNode = xmlRoot.SelectSingleNode("//*[name()='Applications']", namespaceManager);
foreach (var app in Apps)
{
// According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package
// and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
var id = app.UserModelId.Split('!')[1];
- var appNode = appsNode.SelectSingleNode($"//*[local-name()='Application' and @Id='{id}']", namespaceManager);
+ var appNode = appsNode?.SelectSingleNode($"//*[name()='Application' and @Id='{id}']", namespaceManager);
if (appNode != null)
{
- //TODO
app.CanRunElevated = packageCanElevate || Application.IfAppCanRunElevated(appNode, namespaceManager);
+ var visualElement = appNode.SelectSingleNode($"//*[name()='uap:VisualElements']", namespaceManager);
+ var logoUri = visualElement.Attributes[logoName]?.Value;
+ app.InitLogoPathFromUri(logoUri);
}
}
}
catch (Exception e)
{
// TODO Logging
- Apps = Array.Empty();
}
}
@@ -128,68 +128,72 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
}
- private void InitializeAppInfo()
- {
- var path = Path.Combine(Location, "AppxManifest.xml");
+ //private void InitializeAppInfo()
+ //{
+ // var path = Path.Combine(Location, "AppxManifest.xml");
- var namespaces = XmlNamespaces(path);
- InitPackageVersion(namespaces);
+ // var namespaces = XmlNamespaces(path);
+ // InitPackageVersion(namespaces);
- const uint noAttribute = 0x80;
- const Stgm nonExclusiveRead = Stgm.Read | Stgm.ShareDenyNone;
- var hResult = SHCreateStreamOnFileEx(path, nonExclusiveRead, noAttribute, false, null, out IStream stream);
+ // const uint noAttribute = 0x80;
+ // const Stgm nonExclusiveRead = Stgm.Read | Stgm.ShareDenyNone;
+ // var hResult = SHCreateStreamOnFileEx(path, nonExclusiveRead, noAttribute, false, null, out IStream stream);
- if (hResult == Hresult.Ok)
- {
- List _apps = AppxPackageHelper.GetAppsFromManifest(stream);
+ // if (hResult == Hresult.Ok)
+ // {
+ // List _apps = AppxPackageHelper.GetAppsFromManifest(stream);
- Apps = _apps.Select(x => new Application(x, this))
- .Where(a => !string.IsNullOrEmpty(a.UserModelId)
- && !string.IsNullOrEmpty(a.DisplayName))
- .ToArray();
- }
- else
- {
- var e = Marshal.GetExceptionForHR((int)hResult);
- ProgramLogger.LogException($"|UWP|InitializeAppInfo|{path}" +
- "|Error caused while trying to get the details of the UWP program", e);
+ // Apps = _apps.Select(x => new Application(x, this))
+ // .Where(a => !string.IsNullOrEmpty(a.UserModelId)
+ // && !string.IsNullOrEmpty(a.DisplayName))
+ // .ToArray();
+ // }
+ // else
+ // {
+ // var e = Marshal.GetExceptionForHR((int)hResult);
+ // ProgramLogger.LogException($"|UWP|InitializeAppInfo|{path}" +
+ // "|Error caused while trying to get the details of the UWP program", e);
- Apps = Array.Empty();
- }
+ // Apps = Array.Empty();
+ // }
- if (stream != null && Marshal.ReleaseComObject(stream) > 0)
- {
- Log.Error("Flow.Launcher.Plugin.Program.Programs.UWP", "AppxManifest.xml was leaked");
- }
- }
+ // if (stream != null && Marshal.ReleaseComObject(stream) > 0)
+ // {
+ // Log.Error("Flow.Launcher.Plugin.Program.Programs.UWP", "AppxManifest.xml was leaked");
+ // }
+ //}
/// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx
- private static string[] XmlNamespaces(string path)
+ private PackageVersion GetPackageVersionFromManifest(XmlElement xmlRoot)
{
- XDocument z = XDocument.Load(path);
- if (z.Root != null)
+ if (xmlRoot != null)
{
- var namespaces = z.Root.Attributes().Where(a => a.IsNamespaceDeclaration).GroupBy(
- a => a.Name.Namespace == XNamespace.None ? string.Empty : a.Name.LocalName,
- a => XNamespace.Get(a.Value)
- ).Select(
- g => g.First().ToString()
- ).ToArray();
- return namespaces;
+
+ var namespaces = xmlRoot.Attributes;
+ foreach (XmlAttribute ns in namespaces)
+ {
+ if (versionFromNamespace.TryGetValue(ns.Value, out var packageVersion))
+ {
+ return packageVersion;
+ }
+ }
+
+ ProgramLogger.LogException($"|UWP|GetPackageVersionFromManifest|{Location}" +
+ "|Trying to get the package version of the UWP program, but an unknown UWP appmanifest version "
+ + $"{FullName} from location {Location} is returned.", new FormatException());
+ return PackageVersion.Unknown;
}
else
{
- ProgramLogger.LogException($"|UWP|XmlNamespaces|{path}" +
- $"|Error occured while trying to get the XML from {path}", new ArgumentNullException());
-
- return Array.Empty();
+ ProgramLogger.LogException($"|UWP|GetPackageVersionFromManifest|{Location}" +
+ "|Can't parse AppManifest.xml"
+ + $"{FullName} from location {Location} is returned.", new ArgumentNullException(nameof(xmlRoot)));
+ return PackageVersion.Unknown;
}
}
- private void InitPackageVersion(string[] namespaces)
+ private static readonly Dictionary versionFromNamespace = new()
{
- var versionFromNamespace = new Dictionary
- {
{
"http://schemas.microsoft.com/appx/manifest/foundation/windows10", PackageVersion.Windows10
},
@@ -199,23 +203,20 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
"http://schemas.microsoft.com/appx/2010/manifest", PackageVersion.Windows8
},
- };
+ };
- foreach (var n in versionFromNamespace.Keys)
+ private static readonly Dictionary logoNameFromNamespace = new()
+ {
{
- if (namespaces.Contains(n))
- {
- Version = versionFromNamespace[n];
- return;
- }
- }
-
- ProgramLogger.LogException($"|UWP|XmlNamespaces|{Location}" +
- "|Trying to get the package version of the UWP program, but a unknown UWP appmanifest version "
- + $"{FullName} from location {Location} is returned.", new FormatException());
-
- Version = PackageVersion.Unknown;
- }
+ PackageVersion.Windows10, "Square44x44Logo"
+ },
+ {
+ PackageVersion.Windows81, "Square30x30Logo"
+ },
+ {
+ PackageVersion.Windows8, "SmallLogo"
+ },
+ };
public static Application[] All()
{
@@ -375,9 +376,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
public bool Enabled { get; set; }
public bool CanRunElevated { get; set; } = false;
-
- public string LogoUri { get; set; }
- public string LogoPath { get; set; }
+ public string LogoPath { get; set; } = string.Empty;
public Application() { }
@@ -535,34 +534,34 @@ namespace Flow.Launcher.Plugin.Program.Programs
Main.StartProcess(Process.Start, info);
}
- public Application(AppxPackageHelper.IAppxManifestApplication manifestApp, UWP package)
- {
- // This is done because we cannot use the keyword 'out' along with a property
+ //public Application(AppxPackageHelper.IAppxManifestApplication manifestApp, UWP package)
+ //{
+ // // This is done because we cannot use the keyword 'out' along with a property
- manifestApp.GetAppUserModelId(out string tmpUserModelId);
- manifestApp.GetAppUserModelId(out string tmpUniqueIdentifier);
- manifestApp.GetStringValue("DisplayName", out string tmpDisplayName);
- manifestApp.GetStringValue("Description", out string tmpDescription);
- manifestApp.GetStringValue("BackgroundColor", out string tmpBackgroundColor);
- manifestApp.GetStringValue("EntryPoint", out string tmpEntryPoint);
+ // manifestApp.GetAppUserModelId(out string tmpUserModelId);
+ // manifestApp.GetAppUserModelId(out string tmpUniqueIdentifier);
+ // manifestApp.GetStringValue("DisplayName", out string tmpDisplayName);
+ // manifestApp.GetStringValue("Description", out string tmpDescription);
+ // manifestApp.GetStringValue("BackgroundColor", out string tmpBackgroundColor);
+ // manifestApp.GetStringValue("EntryPoint", out string tmpEntryPoint);
- UserModelId = tmpUserModelId;
- UniqueIdentifier = tmpUniqueIdentifier;
- DisplayName = tmpDisplayName;
- Description = tmpDescription;
- BackgroundColor = tmpBackgroundColor;
- EntryPoint = tmpEntryPoint;
+ // UserModelId = tmpUserModelId;
+ // UniqueIdentifier = tmpUniqueIdentifier;
+ // DisplayName = tmpDisplayName;
+ // Description = tmpDescription;
+ // BackgroundColor = tmpBackgroundColor;
+ // EntryPoint = tmpEntryPoint;
- Location = package.Location;
+ // Location = package.Location;
- DisplayName = ResourceFromPri(package.FullName, package.Name, DisplayName);
- Description = ResourceFromPri(package.FullName, package.Name, Description);
- LogoUri = LogoUriFromManifest(manifestApp);
- LogoPath = LogoPathFromUri(LogoUri);
+ // DisplayName = ResourceFromPri(package.FullName, package.Name, DisplayName);
+ // Description = ResourceFromPri(package.FullName, package.Name, Description);
+ // LogoUri = LogoUriFromManifest(manifestApp);
+ // LogoPath = LogoPathFromUri(LogoUri);
- Enabled = true;
- CanRunElevated = CanApplicationRunElevated();
- }
+ // Enabled = true;
+ // CanRunElevated = CanApplicationRunElevated();
+ //}
private bool CanApplicationRunElevated()
{
@@ -654,39 +653,18 @@ namespace Flow.Launcher.Plugin.Program.Programs
return $"{prefix}//{packageName}{key}";
}
- internal string LogoUriFromManifest(AppxPackageHelper.IAppxManifestApplication app)
- {
- var logoKeyFromVersion = new Dictionary
- {
- {
- PackageVersion.Windows10, "Square44x44Logo"
- },
- {
- PackageVersion.Windows81, "Square30x30Logo"
- },
- {
- PackageVersion.Windows8, "SmallLogo"
- },
- };
- if (logoKeyFromVersion.ContainsKey(Package.Version))
- {
- var key = logoKeyFromVersion[Package.Version];
- _ = app.GetStringValue(key, out string logoUri);
- return logoUri;
- }
- else
- {
- return string.Empty;
- }
- }
-
- internal string LogoPathFromUri(string uri)
+ internal void InitLogoPathFromUri(string uri)
{
// all https://msdn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets
// windows 10 https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx
// windows 8.1 https://msdn.microsoft.com/en-us/library/windows/apps/hh965372.aspx#target_size
// windows 8 https://msdn.microsoft.com/en-us/library/windows/apps/br211475.aspx
+ if (string.IsNullOrWhiteSpace(uri))
+ {
+ throw new ArgumentException("uri");
+ }
+
string path = Path.Combine(Location, uri);
var logoPath = TryToFindLogo(uri, path);
@@ -698,10 +676,17 @@ namespace Flow.Launcher.Plugin.Program.Programs
// TODO: Don't know why, just keep it at the moment
// Maybe on older version of Windows 10?
// for C:\Windows\MiracastView etc
- return TryToFindLogo(uri, tmp);
+ logoPath = TryToFindLogo(uri, tmp);
+ if (!String.IsNullOrEmpty(logoPath))
+ {
+ LogoPath = logoPath;
+ }
}
}
- return logoPath;
+ else
+ {
+ LogoPath = logoPath;
+ }
string TryToFindLogo(string uri, string path)
{
From 54f408aeada781e9e165cefda097cc6a991127ec Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 22:08:21 +0800
Subject: [PATCH 13/36] comment unused
---
Flow.Launcher.Test/Plugins/ProgramTest.cs | 32 ++--
.../Programs/UWP.cs | 168 +++++++++---------
2 files changed, 99 insertions(+), 101 deletions(-)
diff --git a/Flow.Launcher.Test/Plugins/ProgramTest.cs b/Flow.Launcher.Test/Plugins/ProgramTest.cs
index e3a05f484..10818ec49 100644
--- a/Flow.Launcher.Test/Plugins/ProgramTest.cs
+++ b/Flow.Launcher.Test/Plugins/ProgramTest.cs
@@ -8,23 +8,23 @@ namespace Flow.Launcher.Test.Plugins
[TestFixture]
public class ProgramTest
{
- [TestCase("Microsoft.WindowsCamera", "ms-resource:LensSDK/Resources/AppTitle", "ms-resource://Microsoft.WindowsCamera/LensSDK/Resources/AppTitle")]
- [TestCase("microsoft.windowscommunicationsapps", "ms-resource://microsoft.windowscommunicationsapps/hxoutlookintl/AppManifest_MailDesktop_DisplayName",
- "ms-resource://microsoft.windowscommunicationsapps/hxoutlookintl/AppManifest_MailDesktop_DisplayName")]
- [TestCase("windows.immersivecontrolpanel", "ms-resource:DisplayName", "ms-resource://windows.immersivecontrolpanel/Resources/DisplayName")]
- [TestCase("Microsoft.MSPaint", "ms-resource:AppName", "ms-resource://Microsoft.MSPaint/Resources/AppName")]
- public void WhenGivenPriReferenceValueShouldReturnCorrectFormat(string packageName, string rawPriReferenceValue, string expectedFormat)
- {
- // Arrange
- var app = new UWP.Application();
+ //[TestCase("Microsoft.WindowsCamera", "ms-resource:LensSDK/Resources/AppTitle", "ms-resource://Microsoft.WindowsCamera/LensSDK/Resources/AppTitle")]
+ //[TestCase("microsoft.windowscommunicationsapps", "ms-resource://microsoft.windowscommunicationsapps/hxoutlookintl/AppManifest_MailDesktop_DisplayName",
+ // "ms-resource://microsoft.windowscommunicationsapps/hxoutlookintl/AppManifest_MailDesktop_DisplayName")]
+ //[TestCase("windows.immersivecontrolpanel", "ms-resource:DisplayName", "ms-resource://windows.immersivecontrolpanel/Resources/DisplayName")]
+ //[TestCase("Microsoft.MSPaint", "ms-resource:AppName", "ms-resource://Microsoft.MSPaint/Resources/AppName")]
+ //public void WhenGivenPriReferenceValueShouldReturnCorrectFormat(string packageName, string rawPriReferenceValue, string expectedFormat)
+ //{
+ // // Arrange
+ // var app = new UWP.Application();
- // Act
- var result = UWP.Application.FormattedPriReferenceValue(packageName, rawPriReferenceValue);
+ // // Act
+ // var result = UWP.Application.FormattedPriReferenceValue(packageName, rawPriReferenceValue);
- // Assert
- Assert.IsTrue(result == expectedFormat,
- $"Expected Pri reference format: {expectedFormat}{Environment.NewLine} " +
- $"Actual: {result}{Environment.NewLine}");
- }
+ // // Assert
+ // Assert.IsTrue(result == expectedFormat,
+ // $"Expected Pri reference format: {expectedFormat}{Environment.NewLine} " +
+ // $"Actual: {result}{Environment.NewLine}");
+ //}
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index f141af37d..c287e31e9 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -374,12 +374,10 @@ namespace Flow.Launcher.Plugin.Program.Programs
public string Name => DisplayName;
public string Location { get; set; }
- public bool Enabled { get; set; }
+ public bool Enabled { get; set; } = false;
public bool CanRunElevated { get; set; } = false;
public string LogoPath { get; set; } = string.Empty;
- public Application() { }
-
public Application(AppListEntry appListEntry, UWP package)
{
UserModelId = appListEntry.AppUserModelId;
@@ -563,26 +561,26 @@ namespace Flow.Launcher.Plugin.Program.Programs
// CanRunElevated = CanApplicationRunElevated();
//}
- private bool CanApplicationRunElevated()
- {
- if (EntryPoint == "Windows.FullTrustApplication")
- {
- return true;
- }
+ //private bool CanApplicationRunElevated()
+ //{
+ // if (EntryPoint == "Windows.FullTrustApplication")
+ // {
+ // return true;
+ // }
- var manifest = Location + "\\AppxManifest.xml";
- if (File.Exists(manifest))
- {
- var file = File.ReadAllText(manifest);
+ // var manifest = Location + "\\AppxManifest.xml";
+ // if (File.Exists(manifest))
+ // {
+ // var file = File.ReadAllText(manifest);
- if (file.Contains("TrustLevel=\"mediumIL\"", StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
- }
+ // if (file.Contains("TrustLevel=\"mediumIL\"", StringComparison.OrdinalIgnoreCase))
+ // {
+ // return true;
+ // }
+ // }
- return false;
- }
+ // return false;
+ //}
internal static bool IfAppCanRunElevated(XmlNode appNode, XmlNamespaceManager namespaceManager)
{
@@ -596,62 +594,62 @@ namespace Flow.Launcher.Plugin.Program.Programs
trustLevelNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL";
}
- internal string ResourceFromPri(string packageFullName, string packageName, string rawReferenceValue)
- {
- if (string.IsNullOrWhiteSpace(rawReferenceValue) || !rawReferenceValue.StartsWith("ms-resource:"))
- return rawReferenceValue;
+ //internal string ResourceFromPri(string packageFullName, string packageName, string rawReferenceValue)
+ //{
+ // if (string.IsNullOrWhiteSpace(rawReferenceValue) || !rawReferenceValue.StartsWith("ms-resource:"))
+ // return rawReferenceValue;
- var formattedPriReference = FormattedPriReferenceValue(packageName, rawReferenceValue);
+ // var formattedPriReference = FormattedPriReferenceValue(packageName, rawReferenceValue);
- var outBuffer = new StringBuilder(128);
- string source = $"@{{{packageFullName}? {formattedPriReference}}}";
- var capacity = (uint)outBuffer.Capacity;
- var hResult = SHLoadIndirectString(source, outBuffer, capacity, IntPtr.Zero);
- if (hResult == Hresult.Ok)
- {
- var loaded = outBuffer.ToString();
- if (!string.IsNullOrEmpty(loaded))
- {
- return loaded;
- }
- else
- {
- ProgramLogger.LogException($"|UWP|ResourceFromPri|{Location}|Can't load null or empty result "
- + $"pri {source} in uwp location {Location}", new NullReferenceException());
- return string.Empty;
- }
- }
- else
- {
- var e = Marshal.GetExceptionForHR((int)hResult);
- ProgramLogger.LogException($"|UWP|ResourceFromPri|{Location}|Load pri failed {source} with HResult {hResult} and location {Location}", e);
- return string.Empty;
- }
- }
+ // var outBuffer = new StringBuilder(128);
+ // string source = $"@{{{packageFullName}? {formattedPriReference}}}";
+ // var capacity = (uint)outBuffer.Capacity;
+ // var hResult = SHLoadIndirectString(source, outBuffer, capacity, IntPtr.Zero);
+ // if (hResult == Hresult.Ok)
+ // {
+ // var loaded = outBuffer.ToString();
+ // if (!string.IsNullOrEmpty(loaded))
+ // {
+ // return loaded;
+ // }
+ // else
+ // {
+ // ProgramLogger.LogException($"|UWP|ResourceFromPri|{Location}|Can't load null or empty result "
+ // + $"pri {source} in uwp location {Location}", new NullReferenceException());
+ // return string.Empty;
+ // }
+ // }
+ // else
+ // {
+ // var e = Marshal.GetExceptionForHR((int)hResult);
+ // ProgramLogger.LogException($"|UWP|ResourceFromPri|{Location}|Load pri failed {source} with HResult {hResult} and location {Location}", e);
+ // return string.Empty;
+ // }
+ //}
- public static string FormattedPriReferenceValue(string packageName, string rawPriReferenceValue)
- {
- const string prefix = "ms-resource:";
+ //public static string FormattedPriReferenceValue(string packageName, string rawPriReferenceValue)
+ //{
+ // const string prefix = "ms-resource:";
- if (string.IsNullOrWhiteSpace(rawPriReferenceValue) || !rawPriReferenceValue.StartsWith(prefix))
- return rawPriReferenceValue;
+ // if (string.IsNullOrWhiteSpace(rawPriReferenceValue) || !rawPriReferenceValue.StartsWith(prefix))
+ // return rawPriReferenceValue;
- string key = rawPriReferenceValue.Substring(prefix.Length);
- if (key.StartsWith("//"))
- return $"{prefix}{key}";
+ // string key = rawPriReferenceValue.Substring(prefix.Length);
+ // if (key.StartsWith("//"))
+ // return $"{prefix}{key}";
- if (!key.StartsWith("/"))
- {
- key = $"/{key}";
- }
+ // if (!key.StartsWith("/"))
+ // {
+ // key = $"/{key}";
+ // }
- if (!key.ToLower().Contains("resources"))
- {
- key = $"/Resources{key}";
- }
+ // if (!key.ToLower().Contains("resources"))
+ // {
+ // key = $"/Resources{key}";
+ // }
- return $"{prefix}//{packageName}{key}";
- }
+ // return $"{prefix}//{packageName}{key}";
+ //}
internal void InitLogoPathFromUri(string uri)
{
@@ -881,26 +879,26 @@ namespace Flow.Launcher.Plugin.Program.Programs
Unknown
}
- [Flags]
- private enum Stgm : uint
- {
- Read = 0x0,
- ShareExclusive = 0x10,
- ShareDenyNone = 0x40
- }
+ //[Flags]
+ //private enum Stgm : uint
+ //{
+ // Read = 0x0,
+ // ShareExclusive = 0x10,
+ // ShareDenyNone = 0x40
+ //}
- private enum Hresult : uint
- {
- Ok = 0x0000,
- }
+ //private enum Hresult : uint
+ //{
+ // Ok = 0x0000,
+ //}
- [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
- private static extern Hresult SHCreateStreamOnFileEx(string fileName, Stgm grfMode, uint attributes, bool create,
- IStream reserved, out IStream stream);
+ //[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
+ //private static extern Hresult SHCreateStreamOnFileEx(string fileName, Stgm grfMode, uint attributes, bool create,
+ // IStream reserved, out IStream stream);
- [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
- private static extern Hresult SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf,
- IntPtr ppvReserved);
+ //[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
+ //private static extern Hresult SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf,
+ // IntPtr ppvReserved);
}
}
From 0374e9f56fb1608be3feb055c99159c0ec343500 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 22:13:55 +0800
Subject: [PATCH 14/36] set default values of fields
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index c287e31e9..d4a41fc07 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -365,14 +365,12 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
private string _uid = string.Empty;
public string UniqueIdentifier { get => _uid; set => _uid = value == null ? string.Empty : value.ToLowerInvariant(); }
- public string DisplayName { get; set; }
- public string Description { get; set; }
- public string UserModelId { get; set; }
- public string BackgroundColor { get; set; } = "transparent";
-
- public string EntryPoint { get; set; }
+ public string DisplayName { get; set; } = string.Empty;
+ public string Description { get; set; } = string.Empty;
+ public string UserModelId { get; set; } = string.Empty;
+ public string BackgroundColor { get; set; } = string.Empty;
public string Name => DisplayName;
- public string Location { get; set; }
+ public string Location { get; set; } = string.Empty;
public bool Enabled { get; set; } = false;
public bool CanRunElevated { get; set; } = false;
From 07a68ed1920f37ff414089d5ac57b08ec1b24bd7 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Mon, 28 Nov 2022 22:55:10 +0800
Subject: [PATCH 15/36] Use imageloader to load icon
---
.../Programs/UWP.cs | 38 +------------------
1 file changed, 2 insertions(+), 36 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index d4a41fc07..5198f5761 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -128,41 +128,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
}
- //private void InitializeAppInfo()
- //{
- // var path = Path.Combine(Location, "AppxManifest.xml");
-
- // var namespaces = XmlNamespaces(path);
- // InitPackageVersion(namespaces);
-
- // const uint noAttribute = 0x80;
- // const Stgm nonExclusiveRead = Stgm.Read | Stgm.ShareDenyNone;
- // var hResult = SHCreateStreamOnFileEx(path, nonExclusiveRead, noAttribute, false, null, out IStream stream);
-
- // if (hResult == Hresult.Ok)
- // {
- // List _apps = AppxPackageHelper.GetAppsFromManifest(stream);
-
- // Apps = _apps.Select(x => new Application(x, this))
- // .Where(a => !string.IsNullOrEmpty(a.UserModelId)
- // && !string.IsNullOrEmpty(a.DisplayName))
- // .ToArray();
- // }
- // else
- // {
- // var e = Marshal.GetExceptionForHR((int)hResult);
- // ProgramLogger.LogException($"|UWP|InitializeAppInfo|{path}" +
- // "|Error caused while trying to get the details of the UWP program", e);
-
- // Apps = Array.Empty();
- // }
-
- // if (stream != null && Marshal.ReleaseComObject(stream) > 0)
- // {
- // Log.Error("Flow.Launcher.Plugin.Program.Programs.UWP", "AppxManifest.xml was leaked");
- // }
- //}
-
/// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx
private PackageVersion GetPackageVersionFromManifest(XmlElement xmlRoot)
{
@@ -425,7 +390,8 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
Title = title,
SubTitle = Main._settings.HideAppsPath ? string.Empty : Location,
- Icon = Logo,
+ //Icon = Logo,
+ IcoPath = LogoPath,
Score = matchResult.Score,
TitleHighlightData = matchResult.MatchData,
ContextData = this,
From b50f43ae7cdc646400c0744094974419a4caa744 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 01:02:53 +0800
Subject: [PATCH 16/36] Remove ApplicationActivationHelper
---
.../Programs/ApplicationActivationHelper.cs | 42 -----------------
.../Programs/UWP.cs | 47 ++++---------------
.../Programs/Win32.cs | 4 +-
3 files changed, 12 insertions(+), 81 deletions(-)
delete mode 100644 Plugins/Flow.Launcher.Plugin.Program/Programs/ApplicationActivationHelper.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ApplicationActivationHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ApplicationActivationHelper.cs
deleted file mode 100644
index 790a70392..000000000
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ApplicationActivationHelper.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace Flow.Launcher.Plugin.Program.Programs
-{
- public class ApplicationActivationHelper
- {
- // Reference : https://github.com/MicrosoftEdge/edge-launcher/blob/108e63df0b4cb5cd9d5e45aa7a264690851ec51d/MIcrosoftEdgeLauncherCsharp/Program.cs
- public enum ActivateOptions
- {
- None = 0x00000000,
- DesignMode = 0x00000001,
- NoErrorUI = 0x00000002,
- NoSplashScreen = 0x00000004,
- }
-
- /// ApplicationActivationManager
- [ComImport, Guid("2e941141-7f97-4756-ba1d-9decde894a3d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- interface IApplicationActivationManager
- {
- IntPtr ActivateApplication([In] string appUserModelId, [In] string arguments, [In] ActivateOptions options, [Out] out uint processId);
- IntPtr ActivateForFile([In] string appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] string verb, [Out] out uint processId);
- IntPtr ActivateForProtocol([In] string appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out uint processId);
- }
-
- // Application Activation Manager Class
- [ComImport, Guid("45BA127D-10A8-46EA-8AB7-56EA9078943C")]
- public class ApplicationActivationManager : IApplicationActivationManager
- {
-
- [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)/*, PreserveSig*/]
- public extern IntPtr ActivateApplication([In] string appUserModelId, [In] string arguments, [In] ActivateOptions options, [Out] out uint processId);
-
- [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
- public extern IntPtr ActivateForFile([In] string appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] string verb, [Out] out uint processId);
-
- [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
- public extern IntPtr ActivateForProtocol([In] string appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out uint processId);
- }
- }
-}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 5198f5761..47443b7ee 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -404,20 +404,13 @@ namespace Flow.Launcher.Plugin.Program.Programs
!e.SpecialKeyState.WinPressed
);
- if (elevated && CanRunElevated)
+ bool shouldRunElevated = elevated && CanRunElevated;
+ _ = Task.Run(() => Launch(shouldRunElevated)).ConfigureAwait(false);
+ if (elevated && !shouldRunElevated)
{
- LaunchElevated();
- }
- else
- {
- Launch(api);
-
- if (elevated)
- {
- var title = "Plugin: Program";
- var message = api.GetTranslation("flowlauncher_plugin_program_run_as_administrator_not_supported_message");
- api.ShowMsg(title, message, string.Empty);
- }
+ var title = "Plugin: Program";
+ var message = api.GetTranslation("flowlauncher_plugin_program_run_as_administrator_not_supported_message");
+ api.ShowMsg(title, message, string.Empty);
}
return true;
@@ -452,7 +445,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
Title = api.GetTranslation("flowlauncher_plugin_program_run_as_administrator"),
Action = _ =>
{
- LaunchElevated();
+ Task.Run(() => Launch(true)).ConfigureAwait(false);
return true;
},
IcoPath = "Images/cmd.png"
@@ -462,35 +455,15 @@ namespace Flow.Launcher.Plugin.Program.Programs
return contextMenus;
}
- private async void Launch(IPublicAPI api)
+ private void Launch(bool elevated=false)
{
- var appManager = new ApplicationActivationHelper.ApplicationActivationManager();
- const string noArgs = "";
- const ApplicationActivationHelper.ActivateOptions noFlags = ApplicationActivationHelper.ActivateOptions.None;
- await Task.Run(() =>
- {
- try
- {
- _ = appManager.ActivateApplication(UserModelId, noArgs, noFlags, out _);
- }
- catch (Exception)
- {
- var name = "Plugin: Program";
- var message = $"Can't start UWP: {DisplayName}";
- api.ShowMsg(name, message, string.Empty);
- }
- });
- }
-
- private void LaunchElevated()
- {
- string command = "shell:AppsFolder\\" + UniqueIdentifier;
+ string command = "shell:AppsFolder\\" + UserModelId;
command = Environment.ExpandEnvironmentVariables(command.Trim());
var info = new ProcessStartInfo(command)
{
UseShellExecute = true,
- Verb = "runas",
+ Verb = elevated ? "runas" : ""
};
Main.StartProcess(Process.Start, info);
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
index 7fbffb548..e89970fb4 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
@@ -142,10 +142,10 @@ namespace Flow.Launcher.Plugin.Program.Programs
FileName = FullPath,
WorkingDirectory = ParentDirectory,
UseShellExecute = true,
- Verb = runAsAdmin ? "runas" : null
+ Verb = runAsAdmin ? "runas" : ""
};
- Task.Run(() => Main.StartProcess(Process.Start, info));
+ _ = Task.Run(() => Main.StartProcess(Process.Start, info));
return true;
}
From df30ec97424269e8a0ddfb172750b9ca90889523 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 01:22:13 +0800
Subject: [PATCH 17/36] Init apps after construction
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 47443b7ee..56ccfc22c 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -40,10 +40,9 @@ namespace Flow.Launcher.Plugin.Program.Programs
Name = package.Id.Name;
FullName = package.Id.FullName;
FamilyName = package.Id.FamilyName;
- InitAppsInPackage(package);
}
- private void InitAppsInPackage(Package package)
+ public void InitAppsInPackage(Package package)
{
var applist = new List();
// WinRT
@@ -195,6 +194,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
try
{
u = new UWP(p);
+ u.InitAppsInPackage(p);
}
#if !DEBUG
catch (Exception e)
@@ -245,22 +245,19 @@ namespace Flow.Launcher.Plugin.Program.Programs
var ps = m.FindPackagesForUser(id);
ps = ps.Where(p =>
{
- bool valid;
try
{
var f = p.IsFramework;
var d = p.IsDevelopmentMode;
var path = p.InstalledLocation.Path;
- valid = !f && !d && !string.IsNullOrEmpty(path);
+ return !f && !d && !string.IsNullOrEmpty(path);
}
catch (Exception e)
{
- ProgramLogger.LogException("UWP", "CurrentUserPackages", $"id", "An unexpected error occured and "
+ ProgramLogger.LogException("UWP", "CurrentUserPackages", $"{id}", "An unexpected error occured and "
+ $"unable to verify if package is valid", e);
return false;
}
-
- return valid;
});
return ps;
}
From 202c660ee64148fb2122969d9011bad11b2bea3c Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 01:46:48 +0800
Subject: [PATCH 18/36] Log exceptions when initing apps
---
.../Programs/UWP.cs | 26 ++++++++++++-------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 56ccfc22c..ab582a033 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -56,7 +56,9 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
catch (Exception e)
{
- // TODO Logging
+ ProgramLogger.LogException($"|UWP|InitAppsInPackage|{Location}" +
+ "|Unexpected exception occurs when trying to construct a Application from package"
+ + $"{FullName} from location {Location}", e);
}
}
Apps = applist.ToArray();
@@ -72,7 +74,10 @@ namespace Flow.Launcher.Plugin.Program.Programs
var xmlRoot = xmlDoc.DocumentElement;
var packageVersion = GetPackageVersionFromManifest(xmlRoot);
- var logoName = logoNameFromNamespace[packageVersion];
+ if (!logoNameFromVersion.TryGetValue(packageVersion, out string logoName))
+ {
+ return;
+ }
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceManager.AddNamespace("", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
@@ -92,15 +97,18 @@ namespace Flow.Launcher.Plugin.Program.Programs
if (appNode != null)
{
app.CanRunElevated = packageCanElevate || Application.IfAppCanRunElevated(appNode, namespaceManager);
+
var visualElement = appNode.SelectSingleNode($"//*[name()='uap:VisualElements']", namespaceManager);
var logoUri = visualElement.Attributes[logoName]?.Value;
- app.InitLogoPathFromUri(logoUri);
+ app.LogoPath = app.LogoPathFromUri(logoUri);
}
}
}
catch (Exception e)
{
- // TODO Logging
+ ProgramLogger.LogException($"|UWP|InitAppsInPackage|{Location}" +
+ "|Unexpected exception occurs when trying to construct a Application from package"
+ + $"{FullName} from location {Location}", e);
}
}
@@ -143,15 +151,15 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
ProgramLogger.LogException($"|UWP|GetPackageVersionFromManifest|{Location}" +
- "|Trying to get the package version of the UWP program, but an unknown UWP appmanifest version "
- + $"{FullName} from location {Location} is returned.", new FormatException());
+ "|Trying to get the package version of the UWP program, but an unknown UWP appmanifest version in package "
+ + $"{FullName} from location {Location}", new FormatException());
return PackageVersion.Unknown;
}
else
{
ProgramLogger.LogException($"|UWP|GetPackageVersionFromManifest|{Location}" +
- "|Can't parse AppManifest.xml"
- + $"{FullName} from location {Location} is returned.", new ArgumentNullException(nameof(xmlRoot)));
+ "|Can't parse AppManifest.xml of package "
+ + $"{FullName} from location {Location}", new ArgumentNullException(nameof(xmlRoot)));
return PackageVersion.Unknown;
}
}
@@ -169,7 +177,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
},
};
- private static readonly Dictionary logoNameFromNamespace = new()
+ private static readonly Dictionary logoNameFromVersion = new()
{
{
PackageVersion.Windows10, "Square44x44Logo"
From a9c271502a85088868a82afbd6678dc532b48e4a Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 01:48:04 +0800
Subject: [PATCH 19/36] Reuse LogoPathFromUri() for preview image
---
.../Programs/UWP.cs | 22 +++++++------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index ab582a033..1d292cbab 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -78,7 +78,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
return;
}
-
+
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceManager.AddNamespace("", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
namespaceManager.AddNamespace("rescap", "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities");
@@ -593,7 +593,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
// return $"{prefix}//{packageName}{key}";
//}
- internal void InitLogoPathFromUri(string uri)
+ internal string LogoPathFromUri(string uri)
{
// all https://msdn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets
// windows 10 https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx
@@ -602,13 +602,15 @@ namespace Flow.Launcher.Plugin.Program.Programs
if (string.IsNullOrWhiteSpace(uri))
{
- throw new ArgumentException("uri");
+ ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Location}" +
+ $"|{UserModelId} 's logo uri is null or empty: {Location}", new ArgumentException("uri"));
+ return string.Empty;
}
string path = Path.Combine(Location, uri);
var logoPath = TryToFindLogo(uri, path);
- if (String.IsNullOrEmpty(logoPath))
+ if (logoPath == string.Empty)
{
var tmp = Path.Combine(Location, "Assets", uri);
if (!path.Equals(tmp, StringComparison.OrdinalIgnoreCase))
@@ -616,17 +618,10 @@ namespace Flow.Launcher.Plugin.Program.Programs
// TODO: Don't know why, just keep it at the moment
// Maybe on older version of Windows 10?
// for C:\Windows\MiracastView etc
- logoPath = TryToFindLogo(uri, tmp);
- if (!String.IsNullOrEmpty(logoPath))
- {
- LogoPath = logoPath;
- }
+ return TryToFindLogo(uri, tmp);
}
}
- else
- {
- LogoPath = logoPath;
- }
+ return logoPath;
string TryToFindLogo(string uri, string path)
{
@@ -714,7 +709,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
private BitmapImage ImageFromPath(string path)
{
- // TODO: Consider using infrastructure.image.imageloader?
if (File.Exists(path))
{
var image = new BitmapImage();
From da19788df14fb46ef2343d736228b734ce1ffdf0 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 02:06:11 +0800
Subject: [PATCH 20/36] Fix potential null reference
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 1d292cbab..33c469acb 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -32,7 +32,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
public Application[] Apps { get; set; } = Array.Empty();
- //public PackageVersion Version { get; set; }
public UWP(Package package)
{
@@ -99,7 +98,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
app.CanRunElevated = packageCanElevate || Application.IfAppCanRunElevated(appNode, namespaceManager);
var visualElement = appNode.SelectSingleNode($"//*[name()='uap:VisualElements']", namespaceManager);
- var logoUri = visualElement.Attributes[logoName]?.Value;
+ var logoUri = visualElement?.Attributes[logoName]?.Value;
app.LogoPath = app.LogoPathFromUri(logoUri);
}
}
@@ -110,7 +109,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
"|Unexpected exception occurs when trying to construct a Application from package"
+ $"{FullName} from location {Location}", e);
}
-
}
private XmlDocument GetManifestXml()
@@ -635,7 +633,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
var logoNamePrefix = Path.GetFileNameWithoutExtension(uri); // e.g Square44x44
var logoDir = Path.GetDirectoryName(path); // e.g ..\..\Assets
- if (String.IsNullOrEmpty(logoNamePrefix) || String.IsNullOrEmpty(logoDir) || !Directory.Exists(logoDir))
+ if (String.IsNullOrEmpty(logoNamePrefix) || !Directory.Exists(logoDir))
{
// Known issue: Edge always triggers it since logo is not at uri
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Location}" +
From 729983352901bcd1e919686666e01561a62d86cf Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 02:14:43 +0800
Subject: [PATCH 21/36] Formatting
---
.../Programs/UWP.cs | 137 +-----------------
1 file changed, 2 insertions(+), 135 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 33c469acb..c9cdf9cd7 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -3,10 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.ComTypes;
using System.Security.Principal;
-using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
@@ -77,7 +74,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
return;
}
-
+
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceManager.AddNamespace("", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
namespaceManager.AddNamespace("rescap", "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities");
@@ -393,7 +390,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
{
Title = title,
SubTitle = Main._settings.HideAppsPath ? string.Empty : Location,
- //Icon = Logo,
IcoPath = LogoPath,
Score = matchResult.Score,
TitleHighlightData = matchResult.MatchData,
@@ -458,7 +454,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
return contextMenus;
}
- private void Launch(bool elevated=false)
+ private void Launch(bool elevated = false)
{
string command = "shell:AppsFolder\\" + UserModelId;
command = Environment.ExpandEnvironmentVariables(command.Trim());
@@ -472,56 +468,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
Main.StartProcess(Process.Start, info);
}
- //public Application(AppxPackageHelper.IAppxManifestApplication manifestApp, UWP package)
- //{
- // // This is done because we cannot use the keyword 'out' along with a property
-
- // manifestApp.GetAppUserModelId(out string tmpUserModelId);
- // manifestApp.GetAppUserModelId(out string tmpUniqueIdentifier);
- // manifestApp.GetStringValue("DisplayName", out string tmpDisplayName);
- // manifestApp.GetStringValue("Description", out string tmpDescription);
- // manifestApp.GetStringValue("BackgroundColor", out string tmpBackgroundColor);
- // manifestApp.GetStringValue("EntryPoint", out string tmpEntryPoint);
-
- // UserModelId = tmpUserModelId;
- // UniqueIdentifier = tmpUniqueIdentifier;
- // DisplayName = tmpDisplayName;
- // Description = tmpDescription;
- // BackgroundColor = tmpBackgroundColor;
- // EntryPoint = tmpEntryPoint;
-
- // Location = package.Location;
-
- // DisplayName = ResourceFromPri(package.FullName, package.Name, DisplayName);
- // Description = ResourceFromPri(package.FullName, package.Name, Description);
- // LogoUri = LogoUriFromManifest(manifestApp);
- // LogoPath = LogoPathFromUri(LogoUri);
-
- // Enabled = true;
- // CanRunElevated = CanApplicationRunElevated();
- //}
-
- //private bool CanApplicationRunElevated()
- //{
- // if (EntryPoint == "Windows.FullTrustApplication")
- // {
- // return true;
- // }
-
- // var manifest = Location + "\\AppxManifest.xml";
- // if (File.Exists(manifest))
- // {
- // var file = File.ReadAllText(manifest);
-
- // if (file.Contains("TrustLevel=\"mediumIL\"", StringComparison.OrdinalIgnoreCase))
- // {
- // return true;
- // }
- // }
-
- // return false;
- //}
-
internal static bool IfAppCanRunElevated(XmlNode appNode, XmlNamespaceManager namespaceManager)
{
// According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package
@@ -534,63 +480,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
trustLevelNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL";
}
- //internal string ResourceFromPri(string packageFullName, string packageName, string rawReferenceValue)
- //{
- // if (string.IsNullOrWhiteSpace(rawReferenceValue) || !rawReferenceValue.StartsWith("ms-resource:"))
- // return rawReferenceValue;
-
- // var formattedPriReference = FormattedPriReferenceValue(packageName, rawReferenceValue);
-
- // var outBuffer = new StringBuilder(128);
- // string source = $"@{{{packageFullName}? {formattedPriReference}}}";
- // var capacity = (uint)outBuffer.Capacity;
- // var hResult = SHLoadIndirectString(source, outBuffer, capacity, IntPtr.Zero);
- // if (hResult == Hresult.Ok)
- // {
- // var loaded = outBuffer.ToString();
- // if (!string.IsNullOrEmpty(loaded))
- // {
- // return loaded;
- // }
- // else
- // {
- // ProgramLogger.LogException($"|UWP|ResourceFromPri|{Location}|Can't load null or empty result "
- // + $"pri {source} in uwp location {Location}", new NullReferenceException());
- // return string.Empty;
- // }
- // }
- // else
- // {
- // var e = Marshal.GetExceptionForHR((int)hResult);
- // ProgramLogger.LogException($"|UWP|ResourceFromPri|{Location}|Load pri failed {source} with HResult {hResult} and location {Location}", e);
- // return string.Empty;
- // }
- //}
-
- //public static string FormattedPriReferenceValue(string packageName, string rawPriReferenceValue)
- //{
- // const string prefix = "ms-resource:";
-
- // if (string.IsNullOrWhiteSpace(rawPriReferenceValue) || !rawPriReferenceValue.StartsWith(prefix))
- // return rawPriReferenceValue;
-
- // string key = rawPriReferenceValue.Substring(prefix.Length);
- // if (key.StartsWith("//"))
- // return $"{prefix}{key}";
-
- // if (!key.StartsWith("/"))
- // {
- // key = $"/{key}";
- // }
-
- // if (!key.ToLower().Contains("resources"))
- // {
- // key = $"/Resources{key}";
- // }
-
- // return $"{prefix}//{packageName}{key}";
- //}
-
internal string LogoPathFromUri(string uri)
{
// all https://msdn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets
@@ -812,27 +701,5 @@ namespace Flow.Launcher.Plugin.Program.Programs
Windows8,
Unknown
}
-
- //[Flags]
- //private enum Stgm : uint
- //{
- // Read = 0x0,
- // ShareExclusive = 0x10,
- // ShareDenyNone = 0x40
- //}
-
- //private enum Hresult : uint
- //{
- // Ok = 0x0000,
- //}
-
- //[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
- //private static extern Hresult SHCreateStreamOnFileEx(string fileName, Stgm grfMode, uint attributes, bool create,
- // IStream reserved, out IStream stream);
-
- //[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
- //private static extern Hresult SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf,
- // IntPtr ppvReserved);
-
}
}
From 220f9f1dd4588d1e22e7700d138e8ff565951d49 Mon Sep 17 00:00:00 2001
From: Jeremy Wu
Date: Tue, 29 Nov 2022 07:25:12 +1100
Subject: [PATCH 22/36] add sponsor
---
README.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/README.md b/README.md
index 1441c8b39..ca17f1130 100644
--- a/README.md
+++ b/README.md
@@ -270,6 +270,10 @@ And you can download
+
+
+
+
From 843c9e1d925bee3b69c839ab13f7f354dc1f9634 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 28 Nov 2022 22:16:37 +0000
Subject: [PATCH 23/36] Bump Microsoft.IO.RecyclableMemoryStream from 2.1.3 to
2.2.1
Bumps [Microsoft.IO.RecyclableMemoryStream](https://github.com/Microsoft/Microsoft.IO.RecyclableMemoryStream) from 2.1.3 to 2.2.1.
- [Release notes](https://github.com/Microsoft/Microsoft.IO.RecyclableMemoryStream/releases)
- [Changelog](https://github.com/microsoft/Microsoft.IO.RecyclableMemoryStream/blob/master/CHANGES.md)
- [Commits](https://github.com/Microsoft/Microsoft.IO.RecyclableMemoryStream/compare/2.1.3...2.2.1)
---
updated-dependencies:
- dependency-name: Microsoft.IO.RecyclableMemoryStream
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
index 7d18c467b..ec99dc520 100644
--- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj
+++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj
@@ -55,7 +55,7 @@
-
+
From f40f41628da05becc9a122da096aa2d2112475ff Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 12:12:09 +0800
Subject: [PATCH 24/36] Comment legacy logo code
---
.../Programs/UWP.cs | 162 +++++++++---------
1 file changed, 83 insertions(+), 79 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index c9cdf9cd7..756334ec6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -333,7 +333,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
public string DisplayName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string UserModelId { get; set; } = string.Empty;
- public string BackgroundColor { get; set; } = string.Empty;
+ //public string BackgroundColor { get; set; } = string.Empty; // preserve for future use
public string Name => DisplayName;
public string Location { get; set; } = string.Empty;
@@ -585,92 +585,96 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
- public ImageSource Logo()
- {
- var logo = ImageFromPath(LogoPath);
- var plated = PlatedImage(logo); // TODO: maybe get plated directly from app package?
+ #region logo legacy
+ // preserve for potential future use
- // todo magic! temp fix for cross thread object
- plated.Freeze();
- return plated;
- }
- private BitmapImage ImageFromPath(string path)
- {
- if (File.Exists(path))
- {
- var image = new BitmapImage();
- image.BeginInit();
- image.UriSource = new Uri(path);
- image.CacheOption = BitmapCacheOption.OnLoad;
- image.EndInit();
- image.Freeze();
- return image;
- }
- else
- {
- ProgramLogger.LogException($"|UWP|ImageFromPath|{(string.IsNullOrEmpty(path) ? "Not Avaliable" : path)}" +
- $"|Unable to get logo for {UserModelId} from {path} and" +
- $" located in {Location}", new FileNotFoundException());
- return new BitmapImage(new Uri(Constant.MissingImgIcon));
- }
- }
+ //public ImageSource Logo()
+ //{
+ // var logo = ImageFromPath(LogoPath);
+ // var plated = PlatedImage(logo); // TODO: maybe get plated directly from app package?
- private ImageSource PlatedImage(BitmapImage image)
- {
- if (!string.IsNullOrEmpty(BackgroundColor) && BackgroundColor != "transparent")
- {
- var width = image.Width;
- var height = image.Height;
- var x = 0;
- var y = 0;
+ // // todo magic! temp fix for cross thread object
+ // plated.Freeze();
+ // return plated;
+ //}
+ //private BitmapImage ImageFromPath(string path)
+ //{
+ // if (File.Exists(path))
+ // {
+ // var image = new BitmapImage();
+ // image.BeginInit();
+ // image.UriSource = new Uri(path);
+ // image.CacheOption = BitmapCacheOption.OnLoad;
+ // image.EndInit();
+ // image.Freeze();
+ // return image;
+ // }
+ // else
+ // {
+ // ProgramLogger.LogException($"|UWP|ImageFromPath|{(string.IsNullOrEmpty(path) ? "Not Avaliable" : path)}" +
+ // $"|Unable to get logo for {UserModelId} from {path} and" +
+ // $" located in {Location}", new FileNotFoundException());
+ // return new BitmapImage(new Uri(Constant.MissingImgIcon));
+ // }
+ //}
- var group = new DrawingGroup();
+ //private ImageSource PlatedImage(BitmapImage image)
+ //{
+ // if (!string.IsNullOrEmpty(BackgroundColor) && BackgroundColor != "transparent")
+ // {
+ // var width = image.Width;
+ // var height = image.Height;
+ // var x = 0;
+ // var y = 0;
- var converted = ColorConverter.ConvertFromString(BackgroundColor);
- if (converted != null)
- {
- var color = (Color)converted;
- var brush = new SolidColorBrush(color);
- var pen = new Pen(brush, 1);
- var backgroundArea = new Rect(0, 0, width, width);
- var rectabgle = new RectangleGeometry(backgroundArea);
- var rectDrawing = new GeometryDrawing(brush, pen, rectabgle);
- group.Children.Add(rectDrawing);
+ // var group = new DrawingGroup();
- var imageArea = new Rect(x, y, image.Width, image.Height);
- var imageDrawing = new ImageDrawing(image, imageArea);
- group.Children.Add(imageDrawing);
+ // var converted = ColorConverter.ConvertFromString(BackgroundColor);
+ // if (converted != null)
+ // {
+ // var color = (Color)converted;
+ // var brush = new SolidColorBrush(color);
+ // var pen = new Pen(brush, 1);
+ // var backgroundArea = new Rect(0, 0, width, width);
+ // var rectabgle = new RectangleGeometry(backgroundArea);
+ // var rectDrawing = new GeometryDrawing(brush, pen, rectabgle);
+ // group.Children.Add(rectDrawing);
- // http://stackoverflow.com/questions/6676072/get-system-drawing-bitmap-of-a-wpf-area-using-visualbrush
- var visual = new DrawingVisual();
- var context = visual.RenderOpen();
- context.DrawDrawing(group);
- context.Close();
- const int dpiScale100 = 96;
- var bitmap = new RenderTargetBitmap(
- Convert.ToInt32(width), Convert.ToInt32(height),
- dpiScale100, dpiScale100,
- PixelFormats.Pbgra32
- );
- bitmap.Render(visual);
- return bitmap;
- }
- else
- {
- ProgramLogger.LogException($"|UWP|PlatedImage|{Location}" +
- $"|Unable to convert background string {BackgroundColor} " +
- $"to color for {Location}", new InvalidOperationException());
+ // var imageArea = new Rect(x, y, image.Width, image.Height);
+ // var imageDrawing = new ImageDrawing(image, imageArea);
+ // group.Children.Add(imageDrawing);
- return new BitmapImage(new Uri(Constant.MissingImgIcon));
- }
- }
- else
- {
- // todo use windows theme as background
- return image;
- }
- }
+ // // http://stackoverflow.com/questions/6676072/get-system-drawing-bitmap-of-a-wpf-area-using-visualbrush
+ // var visual = new DrawingVisual();
+ // var context = visual.RenderOpen();
+ // context.DrawDrawing(group);
+ // context.Close();
+ // const int dpiScale100 = 96;
+ // var bitmap = new RenderTargetBitmap(
+ // Convert.ToInt32(width), Convert.ToInt32(height),
+ // dpiScale100, dpiScale100,
+ // PixelFormats.Pbgra32
+ // );
+ // bitmap.Render(visual);
+ // return bitmap;
+ // }
+ // else
+ // {
+ // ProgramLogger.LogException($"|UWP|PlatedImage|{Location}" +
+ // $"|Unable to convert background string {BackgroundColor} " +
+ // $"to color for {Location}", new InvalidOperationException());
+ // return new BitmapImage(new Uri(Constant.MissingImgIcon));
+ // }
+ // }
+ // else
+ // {
+ // // todo use windows theme as background
+ // return image;
+ // }
+ //}
+
+ #endregion
public override string ToString()
{
return $"{DisplayName}: {Description}";
From 78bc3f48093d4373ba3d0ae68835fe5a935b8c75 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 12:30:36 +0800
Subject: [PATCH 25/36] Prepare for preview panel
---
.../Programs/UWP.cs | 39 ++++++++++++++-----
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 756334ec6..05194b8de 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -70,7 +70,8 @@ namespace Flow.Launcher.Plugin.Program.Programs
var xmlRoot = xmlDoc.DocumentElement;
var packageVersion = GetPackageVersionFromManifest(xmlRoot);
- if (!logoNameFromVersion.TryGetValue(packageVersion, out string logoName))
+ if (!smallLogoNameFromVersion.TryGetValue(packageVersion, out string logoName) ||
+ !bigLogoNameFromVersion.TryGetValue(packageVersion, out string bigLogoName))
{
return;
}
@@ -96,7 +97,9 @@ namespace Flow.Launcher.Plugin.Program.Programs
var visualElement = appNode.SelectSingleNode($"//*[name()='uap:VisualElements']", namespaceManager);
var logoUri = visualElement?.Attributes[logoName]?.Value;
- app.LogoPath = app.LogoPathFromUri(logoUri);
+ app.LogoPath = app.LogoPathFromUri(logoUri, (32, 32));
+ var previewUri = visualElement?.Attributes[bigLogoName]?.Value;
+ app.PreviewImagePath = app.LogoPathFromUri(previewUri, (128, 128));
}
}
}
@@ -172,7 +175,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
},
};
- private static readonly Dictionary logoNameFromVersion = new()
+ private static readonly Dictionary smallLogoNameFromVersion = new()
{
{
PackageVersion.Windows10, "Square44x44Logo"
@@ -185,6 +188,19 @@ namespace Flow.Launcher.Plugin.Program.Programs
},
};
+ private static readonly Dictionary bigLogoNameFromVersion = new()
+ {
+ {
+ PackageVersion.Windows10, "Square150x150Logo"
+ },
+ {
+ PackageVersion.Windows81, "Square150x150Logo"
+ },
+ {
+ PackageVersion.Windows8, "Logo"
+ },
+ };
+
public static Application[] All()
{
var windows10 = new Version(10, 0);
@@ -340,6 +356,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
public bool Enabled { get; set; } = false;
public bool CanRunElevated { get; set; } = false;
public string LogoPath { get; set; } = string.Empty;
+ public string PreviewImagePath { get; set; } = string.Empty;
public Application(AppListEntry appListEntry, UWP package)
{
@@ -480,7 +497,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
trustLevelNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL";
}
- internal string LogoPathFromUri(string uri)
+ internal string LogoPathFromUri(string uri, (int, int) desiredSize)
{
// all https://msdn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets
// windows 10 https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx
@@ -496,7 +513,8 @@ namespace Flow.Launcher.Plugin.Program.Programs
string path = Path.Combine(Location, uri);
- var logoPath = TryToFindLogo(uri, path);
+ var pxCount = desiredSize.Item1 * desiredSize.Item2;
+ var logoPath = TryToFindLogo(uri, path, pxCount);
if (logoPath == string.Empty)
{
var tmp = Path.Combine(Location, "Assets", uri);
@@ -505,12 +523,12 @@ namespace Flow.Launcher.Plugin.Program.Programs
// TODO: Don't know why, just keep it at the moment
// Maybe on older version of Windows 10?
// for C:\Windows\MiracastView etc
- return TryToFindLogo(uri, tmp);
+ return TryToFindLogo(uri, tmp, pxCount);
}
}
return logoPath;
- string TryToFindLogo(string uri, string path)
+ string TryToFindLogo(string uri, string path, int px)
{
var extension = Path.GetExtension(path);
if (extension != null)
@@ -544,6 +562,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
var selected = logos.FirstOrDefault();
var closest = selected;
int min = int.MaxValue;
+ // TODO in one iterartion find preview and logo
foreach (var logo in logos)
{
@@ -551,13 +570,13 @@ namespace Flow.Launcher.Plugin.Program.Programs
var decoder = BitmapDecoder.Create(imageStream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None);
var height = decoder.Frames[0].PixelHeight;
var width = decoder.Frames[0].PixelWidth;
- int pixelCountDiff = Math.Abs(height * width - 1936); // 44*44=1936
+ int pixelCountDiff = Math.Abs(height * width - px);
if (pixelCountDiff < min)
{
- // try to find the closest to 44x44 logo
+ // try to find the closest to desired size
closest = logo;
if (pixelCountDiff == 0)
- break; // found 44x44
+ break; // found
min = pixelCountDiff;
}
}
From 2fd241d776d20e44367e42cbbda0e1d1dd3926ca Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 14:34:15 +0800
Subject: [PATCH 26/36] Use search pattern in Directory.EnumerateFiles
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 05194b8de..795588aa6 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -548,21 +548,16 @@ namespace Flow.Launcher.Plugin.Program.Programs
return string.Empty;
}
- var files = Directory.EnumerateFiles(logoDir);
+ var logos = Directory.EnumerateFiles(logoDir, $"{logoNamePrefix}*{extension}");
// Currently we don't care which one to choose
// Just ignore all qualifiers
// select like logo.[xxx_yyy].png
// https://learn.microsoft.com/en-us/windows/uwp/app-resources/tailor-resources-lang-scale-contrast
- var logos = files.Where(file =>
- Path.GetFileName(file)?.StartsWith(logoNamePrefix, StringComparison.OrdinalIgnoreCase) ?? false
- && extension.Equals(Path.GetExtension(file), StringComparison.OrdinalIgnoreCase)
- );
var selected = logos.FirstOrDefault();
var closest = selected;
int min = int.MaxValue;
- // TODO in one iterartion find preview and logo
foreach (var logo in logos)
{
From f9fbd0887310eb528b7cfbdbabfb6aba742f5db8 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 14:38:09 +0800
Subject: [PATCH 27/36] Delete unused file
---
.../Programs/AppxPackageHelper.cs | 80 -------------------
1 file changed, 80 deletions(-)
delete mode 100644 Plugins/Flow.Launcher.Plugin.Program/Programs/AppxPackageHelper.cs
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/AppxPackageHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/AppxPackageHelper.cs
deleted file mode 100644
index 62416609e..000000000
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/AppxPackageHelper.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.ComTypes;
-
-namespace Flow.Launcher.Plugin.Program.Programs
-{
- public class AppxPackageHelper
- {
- // This function returns a list of attributes of applications
- public static List GetAppsFromManifest(IStream stream)
- {
- IAppxFactory appxFactory = (IAppxFactory)new AppxFactory();
- List apps = new List();
- var reader = appxFactory.CreateManifestReader(stream);
- var manifestApps = reader.GetApplications();
- while (manifestApps.GetHasCurrent())
- {
- string appListEntry;
- var manifestApp = manifestApps.GetCurrent();
- manifestApp.GetStringValue("AppListEntry", out appListEntry);
- if (appListEntry != "none")
- {
- apps.Add(manifestApp);
- }
- manifestApps.MoveNext();
- }
- return apps;
- }
-
- // Reference : https://stackoverflow.com/questions/32122679/getting-icon-of-modern-windows-app-from-a-desktop-application
- [Guid("5842a140-ff9f-4166-8f5c-62f5b7b0c781"), ComImport]
- public class AppxFactory
- {
- }
-
- [Guid("BEB94909-E451-438B-B5A7-D79E767B75D8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface IAppxFactory
- {
- void _VtblGap0_2(); // skip 2 methods
- IAppxManifestReader CreateManifestReader(IStream inputStream);
- }
-
- [Guid("4E1BD148-55A0-4480-A3D1-15544710637C"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface IAppxManifestReader
- {
- void _VtblGap0_1(); // skip 1 method
- IAppxManifestProperties GetProperties();
- void _VtblGap1_5(); // skip 5 methods
- IAppxManifestApplicationsEnumerator GetApplications();
- }
-
- [Guid("9EB8A55A-F04B-4D0D-808D-686185D4847A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface IAppxManifestApplicationsEnumerator
- {
- IAppxManifestApplication GetCurrent();
- bool GetHasCurrent();
- bool MoveNext();
- }
-
- [Guid("5DA89BF4-3773-46BE-B650-7E744863B7E8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface IAppxManifestApplication
- {
- [PreserveSig]
- int GetStringValue([MarshalAs(UnmanagedType.LPWStr)] string name, [MarshalAs(UnmanagedType.LPWStr)] out string value);
-
- [PreserveSig]
- int GetAppUserModelId([MarshalAs(UnmanagedType.LPWStr)] out string value);
- }
-
- [Guid("03FAF64D-F26F-4B2C-AAF7-8FE7789B8BCA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface IAppxManifestProperties
- {
- [PreserveSig]
- int GetBoolValue([MarshalAs(UnmanagedType.LPWStr)]string name, out bool value);
- [PreserveSig]
- int GetStringValue([MarshalAs(UnmanagedType.LPWStr)] string name, [MarshalAs(UnmanagedType.LPWStr)] out string value);
- }
- }
-}
From 713c586b9f382dd0a34551270d8ab93b5220ec6e Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 14:40:50 +0800
Subject: [PATCH 28/36] Fix IDE0005
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 795588aa6..28a368948 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -5,13 +5,11 @@ using System.IO;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
-using System.Windows.Media;
using System.Windows.Media.Imaging;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Plugin.Program.Logger;
-using Rect = System.Windows.Rect;
using Flow.Launcher.Plugin.SharedModels;
using System.Threading.Channels;
using System.Xml;
From a2d57c14bf18739b3ecbe8f383fde70279cc33c8 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 17:49:36 +0800
Subject: [PATCH 29/36] Fix xpath issue
---
.../Programs/UWP.cs | 25 ++++++++-----------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 28a368948..4964550d7 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -75,25 +75,26 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
- namespaceManager.AddNamespace("", "http://schemas.microsoft.com/appx/manifest/foundation/windows10");
+ namespaceManager.AddNamespace("d", "http://schemas.microsoft.com/appx/manifest/foundation/windows10"); // still need a name
namespaceManager.AddNamespace("rescap", "http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities");
namespaceManager.AddNamespace("uap10", "http://schemas.microsoft.com/appx/manifest/uap/windows10/10");
- var allowElevationNode = xmlRoot.SelectSingleNode("//*[name()='rescap:Capability' and @Name='allowElevation']", namespaceManager);
+ var allowElevationNode = xmlRoot.SelectSingleNode("//rescap:Capability[@Name='allowElevation']", namespaceManager);
bool packageCanElevate = allowElevationNode != null;
- var appsNode = xmlRoot.SelectSingleNode("//*[name()='Applications']", namespaceManager);
+ var appsNode = xmlRoot.SelectSingleNode("d:Applications", namespaceManager);
foreach (var app in Apps)
{
// According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package
// and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
var id = app.UserModelId.Split('!')[1];
- var appNode = appsNode?.SelectSingleNode($"//*[name()='Application' and @Id='{id}']", namespaceManager);
+ var appNode = appsNode?.SelectSingleNode($"d:Application[@Id='{id}']", namespaceManager);
if (appNode != null)
{
- app.CanRunElevated = packageCanElevate || Application.IfAppCanRunElevated(appNode, namespaceManager);
+ app.CanRunElevated = packageCanElevate || Application.IfAppCanRunElevated(appNode);
- var visualElement = appNode.SelectSingleNode($"//*[name()='uap:VisualElements']", namespaceManager);
+ // local name to fit all versions
+ var visualElement = appNode.SelectSingleNode($"*[local-name()='VisualElements']", namespaceManager);
var logoUri = visualElement?.Attributes[logoName]?.Value;
app.LogoPath = app.LogoPathFromUri(logoUri, (32, 32));
var previewUri = visualElement?.Attributes[bigLogoName]?.Value;
@@ -131,8 +132,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
}
}
- /// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx
- private PackageVersion GetPackageVersionFromManifest(XmlElement xmlRoot)
+ private PackageVersion GetPackageVersionFromManifest(XmlNode xmlRoot)
{
if (xmlRoot != null)
{
@@ -483,16 +483,13 @@ namespace Flow.Launcher.Plugin.Program.Programs
Main.StartProcess(Process.Start, info);
}
- internal static bool IfAppCanRunElevated(XmlNode appNode, XmlNamespaceManager namespaceManager)
+ internal static bool IfAppCanRunElevated(XmlNode appNode)
{
// According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package
// and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
- var entryPointNode = appNode.SelectSingleNode($"//*[local-name()='Application' and @EntryPoint]", namespaceManager);
- var trustLevelNode = appNode.SelectSingleNode($"//*[local-name()='Application' and @uap10:TrustLevel]", namespaceManager);
-
- return entryPointNode?.Attributes["EntryPoint"]?.Value == "Windows.FullTrustApplication" ||
- trustLevelNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL";
+ return appNode?.Attributes["EntryPoint"]?.Value == "Windows.FullTrustApplication" ||
+ appNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL";
}
internal string LogoPathFromUri(string uri, (int, int) desiredSize)
From 416fcd1881682bfe3efd7f3d91bd0e39abd66f0d Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 17:50:49 +0800
Subject: [PATCH 30/36] set desired size to 64x64
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 4964550d7..180e8aea1 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -96,7 +96,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
// local name to fit all versions
var visualElement = appNode.SelectSingleNode($"*[local-name()='VisualElements']", namespaceManager);
var logoUri = visualElement?.Attributes[logoName]?.Value;
- app.LogoPath = app.LogoPathFromUri(logoUri, (32, 32));
+ app.LogoPath = app.LogoPathFromUri(logoUri, (64, 64));
var previewUri = visualElement?.Attributes[bigLogoName]?.Value;
app.PreviewImagePath = app.LogoPathFromUri(previewUri, (128, 128));
}
From 422307d507d8c763071ba72cb425b8755f3441fa Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 17:56:56 +0800
Subject: [PATCH 31/36] formatting
---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 180e8aea1..8ea5d0c9a 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -59,7 +59,6 @@ namespace Flow.Launcher.Plugin.Program.Programs
try
{
- // From powertoys run
var xmlDoc = GetManifestXml();
if (xmlDoc == null)
{
From 592b838f3eafa723f0d888d52ac2b3e578cabfa0 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 18:13:55 +0800
Subject: [PATCH 32/36] Fix hard-coded translation
---
Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml | 2 ++
Plugins/Flow.Launcher.Plugin.Program/Main.cs | 7 ++++---
Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 2 +-
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
index 654322805..700c37046 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml
@@ -81,7 +81,9 @@
Success
+ Error
Successfully disabled this program from displaying in your query
This app is not intended to be run as administrator
+ Unable to run {0}
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
index feeb8e78a..c94c1dca2 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
+using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin.Program.Programs;
@@ -225,9 +226,9 @@ namespace Flow.Launcher.Plugin.Program
}
catch (Exception)
{
- var name = "Plugin: Program";
- var message = $"Unable to start: {info.FileName}";
- Context.API.ShowMsg(name, message, string.Empty);
+ var title = Context.API.GetTranslation("flowlauncher_plugin_program_disable_dlgtitle_error");
+ var message = string.Format(Context.API.GetTranslation("flowlauncher_plugin_program_run_failed"), info.FileName);
+ Context.API.ShowMsg(title, string.Format(message, info.FileName), string.Empty);
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
index 8ea5d0c9a..627502ea1 100644
--- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
+++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
@@ -421,7 +421,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
_ = Task.Run(() => Launch(shouldRunElevated)).ConfigureAwait(false);
if (elevated && !shouldRunElevated)
{
- var title = "Plugin: Program";
+ var title = api.GetTranslation("flowlauncher_plugin_program_disable_dlgtitle_error");
var message = api.GetTranslation("flowlauncher_plugin_program_run_as_administrator_not_supported_message");
api.ShowMsg(title, message, string.Empty);
}
From aeb72d26047c799c8f193711cee160e196d5f9e6 Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 19:26:29 +0800
Subject: [PATCH 33/36] Separate image loading logic
1. Separate image loading logic
2. Make IconDelegate async while calling to avoid blocking UI thread
---
Flow.Launcher/ViewModel/ResultViewModel.cs | 47 ++++++++++++----------
1 file changed, 25 insertions(+), 22 deletions(-)
diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs
index a8bb052b5..50b9aca21 100644
--- a/Flow.Launcher/ViewModel/ResultViewModel.cs
+++ b/Flow.Launcher/ViewModel/ResultViewModel.cs
@@ -173,50 +173,53 @@ namespace Flow.Launcher.ViewModel
public GlyphInfo Glyph { get; set; }
- private async Task LoadImageAsync()
+ private async Task LoadImageInternalAsync(string imagePath, Result.IconDelegate icon, bool loadFullImage)
{
- var imagePath = Result.IcoPath;
- if (string.IsNullOrEmpty(imagePath) && Result.Icon != null)
+ if (string.IsNullOrEmpty(imagePath) && icon != null)
{
try
{
- image = Result.Icon();
- return;
+ var image = await Task.Run(() => icon()).ConfigureAwait(false);
+ return image;
}
catch (Exception e)
{
Log.Exception(
- $"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>",
+ $"|ResultViewModel.LoadImageInternalAsync|IcoPath is empty and exception when calling IconDelegate for result <{Result.Title}> of plugin <{Result.PluginDirectory}>",
e);
}
}
- var loadFullImage = (Path.GetExtension(imagePath) ?? "").Equals(".url", StringComparison.OrdinalIgnoreCase);
-
- if (ImageLoader.CacheContainImage(imagePath))
- {
- // will get here either when icoPath has value\icon delegate is null\when had exception in delegate
- image = await ImageLoader.LoadAsync(imagePath, loadFullImage).ConfigureAwait(false);
- return;
- }
-
- // We need to modify the property not field here to trigger the OnPropertyChanged event
- Image = await ImageLoader.LoadAsync(imagePath, loadFullImage).ConfigureAwait(false);
+ return await ImageLoader.LoadAsync(imagePath, loadFullImage).ConfigureAwait(false);
}
+ private async Task LoadImageAsync()
+ {
+ var imagePath = Result.IcoPath;
+ var iconDelegate = Result.Icon;
+ if (ImageLoader.CacheContainImage(imagePath, false))
+ {
+ image = await LoadImageInternalAsync(imagePath, iconDelegate, false).ConfigureAwait(false);
+ }
+ else
+ {
+ // We need to modify the property not field here to trigger the OnPropertyChanged event
+ Image = await LoadImageInternalAsync(imagePath, iconDelegate, false).ConfigureAwait(false);
+ }
+ }
private async Task LoadPreviewImageAsync()
{
var imagePath = Result.PreviewImage ?? Result.IcoPath;
- if (imagePath == null && Result.Icon != null)
+ var iconDelegate = Result.Icon;
+ if (ImageLoader.CacheContainImage(imagePath, true))
{
- // For UWP programs from program plugin
- // TODO: Consider https://github.com/Flow-Launcher/Flow.Launcher/pull/1492#issuecomment-1304829947
- PreviewImage = Result.Icon();
+ previewImage = await LoadImageInternalAsync(imagePath, iconDelegate, true).ConfigureAwait(false);
}
else
{
- PreviewImage = await ImageLoader.LoadAsync(imagePath, true).ConfigureAwait(false);
+ // We need to modify the property not field here to trigger the OnPropertyChanged event
+ PreviewImage = await LoadImageInternalAsync(imagePath, iconDelegate, true).ConfigureAwait(false);
}
}
From 19d29e82fe1aabb7f5f57aa93826f9cfc6b9ca1f Mon Sep 17 00:00:00 2001
From: Vic <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Tue, 29 Nov 2022 19:32:55 +0800
Subject: [PATCH 34/36] update description
---
Flow.Launcher.Plugin/Result.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs
index 8f503131c..91dcb3336 100644
--- a/Flow.Launcher.Plugin/Result.cs
+++ b/Flow.Launcher.Plugin/Result.cs
@@ -241,7 +241,7 @@ namespace Flow.Launcher.Plugin
public string ProgressBarColor { get; set; } = "#26a0da";
///
- /// Suggests a result's file extension should use full width of the default preview panel.
+ /// Suggests the preview image of result should use full width of the default preview panel by result's file extension.
///
/// File extension. Dot included.
public static bool ShouldUseBigThumbnail(string extension)
From 730b353de2c72f1574ff8246989291d5fa9dde52 Mon Sep 17 00:00:00 2001
From: DB p
Date: Wed, 30 Nov 2022 16:22:23 +0900
Subject: [PATCH 35/36] Add Focusing (plugin/plugin store) when changed tab
---
Flow.Launcher/SettingWindow.xaml | 2 ++
Flow.Launcher/SettingWindow.xaml.cs | 10 ++++++++++
2 files changed, 12 insertions(+)
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index b1cfe790d..8d702fcf5 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -994,6 +994,7 @@
TextAlignment="Left" />
Date: Wed, 30 Nov 2022 16:42:12 +0800
Subject: [PATCH 36/36] Delete ProgramTest.cs
---
Flow.Launcher.Test/Plugins/ProgramTest.cs | 30 -----------------------
1 file changed, 30 deletions(-)
delete mode 100644 Flow.Launcher.Test/Plugins/ProgramTest.cs
diff --git a/Flow.Launcher.Test/Plugins/ProgramTest.cs b/Flow.Launcher.Test/Plugins/ProgramTest.cs
deleted file mode 100644
index 10818ec49..000000000
--- a/Flow.Launcher.Test/Plugins/ProgramTest.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using Flow.Launcher.Plugin.Program.Programs;
-using NUnit.Framework;
-using System;
-using Windows.ApplicationModel;
-
-namespace Flow.Launcher.Test.Plugins
-{
- [TestFixture]
- public class ProgramTest
- {
- //[TestCase("Microsoft.WindowsCamera", "ms-resource:LensSDK/Resources/AppTitle", "ms-resource://Microsoft.WindowsCamera/LensSDK/Resources/AppTitle")]
- //[TestCase("microsoft.windowscommunicationsapps", "ms-resource://microsoft.windowscommunicationsapps/hxoutlookintl/AppManifest_MailDesktop_DisplayName",
- // "ms-resource://microsoft.windowscommunicationsapps/hxoutlookintl/AppManifest_MailDesktop_DisplayName")]
- //[TestCase("windows.immersivecontrolpanel", "ms-resource:DisplayName", "ms-resource://windows.immersivecontrolpanel/Resources/DisplayName")]
- //[TestCase("Microsoft.MSPaint", "ms-resource:AppName", "ms-resource://Microsoft.MSPaint/Resources/AppName")]
- //public void WhenGivenPriReferenceValueShouldReturnCorrectFormat(string packageName, string rawPriReferenceValue, string expectedFormat)
- //{
- // // Arrange
- // var app = new UWP.Application();
-
- // // Act
- // var result = UWP.Application.FormattedPriReferenceValue(packageName, rawPriReferenceValue);
-
- // // Assert
- // Assert.IsTrue(result == expectedFormat,
- // $"Expected Pri reference format: {expectedFormat}{Environment.NewLine} " +
- // $"Actual: {result}{Environment.NewLine}");
- //}
- }
-}