mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #79 from Flow-Launcher/fix_loading_uwp
Fix UWP loading
This commit is contained in:
commit
7c3aac47cf
5 changed files with 113 additions and 34 deletions
Binary file not shown.
|
|
@ -40,13 +40,6 @@
|
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="AppxPackagingTlb">
|
||||
<HintPath>.\AppxPackagingTlb.dll</HintPath>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Languages\*.xaml">
|
||||
|
|
|
|||
|
|
@ -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<IAppxManifestApplication> getAppsFromManifest(IStream stream)
|
||||
{
|
||||
List<IAppxManifestApplication> apps = new List<IAppxManifestApplication>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ 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;
|
||||
|
|
@ -12,10 +13,8 @@ using System.Windows.Media.Imaging;
|
|||
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
|
||||
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<Application>();
|
||||
while (manifestApps.GetHasCurrent() != 0)
|
||||
|
||||
List<AppxPackageHelper.IAppxManifestApplication> _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 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
});
|
||||
}
|
||||
|
||||
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 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
return $"{prefix}//{packageName}{key}";
|
||||
}
|
||||
|
||||
internal string LogoUriFromManifest(IAppxManifestApplication app)
|
||||
internal string LogoUriFromManifest(AppxPackageHelper.IAppxManifestApplication app)
|
||||
{
|
||||
var logoKeyFromVersion = new Dictionary<PackageVersion, string>
|
||||
{
|
||||
|
|
@ -453,7 +457,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
if (logoKeyFromVersion.ContainsKey(Package.Version))
|
||||
{
|
||||
var key = logoKeyFromVersion[Package.Version];
|
||||
var logoUri = app.GetStringValue(key);
|
||||
app.GetStringValue(key, out string logoUri);
|
||||
return logoUri;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in a new issue