diff --git a/Plugins/Flow.Launcher.Plugin.Program/AppxPackagingTlb.dll b/Plugins/Flow.Launcher.Plugin.Program/AppxPackagingTlb.dll deleted file mode 100644 index 183cfc085c3..00000000000 Binary files a/Plugins/Flow.Launcher.Plugin.Program/AppxPackagingTlb.dll and /dev/null differ diff --git a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj index 5de32e83248..a2d7b7fef00 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj +++ b/Plugins/Flow.Launcher.Plugin.Program/Flow.Launcher.Plugin.Program.csproj @@ -40,13 +40,6 @@ PreserveNewest - - - - .\AppxPackagingTlb.dll - True - - diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/AppxPackageHelper.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/AppxPackageHelper.cs new file mode 100644 index 00000000000..e48f30757be --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/AppxPackageHelper.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using Windows.Storage; + +namespace Flow.Launcher.Plugin.Program.Programs +{ + public class AppxPackageHelper + { + // This function returns a list of attributes of applications + public List getAppsFromManifest(IStream stream) + { + List apps = new List(); + var appxFactory = new AppxFactory(); + var reader = ((IAppxFactory)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); + } + } +} diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index 209b8f92ce4..855a11c86fa 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -4,6 +4,7 @@ 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; @@ -12,10 +13,8 @@ using System.Xml.Linq; using Windows.ApplicationModel; using Windows.Management.Deployment; -using AppxPackaing; using Flow.Launcher.Infrastructure; using Flow.Launcher.Plugin.Program.Logger; -using IStream = AppxPackaing.IStream; using Rect = System.Windows.Rect; using Flow.Launcher.Plugin.SharedModels; @@ -51,33 +50,27 @@ public UWP(Package package) private void InitializeAppInfo() { + AppxPackageHelper _helper = new AppxPackageHelper(); var path = Path.Combine(Location, "AppxManifest.xml"); var namespaces = XmlNamespaces(path); InitPackageVersion(namespaces); - var appxFactory = new AppxFactory(); - IStream stream; const uint noAttribute = 0x80; const Stgm exclusiveRead = Stgm.Read | Stgm.ShareExclusive; - var hResult = SHCreateStreamOnFileEx(path, exclusiveRead, noAttribute, false, null, out stream); + var hResult = SHCreateStreamOnFileEx(path, exclusiveRead, noAttribute, false, null, out IStream stream); if (hResult == Hresult.Ok) { - var reader = appxFactory.CreateManifestReader(stream); - var manifestApps = reader.GetApplications(); var apps = new List(); - while (manifestApps.GetHasCurrent() != 0) + + List _apps = _helper.getAppsFromManifest(stream); + foreach(var _app in _apps) { - var manifestApp = manifestApps.GetCurrent(); - var appListEntry = manifestApp.GetStringValue("AppListEntry"); - if (appListEntry != "none") - { - var app = new Application(manifestApp, this); - apps.Add(app); - } - manifestApps.MoveNext(); + var app = new Application(_app, this); + apps.Add(app); } + Apps = apps.Where(a => a.AppListEntry != "none").ToArray(); } else @@ -253,6 +246,7 @@ public class Application : IProgram public string UserModelId { get; set; } public string BackgroundColor { get; set; } + public string EntryPoint { get; set; } public string Name => DisplayName; public string Location => Package.Location; @@ -350,14 +344,13 @@ public List ContextMenus(IPublicAPI api) private async void Launch(IPublicAPI api) { var appManager = new ApplicationActivationHelper.ApplicationActivationManager(); - uint unusedPid; const string noArgs = ""; const ApplicationActivationHelper.ActivateOptions noFlags = ApplicationActivationHelper.ActivateOptions.None; await Task.Run(() => { try { - appManager.ActivateApplication(UserModelId, noArgs, noFlags, out unusedPid); + appManager.ActivateApplication(UserModelId, noArgs, noFlags, out _); } catch (Exception) { @@ -368,13 +361,24 @@ await Task.Run(() => }); } - public Application(IAppxManifestApplication manifestApp, UWP package) + public Application(AppxPackageHelper.IAppxManifestApplication manifestApp, UWP package) { - UserModelId = manifestApp.GetAppUserModelId(); - UniqueIdentifier = manifestApp.GetAppUserModelId(); - DisplayName = manifestApp.GetStringValue("DisplayName"); - Description = manifestApp.GetStringValue("Description"); - BackgroundColor = manifestApp.GetStringValue("BackgroundColor"); + // 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; + Package = package; DisplayName = ResourceFromPri(package.FullName, package.Name, DisplayName); @@ -442,7 +446,7 @@ public string FormattedPriReferenceValue(string packageName, string rawPriRefere return $"{prefix}//{packageName}{key}"; } - internal string LogoUriFromManifest(IAppxManifestApplication app) + internal string LogoUriFromManifest(AppxPackageHelper.IAppxManifestApplication app) { var logoKeyFromVersion = new Dictionary { @@ -453,7 +457,7 @@ internal string LogoUriFromManifest(IAppxManifestApplication app) if (logoKeyFromVersion.ContainsKey(Package.Version)) { var key = logoKeyFromVersion[Package.Version]; - var logoUri = app.GetStringValue(key); + app.GetStringValue(key, out string logoUri); return logoUri; } else diff --git a/Plugins/Flow.Launcher.Plugin.Program/plugin.json b/Plugins/Flow.Launcher.Plugin.Program/plugin.json index 93e5079c2d5..d110124ff42 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Program/plugin.json @@ -4,7 +4,7 @@ "Name": "Program", "Description": "Search programs in Flow.Launcher", "Author": "qianlifeng", - "Version": "1.4.1", + "Version": "1.4.2", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.Program.dll",