您好,登錄后才能下訂單哦!
這篇文章主要講解了“C#如何使用com獲取Windows攝像頭列表”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C#如何使用com獲取Windows攝像頭列表”吧!
我們使用directshow獲取視頻設備列表,由于com的跨語言特性,完全可以直接在C#中調用,而不用通過C++封裝一層dll給C#使用。我們首先定義需要的com對象接口。
static readonly Guid SystemDeviceEnum = new Guid(0x62BE5D10, 0x60EB, 0x11D0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86); static readonly Guid VideoInputDevice = new Guid(0x860BB310, 0x5D01, 0x11D0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86); [Flags] enum CDef { None = 0x0, ClassDefault = 0x1, BypassClassManager = 0x2, ClassLegacy = 0x4, MeritAboveDoNotUse = 0x8, DevmonCMGRDevice = 0x10, DevmonDMO = 0x20, DevmonPNPDevice = 0x40, DevmonFilter = 0x80, DevmonSelectiveMask = 0xF0 } [ComImport] [SuppressUnmanagedCodeSecurity] [Guid("3127CA40-446E-11CE-8135-00AA004BB851")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IErrorLog { [PreserveSig] int AddError([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [In] System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo); } [ComImport] [Localizable(false)] [SuppressUnmanagedCodeSecurity] [Guid("55272A00-42CB-11CE-8135-00AA004BB851")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IPropertyBag { [PreserveSig] int Read([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [MarshalAs(UnmanagedType.Struct)] out object pVar, [In] IErrorLog pErrorLog); [PreserveSig] int Write([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [In][MarshalAs(UnmanagedType.Struct)] ref object pVar); } [ComImport] [SuppressUnmanagedCodeSecurity] [Guid("29840822-5B84-11D0-BD3B-00A0C911CE86")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface ICreateDevEnum { [PreserveSig] int CreateClassEnumerator([In][MarshalAs(UnmanagedType.LPStruct)] Guid pType, out IEnumMoniker ppEnumMoniker, [In] CDef dwFlags); }
與directshow流程一樣,調用com枚舉設備即可,本文只展示獲取設備名稱(FriendlyName),獲取其他屬性可以參照c++調用directshow的實現。
/// <summary> /// 枚舉視頻設備 /// </summary> public static IEnumerable<string> Devices { get { IMoniker[] monikers = new IMoniker[5]; var devEnum = Activator.CreateInstance(Type.GetTypeFromCLSID(SystemDeviceEnum)) as ICreateDevEnum; IEnumMoniker moniker; if (devEnum.CreateClassEnumerator(VideoInputDevice, out moniker, 0) == 0) { while (true) { int r = moniker.Next(1, monikers, IntPtr.Zero); if (r != 0 || monikers[0] == null) break; yield return GetName(monikers[0]); foreach (var i in monikers) { if(i!=null) Marshal.ReleaseComObject(i); } } Marshal.ReleaseComObject(moniker); } Marshal.ReleaseComObject(devEnum); } } /// <summary> /// 獲取設備名稱 /// </summary> /// <param name="moniker"></param> /// <returns></returns> static string GetName(IMoniker moniker) { IPropertyBag property; object value; object temp = null; try { Guid guid = typeof(IPropertyBag).GUID; moniker.BindToStorage(null, null, ref guid, out temp); property = temp as IPropertyBag; int hr = property.Read("FriendlyName", out value, null); Marshal.ThrowExceptionForHR(hr); return value as string; } catch (Exception) { return null; } finally { if (temp != null) { Marshal.ReleaseComObject(temp); } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Security; namespace AC { public class EnumDevices { /// <summary> /// 枚舉視頻設備 /// </summary> public static IEnumerable<string> Devices { get { IMoniker[] monikers = new IMoniker[5]; var devEnum = Activator.CreateInstance(Type.GetTypeFromCLSID(SystemDeviceEnum)) as ICreateDevEnum; IEnumMoniker moniker; if (devEnum.CreateClassEnumerator(VideoInputDevice, out moniker, 0) == 0) { while (true) { int hr = moniker.Next(1, monikers, IntPtr.Zero); if (hr != 0 || monikers[0] == null) break; yield return GetName(monikers[0]); foreach (var i in monikers) { if(i!=null) Marshal.ReleaseComObject(i); } } Marshal.ReleaseComObject(moniker); } Marshal.ReleaseComObject(devEnum); } } /// <summary> /// 獲取設備名稱 /// </summary> /// <param name="moniker"></param> /// <returns></returns> static string GetName(IMoniker moniker) { IPropertyBag property; object value; object temp = null; try { Guid guid = typeof(IPropertyBag).GUID; moniker.BindToStorage(null, null, ref guid, out temp); property = temp as IPropertyBag; int hr = property.Read("FriendlyName", out value, null); Marshal.ThrowExceptionForHR(hr); return value as string; } catch (Exception) { return null; } finally { if (temp != null) { Marshal.ReleaseComObject(temp); } } } static readonly Guid SystemDeviceEnum = new Guid(0x62BE5D10, 0x60EB, 0x11D0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86); static readonly Guid VideoInputDevice = new Guid(0x860BB310, 0x5D01, 0x11D0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86); [Flags] enum CDef { None = 0x0, ClassDefault = 0x1, BypassClassManager = 0x2, ClassLegacy = 0x4, MeritAboveDoNotUse = 0x8, DevmonCMGRDevice = 0x10, DevmonDMO = 0x20, DevmonPNPDevice = 0x40, DevmonFilter = 0x80, DevmonSelectiveMask = 0xF0 } [ComImport] [SuppressUnmanagedCodeSecurity] [Guid("3127CA40-446E-11CE-8135-00AA004BB851")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IErrorLog { [PreserveSig] int AddError([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [In] System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo); } [ComImport] [Localizable(false)] [SuppressUnmanagedCodeSecurity] [Guid("55272A00-42CB-11CE-8135-00AA004BB851")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IPropertyBag { [PreserveSig] int Read([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [MarshalAs(UnmanagedType.Struct)] out object pVar, [In] IErrorLog pErrorLog); [PreserveSig] int Write([In][MarshalAs(UnmanagedType.LPWStr)] string pszPropName, [In][MarshalAs(UnmanagedType.Struct)] ref object pVar); } [ComImport] [SuppressUnmanagedCodeSecurity] [Guid("29840822-5B84-11D0-BD3B-00A0C911CE86")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface ICreateDevEnum { [PreserveSig] int CreateClassEnumerator([In][MarshalAs(UnmanagedType.LPStruct)] Guid pType, out IEnumMoniker ppEnumMoniker, [In] CDef dwFlags); } } }
.net 6.0代碼示例如下
// See https://aka.ms/new-console-template for more information using AC; //枚舉設備 foreach (var i in EnumDevices.Devices) { //打印設備名稱 Console.WriteLine(i); }
效果:
感謝各位的閱讀,以上就是“C#如何使用com獲取Windows攝像頭列表”的內容了,經過本文的學習后,相信大家對C#如何使用com獲取Windows攝像頭列表這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。