私の目標
Windows メディア ライブラリ アイテムに関するメタデータを取得するために WMP (Windows Media Player) と 連携するPlex Media Server (PMS)用のプラグインを作成しようとしています。
セットアップ
- PMS は、主要なスクリプト ホストとして Python 2.7 を使用します。Plex プラグインは Python で記述されていますが、サンドボックス化された容量で動作します。残念ながら、このサンドボックス化された機能の境界が正確に何であるかについての残念なドキュメントはほとんどありません。
- 私は Python for .NET を使用して Windows SDK にアクセスし、WMPLib とやり取りすることにしました。Python for .NET ( http://pythonnet.github.io/ ) は、Python ランタイム内から .NET アセンブリの機能にアクセスするために使用される Python ライブラリです。
- WMPLib にアクセスするための .NET アセンブリを作成しました。これは、WMP の機能にプログラムでアクセスするように設計された Windows SDK の一部です。WMPLib は基本的に、wmp.dll をターゲットとする .NET の COM Interop ラッパーです。
何が機能していますか?
Python から COM ベースの WMP アクセスまでのチェーン全体が機能しています。Plex Media Server (Python 2.7 のバージョン) に付属する組み込みの Plex Script Host を起動すると、WMP からデータに簡単にアクセスできます。これは、チェーン内の次のリンクがすべて機能していることを意味します。
- PythonはPython for .NET をロードしています
- Python for .NETが.NET アセンブリをロードしています
- .NET アセンブリがWMPLib (Interop.WMPLib.dll、COM Interop 用の .NET アセンブリ) をロードしています
- WMPLibは正常に wmp.dll を開いて利用しています (C:\Windows\System32 からアクセス)
何が機能していないのですか?
このチェーンの COM Interop 部分をアクティブ化しても、サンドボックス化された Plex プラグイン内からは機能しません。繰り返しますが、このプラグインは標準の Python で記述されていますが、サンドボックス コードが実行されると、Python 実行環境が微妙に異なります。プラグイン内から WMP アクセス コードを実行すると、次の例外が発生します。
COMException: Exception from HRESULT: 0xC00D1327
at WMPLib.IWMPPlayer4.get_mediaCollection()
- このシナリオでは、Python for .NET が機能していることがわかります。これは、この時点で .NET アセンブリから他のものを既に読み込んでアクセスしているためです。
- C:\Windows\System32は PATH 変数の先頭にあります。COM dll は PATH 環境変数 (これはそう言っているようです) を介して配置する必要があると想定していますが、それについては完全には確信が持てません。 このユニークなシナリオ (Python が .NET にアクセスし、COM にアクセスする) で COM アセンブリをどのように配置するかは、私にとって最大の未知数の 1 つです。
質問
- COM アセンブリへのアクセスが機能しなくなるなど、Plex プラグイン サンドボックスが Python 実行環境をどのように変更している可能性がありますか?
- この場合、環境は COM アセンブリをどのように見つけてアクセスする必要がありますか?
- Plex サンドボックスがロックダウンしている特定の権限が必要ですか?
たぶん、非常に多くの異なるテクノロジーが独特の混乱を招く方法で交差する質問に到達したことに対して、少なくとも何らかの賞を獲得する必要があります...
編集 1
以下の@Pauloの提案のおかげで、.NET関連の問題を完全に除外しました。私は現在、 Python ライブラリをWMPLib
介してすべての相互運用を行っています。comtypes
今、私は次のエラーが発生しています:
COMError: (-1072884953, None, (None, None, None, 0, None))
は別-1072884953
のエラー コードですが、少し調べてみると、このエラーは .NET 相互運用機能で発生していたのと同じエラーに関連しているように見えます (この投稿ではそのように見えます)。
だから今、私が立ち往生している事実は次のとおりです。
wmp.dll
すべてのケースでロードされています(@Pauloが以下で理解するのを助けてくれました)。- WMP にアクセスするコードが Plex サンドボックス環境の外で実行されると、WMP からライブラリ アイテムに問題なくアクセスできます。
- WMP にアクセスするコードが Plex サンドボックス環境内で実行されると、WMP からライブラリ アイテムにアクセスできません。
- 私が受け取ったエラー コード (.NET または Python ベースの COM 相互運用機能のいずれか) は
NS_E_CURL_INVALIDPATH: The URL contains a path that is not valid.
、ほとんどの場合、試行された再生に関連しているようです。 - 私のシナリオでは再生まで行ったことがないので、これは奇妙です...私は電話しようとしているだけです
wmp.mediaCollection
したがって、このシナリオでは Plex サンドボックスが本当に重要なようです。さらにアイデアはありますか?
編集 2
少なくとも、失敗するために必要なコードは次のとおりです。
from comtypes.client import CreateObject
wmp = CreateObject("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")
collection = wmp.mediaCollection
そこでcollection = wmp.mediaCollection
エラーが発生します。
したがって、失敗の原因となる可能性のあるパラメーターが渡されることは実際にはありません。繰り返しますが、このコードは一般的な Python 2.7 コンテキストで問題なく動作します。Plex プラグイン サンドボックス内でのみ失敗します。Plex サンドボックスが実行環境をどのように変更しているかについての詳細を取得する方法がわかりません。私の答えはその方向にあると思います。