0

我尝试使用流动代码在 C# 中创建 WMPLib.IWMPFolderMonitorServices 来管理包含音乐的文件夹。

public partial class MainWindow : Window
    {
        private WMPLib.IWMPPlayer player;
        private WMPLib.IWMPFolderMonitorServices manageFolder;


        [DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        static extern void CoCreateInstance([In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
                                            [MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
                                             CLSCTX dwClsContext,
                                            [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
                                            [MarshalAs(UnmanagedType.IUnknown)] out object rReturnedComObject);

        public MainWindow()
        {
            InitializeComponent();

            Object instancePlayer = null;
            Guid guid_IWMPPlayer = typeof(WMPLib.IWMPPlayer).GUID;
            Guid guid_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); 
            try
            {
                CoCreateInstance(guid_IWMPPlayer, null, CLSCTX.CLSCTX_INPROC_SERVER, guid_IUnknown, out instancePlayer);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }            
            Type type = Type.GetTypeFromCLSID(guid_IWMPPlayer);

            player = instancePlayer as WMPLib.IWMPPlayer;

            Object instanceFolder = null;
            Guid guid_IWMFolder = typeof(WMPLib.IWMPFolderMonitorServices).GUID;
            IntPtr ptr1, ptr2;

            try
            {
                ptr1 = Marshal.GetComInterfaceForObject(instancePlayer, type);
                Marshal.QueryInterface(ptr1, ref guid_IWMFolder, out ptr2);
                Marshal.PtrToStructure(ptr2, instanceFolder);
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);
            }
            manageFolder = instanceFolder as WMPLib.IWMPFolderMonitorServices;
        }
    }
}

我得到例外:

类未注册(HRESULT 异常:0x80040154 (REGDB_E_CLASSNOTREG))

在 :

CoCreateInstance(guid_IWMPPlayer, null, CLSCTX.CLSCTX_INPROC_SERVER, guid_IUnknown, out instancePlayer);

和例外:

值不能为空。参数名称:o

在第二个尝试块中。我在谷歌上搜索这个异常,但我无法修复它。

4

2 回答 2

0

COM 中没有“创建接口的实例”之类的东西。充其量,您创建恰好实现接口的类(即对象)的实例。我不是迂腐;这是一个重要的区别。

知道您想要的接口(大概是因为您想调用在该接口中声明的方法)绝对不会告诉您如何获取实现它的对象。也许你调用 CoCreateInstance()。或者,也许您在必须首先获得的其他对象上调用一些“GetMonitoringServices()”方法。或者,也许您必须调用一些带有回调函数指针的“Subscribe()”方法,该回调函数指针接收接口指针作为参数。我不知道。您必须阅读类库的文档才能找到答案。

我对 WMP 自动化一无所知,但是从IWMPFolderMonitorServices 文档开始,走这条路并不难:

要使用此界面,您必须创建 Windows Media Player 11 控件的远程实例。有关远程处理的详细信息,请参阅远程处理 Windows Media Player 控件

(您可能也应该阅读引用中链接的页面)

和:

通过 IWMPPlayer 调用 QueryInterface 检索指向 IWMPFolderMonitorServices 的指针。

好的。查看IWMPPlayer 文档

通过调用 COM CoCreateInstance 方法检索指向 IWMPPlayer 接口的指针

这告诉我代码应该是这样的:

var player = new WindowsMediaPlayerClass(); 
var monitoringSvc = (WMPLib.IWMPFolderMonitorServices)player;

我没有测试过代码。一些细节可能会关闭(命名空间等)。但你明白了。

最后,请注意第一个链接:

IWMPFolderMonitorServices 接口已弃用。

您确实应该研究并了解为什么不推荐使用该界面。可能接口还在,但不能使用;或者它公开的功能在现代版本的 Windows 中被永久禁用;或者它不会被下一个版本的 WMP 实现。

于 2013-04-18T13:47:51.907 回答
0

如果您只需要创建媒体播放器的实例,只需执行以下操作:

WindowsMediaPlayerClass wmp = new WindowsMediaPlayerClass();

导入 WMPLib 时已创建 WindowsMediaPlayerClass。

于 2013-04-18T12:26:00.653 回答