如何查询已安装的“打包 COM”扩展点

Posted

技术标签:

【中文标题】如何查询已安装的“打包 COM”扩展点【英文标题】:How to query for installed "packaged COM" extension points 【发布时间】:2021-12-01 23:39:26 【问题描述】:

我正在开发一个基于插件的应用程序,该应用程序当前正在扫描 Windows 注册表以查找公开某些“已实施类别”条目的兼容 COM 服务器。这适用于通过 MSI 安装程序安装的“常规”COM 服务器。

但是,我现在面临通过 MSIX 安装程序安装的 COM 服务器的问题,这些安装程序通过“打包的 COM”目录公开 COM 扩展点,如 https://blogs.windows.com/windowsdeveloper/2017/04/13/com-server-ole-document-support-desktop-bridge/ 中所述。这些 COM 服务器仍然可以通过 CoCreateInstance 实例化,但 RegOpenKey/RegEnumKey 搜索无法检测到它们的存在。

我不确定如何解决这个问题。最好的结果是某种 Windows API,用于查询已安装 COM 服务器的“打包 COM”目录,除了注册表搜索之外,我还可以运行它。但是,我不知道这是否存在?我也愿意接受其他建议,只要它们仍然允许我的应用程序动态检测新的基于 COM 的插件的存在。

【问题讨论】:

您是否正在寻找此信息:***.com/questions/50802129/…(软件包列表在“%ProgramFiles%\WindowsApps”中) 也可以使用WinRT API PackageManager.FindPackages:docs.microsoft.com/en-us/uwp/api/… 感谢@SimonMourier 提供的非常有用的线索。我现在已经成功地检索了我计算机上安装的所有软件包的Windows.ApplicationModel.Package 对象列表。但是,我还需要为这些包检索相应的 COM 扩展。 XML 架构记录在 docs.microsoft.com/nb-no/uwp/schemas/appxpackage/… 上,但到目前为止我还没有找到相应的 API。 您不需要 API 来记录模式。 也许您可以在 MSIX 社区 (techcommunity.microsoft.com/t5/MSIX/ct-p/MSIX) 上发布此内容,希望 Microsoft 的某个人能提供帮助。我尝试在网上四处询问,但到目前为止没有运气。我们的团队也不知道任何 API(我跳过了解析清单的建议,因为它不是最优雅的解决方案) 【参考方案1】:

用示例代码回答我自己,以查询已安装的 COM 服务器的“打包 COM”目录。基于@SimonMourier 的建议。

using System.Collections.Generic;
using System.IO;

/** Use Target Framework Moniker as described in https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/desktop-to-uwp-enhance */
class PackagedComScan 
    static void Main(string[] args) 
        var packageManager = new Windows.Management.Deployment.PackageManager();
        // this call require the "packageQuery" capability if called from a UWP app (add <rescap:Capability Name="packageQuery" /> to the appxmanifest)
        IEnumerable<Windows.ApplicationModel.Package> my_packages = packageManager.FindPackagesForUser("");

        foreach (var package in my_packages) 
            try 
                ParseAppxManifest(package.InstalledLocation.Path + @"\AppxManifest.xml");
             catch (FileNotFoundException) 
                // Installed package missing from disk. Can happen after deploying UWP builds from Visual Studio.
            
        
    

    static void ParseAppxManifest(string manifest_path) 
        var doc = new System.Xml.XmlDocument();
        using (var fs = new FileStream(manifest_path, FileMode.Open, FileAccess.Read, FileShare.Read))
            doc.Load(fs);

        var nsmgr = new System.Xml.XmlNamespaceManager(doc.NameTable);
        nsmgr.AddNamespace("a", "http://schemas.microsoft.com/appx/manifest/foundation/windows10"); // default namespace
        nsmgr.AddNamespace("com", "http://schemas.microsoft.com/appx/manifest/com/windows10");

        // detect exported COM servers
        var nodes = doc.SelectNodes("/a:Package/a:Applications/a:Application/a:Extensions/com:Extension/com:ComServer/com:ExeServer/com:Class/@Id", nsmgr);
        foreach (System.Xml.XmlNode node in nodes)
            System.Console.WriteLine("Exported COM CLSID: 0", node.Value);
    

这确实有点临时,因为它依赖于解析 AppxManifest.xml 文件。不过,它似乎完成了工作。请注意,在沙盒化 AppContainer 进程中运行的 UWP 应用程序似乎只有对 AppxManifest.xml 文件中的 一些 文件的读取权限,而不是全部。因此,该代码仅适用于“常规”Win32 或 .Net 进程

【讨论】:

以上是关于如何查询已安装的“打包 COM”扩展点的主要内容,如果未能解决你的问题,请参考以下文章

Dubbo中的线程池——自适应扩展点应用之一

Eclipse 插件开发,怎么调用popupMenus扩展点的右键菜单

玩转Asp.net MVC 的八个扩展点

玩转Asp.net MVC 的八个扩展点(上)

vmware中给centos扩展磁盘大小

如何扩展多边形直到其中一个边界到达一个点