从Plex插件访问WMP的COMException(使用Python for.NET)

2024-05-17 11:36:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标

我正在尝试为Plex Media Server (PMS)创建一个插件,它将与WMP(Windows Media Player)接口,以获取有关Windows Media库项的元数据。在

设置

  • PMS使用python2.7作为其主要脚本宿主。Plex插件是 用Python编写,尽管它们在沙盒中运行。不幸的是,这个沙盒上有一些沙盒功能。在
  • 我决定使用pythonfor.NET来访问windowsdk来与WMPLib接口。 .NET的Python(http://pythonnet.github.io/)是一种Python 用于从中访问.NET程序集功能的库 Python运行时。在
  • 我创建了一个.NET程序集来访问WMPLib,它 是Windows SDK的一部分,旨在以编程方式访问 WMP的功能。WMPLib基本上是 .NET目标wmp.dll. 在

有什么用?在

从Python到基于COM的WMP访问的整个链都在工作。如果启动Plex Media Server(Python2.7的一个版本)附带的嵌入式Plex脚本主机,我就可以很容易地从WMP访问数据。这意味着链中的以下环节都在工作:

  • Python正在为.NET加载Python
  • pythonfor.NET正在加载我的.NET程序集
  • 我的.NET程序集正在加载WMPLib(互操作.WMPLib.dll,用于COM互操作的.NET程序集)
  • WMPLib成功开放和利用的wmp.dll(从C:\Windows\System32访问)

什么不管用?在

激活这个链的COM互操作部分是在沙盒Plex插件中工作的而不是。同样,这个插件是用标准Python编写的,但是一旦沙盒代码运行,Python执行环境就有了微妙的不同。在插件中运行WMP访问代码时,出现以下异常:

COMException: Exception from HRESULT: 0xC00D1327
   at WMPLib.IWMPPlayer4.get_mediaCollection()
  • 在这个场景中,我知道pythonfor.NET正在工作,因为此时我已经从我的.NET程序集中加载并访问了其他东西。在
  • C:\Windows\System32位于PATH变量的前面。我假设COM DLL应该通过PATH环境变量来定位(This似乎是这么说的),但我并不完全确定这一点。在这种独特的场景(Python访问.NET访问COM)中如何定位COM程序集是我最大的未知数之一。在

问题

  1. Plex插件沙盒是如何改变Python执行环境的,以至于访问COM程序集不再工作?在
  2. 在这种情况下,环境应该如何定位和访问COM程序集?在
  3. 是否需要丛沙盒可能已锁定的特定权限?在

也许我至少应该赢得某种奖项,因为我提出了一个问题,这个问题以一种独特的令人困惑的方式交叉了这么多不同的技术。。。在

编辑1

多亏了@Paulo下面的建议,我完全排除了任何与.NET相关的问题。我现在正在通过comtypesPython库与WMPLib进行所有的互操作。现在我得到以下错误:

^{pr2}$

尽管-1072884953是一个不同的错误代码,但是稍微深入一下就会发现这个错误与(可能等价于?)有关我在.NET互操作中遇到的相同错误(this post使其看起来如此)。在

所以现在我要面对的事实是:

  1. wmp.dll在所有情况下都在加载(这是@Paulo帮助我计算的) 在下面)。在
  2. 当访问WMP的代码在Plex沙盒环境之外运行时,可以从WMP访问库项。在
  3. 当访问WMP的代码在Plex沙盒环境中运行时,无法从WMP访问库项。在
  4. 我得到的错误代码(是否来自.NET或者基于Python的COM互操作是NS_E_CURL_INVALIDPATH: The URL contains a path that is not valid.在大多数情况下,这个错误似乎与尝试回放有关。在
  5. 这很奇怪,因为我从来没有在我的场景中播放过。。。我只是想打电话给wmp.mediaCollection

因此,Plex沙箱在这个场景中确实是关键。有什么进一步的想法吗?在

编辑2

至少,这是失败所需的代码:

from comtypes.client import CreateObject

wmp = CreateObject("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")
collection = wmp.mediaCollection

collection = wmp.mediaCollection就是发生错误的地方。在

因此,实际上没有传递任何可能导致失败的参数。重申一下,这段代码在一般的python2.7上下文中运行良好。它只在Plex插件沙盒中失败。我不知道如何获得关于Plex沙盒如何改变执行环境的详细信息。我想我的答案就在那个方向。在


Tags: 代码程序com沙盒插件net环境windows
1条回答
网友
1楼 · 发布于 2024-05-17 11:36:05

让我直说,如果我错了,请纠正我:

  • 您有一个正在运行的Python2.7 Plex Media Server实例

  • 您正在使用Python for.NET库将.NET加载到您的进程中

  • 您正在.NET中加载WMPLib,一个导入的COM互操作程序集,以便通过Python for.NET使用Windows Media Player库

我们来澄清一下:

  • ^{} is ^{}

    The URL contains a path that is not valid.

    这似乎是一个合法的对象错误,而不是COM错误。

  • DLL search order与此几乎没有关系,因为wmp.dll在InProcServer32注册表项下为每个提供的类注册一个完整路径,这才是最重要的。在

    事实上,正如您所说的,如果您已经达到了这一点,那么加载.NET程序集或COM找不到DLL显然不是问题。

现在,对于这些问题:

  1. 由于错误似乎是合法的,您可能无法访问媒体集合(Internet区域?),或WMP未正确注册/安装,或某些编解码器丢失或未正确注册/安装等

    你在全脂奶粉里装什么?尝试一些基本的东西,比如本地.WAV、.MP3、.AVI和.MPG文件,然后尝试更高级的格式,例如MPEG4编码的视频,或者可能是远程位置。

  2. 你应该尝试一种更直接的方法,尽管我不能保证哪个更好:win32com (part of pywin32)还是{a5}。在

    很久以前我还没看过它们了,所以要稍微考虑一下:对于comtypes,你可以像普通的Python对象一样使用COM对象和属性和方法,而win32com似乎更倾向于通过运行时名称分派来做事情。在

    至少你会用一些你必须忍受的东西(Python)来代替那些根本不需要它(WMP)的东西来加载.NET。

  3. 我不知道沙盒是关于什么的,但我猜这是一个只支持Python的沙盒,而不是限制操作系统使用的东西。


提供路径\a\文件.mp4)其中需要URL(file:///C:/path/to/文件.mp4),反之亦然?我想您必须显示失败的代码以及提供的值。在

相关问题 更多 >