Программно получить список установленных исполняемых файлов приложения (Windows10, C #) - PullRequest
0 голосов
/ 23 мая 2019

Я хочу получить список приложений, которые установлены и выполняются в 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?

Ответы [ 2 ]

0 голосов
/ 11 июня 2019

Вы получаете AppUserModelId с IShellFolder2.GetDetailsEx и PKEY_AppUserModel_ID

(протестировано в C # на Windows 10)

[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct PROPERTYKEY
{
    private readonly Guid _fmtid;
    private readonly uint _pid;

    public PROPERTYKEY(Guid fmtid, uint pid)
    {
        _fmtid = fmtid;
        _pid = pid;
    }

    public static readonly PROPERTYKEY PKEY_AppUserModel_ID = new PROPERTYKEY(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 5);     
}
0 голосов
/ 23 мая 2019

Вы можете получить идентификатор модели приложения (AUMID) для всех приложений, установленных для текущего пользователя, выполнив следующую команду в командной строке Windows PowerShell:

get-StartApps

Чтобы получить AUMID для приложений Магазина Windows, установленных длядругой пользователь, введите в командной строке Windows PowerShell следующую команду:

$installedapps = get-AppxPackage

$aumidList = @()
foreach ($app in $installedapps)
{
    foreach ($id in (Get-AppxPackageManifest $app).package.applications.application.id)
    {
        $aumidList += $app.packagefamilyname + "!" + $id
    }
}

$aumidList

Более подробную информацию можно найти в разделе « Поиск идентификатора модели приложения установленного приложения ».

Что вам нужно сделать, это вызвать связанный API реестра или команду Powershell из C #.

...