Я хочу получить список приложений, которые установлены и выполняются в Windows 10 - т.е. исполняемые файлы приложений, которые пользователь может запускать (UWP и не-UWP).Для приложений UWP я хочу получить его AppUserModelId.Для приложений, не относящихся к UWP, я хочу получить расположение файла исполняемого файла.
До сих пор я пытался: 1) Проходить через реестр и перебирать установленных приложений .Тем не менее, этот метод проходит через все установленные приложения, возвращенный список будет включать в себя такие вещи, как microsoft asp.net core 2.1.8 shared framework (x64)
, которые я хочу исключить.
2) Я обнаружил, что могу получить доступ к тому, что я хотел, через специальный Appsfolder
, набрав shell:Appsfolder
либо в окне проводника, либо в меню «Выполнить».До сих пор мне удавалось получить доступ к этой папке, перебирать элементы и перечислять имена файлов.Но я не уверен, как собирать информацию о AppUserModelId (для приложений UWP) и filepath (для приложений WPF).
Соответствующий код, который я использовал для перечисления файлов Appsfolder:
namespace AppsFolder
{
...
public static class AppsFolder
{
...
// GUID for shell:Appsfolder
public static readonly Guid KnownFolderID = new Guid("1e87508d-89c2-42f0-8a7e-645a0f50ca58");
public static IEnumerable<string> GetItemNames(ESHGDN gdn)
{
IShellFolder appsFolder = GetAppsFolder();
try
{
IntPtr enumIDListInterfacePointer;
appsFolder.EnumObjects(IntPtr.Zero,
ESHCONTF.SHCONTF_NONFOLDERS | ESHCONTF.SHCONTF_FOLDERS,
out enumIDListInterfacePointer);
using (var enumIDList = new
EnumIDListWrapper(enumIDListInterfacePointer))
{
var names = new List<string>();
foreach (var pidl in enumIDList)
{
STRRET name;
recycleBin.GetDisplayNameOf(
pidl.DangerousGetHandle(),
gdn,
out name);
names.Add(STRRETToString(ref name, pidl));
if (name.uType != (int)STRRETType.Offset)
Marshal.FreeCoTaskMem(name.data.pOleStr);
}
return names;
}
}
finally
{
Marshal.FinalReleaseComObject(recycleBin);
}
}
private static IShellFolder GetAppsFolder()
{
IShellFolder desktop;
NativeMethod.SHGetDesktopFolder(out desktop);
try
{
Guid shellFolderInterfaceId = typeof(IShellFolder).GUID;
IntPtr recycleBinShellFolderInterfacePointer;
desktop.BindToObject(
GetItemIDList().DangerousGetHandle(),
IntPtr.Zero,
ref shellFolderInterfaceId,
out recycleBinShellFolderInterfacePointer);
return (IShellFolder)Marshal.GetObjectForIUnknown(
recycleBinShellFolderInterfacePointer);
}
finally
{
Marshal.FinalReleaseComObject(desktop);
}
}
public static SafeCoTaskMemHandleZeroIsInvalid GetItemIDList()
{
SafeCoTaskMemHandleZeroIsInvalid pidl;
Guid guid = KnownFolderID;
NativeMethod.SHGetKnownFolderIDList(
ref guid, 0, IntPtr.Zero, out pidl);
return pidl;
}
}
}
Выполняется как:
string[] names = AppsFolder.GetItemNames(AppsFolder.ESHGDN.SHGDN_INFOLDER).ToArray();
for (int i=0; i<names.Length; i++)
{
Console.WriteLine(names[i]);
}
Интерфейс ILaunchSourceAppUserModelID
предоставляет метод для получения AppUserModelID, но я не уверен, как получить доступ к этому интерфейсу через мой интерфейс IShellFolder.Кроме того, как я могу получить фактическое местоположение файла в виртуальной папке AppsFolder к фактическому пути к файлу exe?