PDA

View Full Version : سوال: دریافت لیست سخت افزارهای ورودی صدا



ROSTAM2
جمعه 20 مرداد 1402, 08:01 صبح
سلام.
من نیاز به دریافت لیست سخت افزارهای ورودی صدا دارم که این کد دیوایس ها رو بدون اطلاعات وزودی یا خروجی بودن برمی گردونه:

Dim objSearcher As New System.Management.ManagementObjectSearcher("SELECT * FROM Win32_SoundDevice")
Dim objCollection As System.Management.ManagementObjectCollection = objSearcher.Get()

For Each obj As System.Management.ManagementObject In objCollection
If GetPropertyValue(obj, "Status") = "OK" Then
DeviceComboBox.Items.Add(obj)
End If
Next




Function GetPropertyValue(obj As System.Management.ManagementObject, PName As String) As Object
Return obj.GetPropertyValue(PName)
End Function


مطمئنا مشخصه ای باید وجود داشته باشه تا بشه اطلاعات کلی رجیستر شده سخت افزار رو از رجیستری فراخواند ولی من مطمئن نیستم کدوم مشخصه لازمه برای گرفتن این اطلاعات.

چیزی که هست من همه دیوایس های رجیستر شده در رجیستری رو که مربوط به Audio می شه رو به یک لیست کشویی اضافه کردم، منتها چون برنامه من یک رکوردر صوتی هست ققط دیوایس های صدای ورودی باید لیست بشه:

Private RegistryDevicesPath As Microsoft.Win32.RegistryKey



Dim DeviceKind As String, DeviceMame As String
RegistryDevicesPath = My.Computer.Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Enum\SWD\MMDEVAPI", False)


For Each Rk As String In RegistryDevicesPath.GetSubKeyNames
With RegistryDevicesPath.OpenSubKey(Rk, Microsoft.Win32.RegistryKeyPermissionCheck.ReadSub Tree)
'If Me.HardwareList.Contains(.GetValue("ContainerID", "")) = True Then
DeviceKind = .GetValue("ContainerID", "")
DeviceMame = .GetValue("FriendlyName", "")
DeviceComboBox.Items.Add(String.Format("{1}", DeviceKind, DeviceMame))
' End If


End With
Next
If Me.DeviceComboBox.Items.Count > 0 Then
Me.DeviceComboBox.SelectedIndex = 0
End If


154856

و اینکه اون سخت افزار ورودی که در رجیستری موجود هست ممکنه از سیستم حذف شده باشه بنابراین تنها استفاده از رجیستری کارآمد نیست.
اگر اطلاعاتی در این زمینه دارید ممنون می شم اینجا به اشتراک بگذارید.

ROSTAM2
جمعه 20 مرداد 1402, 21:42 عصر
با سلام مجدد.
من لیست دیوایس های صدار را با این الگوریتم به دست آوردم.
اگر راه بهتری سراغ دارید بگید:

Class DeviceInf
Sub New(DisplayName$, IsInput As Boolean)
Me.DisplayName = DisplayName
Me.IsInputDevice = IsInput
End Sub
Public IsInputDevice As Boolean
Public DisplayName As String
End Class
Class DeviceCollection
Inherits List(Of DeviceInf)
Sub New()
MyBase.New()
End Sub
Sub New(DisplayName$, IsInput As Boolean)
MyBase.New()
Me.Add(New DeviceInf(DisplayName, IsInput))
End Sub
Function ExistsByDisplayName(Name$) As Boolean
'If Devices Is Nothing Then Return False
For Each DV As DeviceInf In Me
If DV.DisplayName.Trim.ToLower = Name.Trim.ToLower Then
Return True
End If
Next
Return False
End Function
End Class
Class HardwareInfo
Public Name As String
Public Devices As New DeviceCollection
Public ID As Guid
End Class
Dim Hardvares As New List(Of Guid)
Function GetAudioDevices() As DeviceCollection
Dim Expr As New HardwareInfo
Hardvares.Clear()
Expr.Devices.Clear()
'Dim Devices As New List(Of DeviceInf)
'Devices.Clear()
For Each obj As System.Management.ManagementObject In objCollection
If GetPropertyValue(obj, "Status") = "OK" Then
Dim RegPath As String = DeviceID(obj)
Dim Description$ = ""
Dim DisplayName As String
'================================================= ==========================
' To Recieve Present Device FriendlyNames
' HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\*
'================================================= ==========================
With My.Computer.Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Enum")
With .OpenSubKey(RegPath)
Expr.ID = New Guid(.GetValue("ContainerID", "").ToString)
If Hardvares.Contains(Expr.ID) = True Then Continue For
Description = .GetValue("DeviceDesc", "")
Description = If(Description.Contains(";"), Description.Split(";")(1), Description)
Expr.Name = .GetValue("FriendlyName", Description)
Hardvares.Add(Expr.ID)
Debug.Print("ID:{0}", Expr.ID)
End With
'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ SWD\MMDEVAPI
With .OpenSubKey("SWD\MMDEVAPI")
For Each RegKey As String In .GetSubKeyNames
With .OpenSubKey(RegKey)
If New Guid(.GetValue("ContainerID", "").ToString) = Expr.ID Then
DisplayName = .GetValue("FriendlyName", "")
Debug.Print(" ID:{0} - {1}", Expr.ID, DisplayName)
If Expr.Devices.ExistsByDisplayName(DisplayName) = False Then
Expr.Devices.Add(New DeviceInf(DisplayName, IsInputDevice(DisplayName)))
End If
End If
End With
Next
End With
End With
End If
Next
Return Expr.Devices
End Function


متود IsInputDevice:

Dim NameRegEx As New Regex("(\w*\s*){7}\(")
Function IsInputDevice(Input$) As Boolean
Dim DevName$ = ""
With NameRegEx.Match(Input$)
If .Success = True Then
DevName = .Value.Trim.Substring(0, .Value.Trim.Length - 2)
Return Not (DevName.Contains("Speakers") Or DevName.Contains("Input"))
End If
End With
Return False
End Function


این هم برای جدا سازی دیوایس های صوتی ورودی:
154859

Dim Devices As DeviceCollection

Devices = GetAudioDevices()
For Each Hardware As DeviceInf In Devices
If Hardware.IsInputDevice = True Then
DeviceComboBox.Items.Add(Hardware.DisplayName)
End If
Next

پرستو پارسایی
جمعه 20 مرداد 1402, 23:41 عصر
برای بهبود و بهینه‌سازی کد، می‌توانید از کتابخانه‌هایی مانند NAudio استفاده کنید که عملیات مربوط به دستگاه‌های صوتی را ساده‌تر می‌کند.
این هم نمونه‌ای از کتابخانه NAudio برای دریافت دستگاه‌های صوتی :

Imports NAudio.CoreAudioApi


Class DeviceInfo
Public Property Name As String
Public Property IsInputDevice As Boolean


Public Sub New(name As String, isInputDevice As Boolean)
Me.Name = name
Me.IsInputDevice = isInputDevice
End Sub
End Class


Function GetAudioDevices() As List(Of DeviceInfo)
Dim devices As New List(Of DeviceInfo)()


Dim enumerator As New MMDeviceEnumerator()
Dim endpointCount As Integer = enumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).Count


For i As Integer = 0 To endpointCount - 1
Dim endpoint As MMDevice = enumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active)(i)
Dim isInputDevice As Boolean = (endpoint.DataFlow = DataFlow.Capture)
devices.Add(New DeviceInfo(endpoint.FriendlyName, isInputDevice))
Next


Return devices
End Function



این کد از کتابخانه NAudio استفاده می‌کند و با استفاده از `MMDeviceEnumerator` و `MMDevice` اندازه دقیق دستگاه‌های صوتی را دریافت می‌کند. سپس برای هر دستگاه، یک شی `DeviceInfo` ایجاد می‌شود که شامل نام دستگاه و نوع آن (ورودی یا خروجی) است.

برای استفاده از این کد، کافی است متد `GetAudioDevices` را صدا بزنید و لیستی از دستگاه‌های صوتی را دریافت کنید.