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

时间:2013-04-18 09:26:12

标签: c# com

我尝试在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))

at:

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

和例外:

  

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

在第二次尝试块中。 我在google上搜索此异常,但我无法修复它。

2 个答案:

答案 0 :(得分:0)

如果您只需要创建Media Player的实例,只需执行以下操作:

WindowsMediaPlayerClass wmp = new WindowsMediaPlayerClass();

导入WMPLib时已创建WindowsMediaPlayerClass。

答案 1 :(得分:0)

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

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

我对WMP自动化一无所知,但从IWMPFolderMonitorServices documentation

开始,并不难实现这一目标。
  

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

(您可能应该阅读报价中链接的那个页面)

并且:

  

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

确定。查看IWMPPlayer documentation

  

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

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

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

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

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

  

不推荐使用IWMPFolderMonitorServices接口。

您真的应该研究并理解为什么不推荐使用该界面。可能是界面仍然存在但不能使用;或者在现代版本的Windows中永久禁用它公开的功能;或者下一版WMP将不会实现它。