如何从C#桌面应用程序中检索Windows应用商店应用的图标?

问题描述:

在C#中,获取.exe文件的图标很容易。你只是做Icon.ExtractAssociatedIcon(path)和voilà。 但是,如果我想要获取图标的应用程序不是标准的.exe文件,而是这些新颖的Windows应用商店应用程序之一呢?如何从C#桌面应用程序中检索Windows应用商店应用的图标?

有没有办法让我的C#应用​​程序中的Windows应用商店应用程序的图标作为位图对象?

+0

那么,你想从第三方应用程序提取图像?你知道部署后应用程序的存储位置吗? – Konstantin

这个问题已经回答了关于超级用户一般方法: https://superuser.com/questions/478975/how-to-create-a-desktop-shortcut-to-a-windows-8-modern-ui-app

如果你想要做的在C# - 这一定程度上取决于你从哪里开始。你想为所有应用程序的特定应用程序或图标的图标?你知道应用程序,应用程序名称或应用程序ID的路径吗?

您可以使用PowerShell Get-AppxPackage命令获取应用程序的列表。

using (var runspace = RunspaceFactory.CreateRunspace(InitialSessionState.CreateDefault())) 
{ 
    runspace.Open(); 

    PowerShell powerShellCommand = PowerShell.Create(); 
    powerShellCommand.Runspace = runspace; 
    powerShellCommand.AddScript("Get-AppxPackage |?{!$_.IsFramework}"); 

    foreach (var result in powerShellCommand.Invoke()) 
    { 
     try 
     { 
      if (result.Properties.Match("Name").Count > 0 && 
       result.Properties.Match("InstallLocation").Count > 0) 
      { 
       var name = result.Properties["Name"].Value; 
       var installLocation = result.Properties["InstallLocation"].Value; 
       Console.WriteLine(installLocation.ToString()); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
     } 
    } 

    runspace.Close(); 
} 

上述的问题是,它返回了很多:我还没有得到它的工作,但要做到这一点从C#,你会安装​​NuGet包,然后运行这样的事情太过分了的不是真正的应用程序的组件包。我找不到找到应用显示名称的简单方法。您可以破解安装位置中找到的AppxManifest.xml文件,但对于任何本地化的应用程序,它的显示名称都会显示“ms-resource:ApplicationTitleWithBranding”,从应用程序外部提取它似乎很复杂。

要从注册表中获取应用程序列表,您可以使用Microsoft.Win32.Registry类从“HKEY_CLASSES_ROOT \ Extensions \ ContractId \ Windows.Protocol \ PackageId”中读取注册表,然后使用超级用户所描述的技术获取该图块图片。

在Windows存储UWP应用程序的情况下,您将拥有所谓“间接字符串”形式的应用程序图标路径。 例如对于Groove音乐:

@{Microsoft.ZuneMusic_10.18011.12711.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.ZuneMusic/Files/Assets/AppList.png}

为了从间接串SHLoadIndirectString Windows API函数正常路径都可以使用。

using System; 
using System.Runtime.InteropServices; 
using System.Text; 

class IndirectString 
{ 
    [DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)] 
    public static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved); 

    public string ExtractNormalPath(string indirectString) 
    { 
     StringBuilder outBuff = new StringBuilder(1024); 
     int result = SHLoadIndirectString(indirectString, outBuff, outBuff.Capacity, IntPtr.Zero); 

     return outBuff.ToString(); 
    } 
}