C# 以编程方式获取已安装的应用程序可执行文件列表(Windows10,C)
我想获得Windows 10上已安装和可执行的应用程序列表,即用户可以启动UWP和非UWP的应用程序的可执行文件。对于UWP应用程序,我想获取其AppUserModelId。对于非UWP应用程序,我希望获取可执行文件的文件位置 到目前为止,我已经尝试: 1遍历注册表,并遍历。但是,此方法会遍历所有已安装的应用程序,返回的列表将包括microsoft asp.net core 2.1.8 shared framework x64之类的内容,我希望消除这些内容 2我发现我可以通过特殊的方式访问我想要的内容,方法是在explorer窗口或Run中键入shell:Appsfolder。到目前为止,我能够访问这个文件夹,遍历这些项目并列出文件名。但我不知道如何收集有关UWP应用程序的AppUserModelId和WPF应用程序的filepath的信息 我用于枚举Appsfolder文件的相关代码:C# 以编程方式获取已安装的应用程序可执行文件列表(Windows10,C),c#,.net,windows,winapi,known-folders,C#,.net,Windows,Winapi,Known Folders,我想获得Windows 10上已安装和可执行的应用程序列表,即用户可以启动UWP和非UWP的应用程序的可执行文件。对于UWP应用程序,我想获取其AppUserModelId。对于非UWP应用程序,我希望获取可执行文件的文件位置 到目前为止,我已经尝试: 1遍历注册表,并遍历。但是,此方法会遍历所有已安装的应用程序,返回的列表将包括microsoft asp.net core 2.1.8 shared framework x64之类的内容,我希望消除这些内容 2我发现我可以通过特殊的方式访问我想要
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]);
}
该接口提供了获取AppUserModelID的方法,但我不确定如何通过IShellFolder接口访问该接口。另外,如何将AppsFolder虚拟文件夹中的实际文件位置获取到实际exe的文件路径?通过在Windows PowerShell命令提示符下运行以下命令,可以获取为当前用户安装的所有应用程序的应用程序用户模型ID AUMID:
get-StartApps
$installedapps = get-AppxPackage
$aumidList = @()
foreach ($app in $installedapps)
{
foreach ($id in (Get-AppxPackageManifest $app).package.applications.application.id)
{
$aumidList += $app.packagefamilyname + "!" + $id
}
}
$aumidList
要获取为其他用户安装的用于Windows应用商店应用的AUMIDs,请在Windows PowerShell命令提示符中运行以下命令:
get-StartApps
$installedapps = get-AppxPackage
$aumidList = @()
foreach ($app in $installedapps)
{
foreach ($id in (Get-AppxPackageManifest $app).package.applications.application.id)
{
$aumidList += $app.packagefamilyname + "!" + $id
}
}
$aumidList
您可以参考更多详细信息
您需要做的是从C调用相关的注册表API或Powershell命令。您可以通过在Windows Powershell命令提示符下运行以下命令,获取为当前用户安装的所有应用程序的应用程序用户模型ID AUMID:
get-StartApps
$installedapps = get-AppxPackage
$aumidList = @()
foreach ($app in $installedapps)
{
foreach ($id in (Get-AppxPackageManifest $app).package.applications.application.id)
{
$aumidList += $app.packagefamilyname + "!" + $id
}
}
$aumidList
要获取为其他用户安装的用于Windows应用商店应用的AUMIDs,请在Windows PowerShell命令提示符中运行以下命令:
get-StartApps
$installedapps = get-AppxPackage
$aumidList = @()
foreach ($app in $installedapps)
{
foreach ($id in (Get-AppxPackageManifest $app).package.applications.application.id)
{
$aumidList += $app.packagefamilyname + "!" + $id
}
}
$aumidList
您可以参考更多详细信息
您需要做的是从C中调用相关的注册表API或Powershell命令。您将获得带有IShellFolder2.GetDetailsEx和PKEY_AppUserModel_ID的AppUserModelId 在Windows10上用C语言测试
[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);
}
您可以使用IShellFolder2.GetDetailsEx和PKEY_AppUserModel_ID获取AppUserModelId 在Windows10上用C语言测试
[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);
}
查看答案
简而言之,将nuget包添加到项目中,然后使用以下代码:
// GUID taken from https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid
var FODLERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FODLERID_AppsFolder);
foreach (var app in (IKnownFolder)appsFolder)
{
// The friendly app name
string name = app.Name;
// The ParsingName property is the AppUserModelID
string appUserModelID = app.ParsingName; // or app.Properties.System.AppUserModel.ID
// You can even get the Jumbo icon in one shot
ImageSource icon = app.Thumbnail.ExtraLargeBitmapSource;
}
要启动应用程序,请执行以下操作:
System.Diagnostics.Process.Start("explorer.exe", @" shell:appsFolder\" + appUserModelID);
适用于普通应用程序和商店应用程序。查看答案
简而言之,将nuget包添加到项目中,然后使用以下代码:
// GUID taken from https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid
var FODLERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FODLERID_AppsFolder);
foreach (var app in (IKnownFolder)appsFolder)
{
// The friendly app name
string name = app.Name;
// The ParsingName property is the AppUserModelID
string appUserModelID = app.ParsingName; // or app.Properties.System.AppUserModel.ID
// You can even get the Jumbo icon in one shot
ImageSource icon = app.Thumbnail.ExtraLargeBitmapSource;
}
要启动应用程序,请执行以下操作:
System.Diagnostics.Process.Start("explorer.exe", @" shell:appsFolder\" + appUserModelID);
适用于常规应用程序和应用商店应用程序。我有一个解决方案,您无需添加任何额外的dll或命名空间即可从Windows应用商店获取应用程序名称:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = "powershell.exe";
p.StartInfo.Arguments = @"Get-AppxPackage | select name";
p.Start();
output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
输出中包含的所有应用程序列表 我有一个解决方案,您无需添加任何额外的dll或命名空间即可从Windows应用商店获取应用程序名称:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = "powershell.exe";
p.StartInfo.Arguments = @"Get-AppxPackage | select name";
p.Start();
output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
输出中包含的所有应用程序列表 您所描述的仅适用于在操作系统中注册的应用程序,但这不是一项要求。应用程序可以安装并可执行,而无需向操作系统注册。如果你真的想找到所有的东西,你可能最终不得不枚举整个文件系统。对,我理解。在这一点上,我只想找到那些在操作系统上注册的。你能推荐一种更好的方法吗?你所描述的方法只适用于在操作系统上注册的应用程序,但这不是一个要求。应用程序可以安装并可执行,而无需向操作系统注册。如果你真的想找到所有的东西,你可能最终不得不枚举整个文件系统。对,我理解。在这一点上,我只想找到那些在操作系统上注册的。你能推荐一种更好的方法吗?看起来是一种方法,我会试试。winapi不可能吗?看起来是一种方法,我会试试。winapi不可能吗?