Subz Posted March 25, 2018 Posted March 25, 2018 (edited) Hello all. in the process of packaging an application (Voip) and looking at trying to automate capturing the following information to add to a config.xml file: Default: Playback Device Name and Guid Example: Name: Speakers (Realtek High Definition Audio) Guid: {0.0.0.00000000}.{a46ce930-4dd3-49b5-8e8e-7c8a2fdc3925} Default Microphone Device Name and Guid Example: Name: Microphone (Realtek High Definition Audio) Guid: {0.0.1.00000000}.{cff6f838-33ce-4c2d-9f77-98f4e19e4a75} I've seen the following post by @trancexx, which gives me the Default Audit Device Name, but unsure how to get the Guid or the Microphone Name and Guid. I believe to get the Guid, I would need to use PKEY_AudioEndpoint_GUID but unsure how to code this. If anyone can assist or point me in the right direction it would be much appreciated. Cheers Subz Edited March 26, 2018 by Subz
Bilgus Posted March 25, 2018 Posted March 25, 2018 Thats a nice example from Trancexx there I believe you just need to pass the Correct Property Key Global Const $sPKEY_Device_FriendlyName = "{a45c254e-df1c-4efd-8020-67d146a850e0}, 14" Global Const $sPKEY_Audio_Endpoint_GUID = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E}, 4" like literally use $sPKEY_Audio_Endpoint_GUID instead of $sPKEY_Device_FriendlyName
Bilgus Posted March 25, 2018 Posted March 25, 2018 (edited) sorry I missed the part about you wanting the microphone as well expandcollapse popup#include <WinAPICOM.au3> Global Const $sCLSID_MMDeviceEnumerator = "{BCDE0395-E52F-467C-8E3D-C4579291692E}" Global Const $sIID_IMMDeviceEnumerator = "{A95664D2-9614-4F35-A746-DE8DB63617E6}" Global Const $tagIMMDeviceEnumerator = "EnumAudioEndpoints hresult(int;int;ptr*);" & _ "GetDefaultAudioEndpoint hresult(int;int;ptr*);" & _ "GetDevice hresult(wstr;ptr*);" & _ "RegisterEndpointNotificationCallback hresult(ptr);" & _ "UnregisterEndpointNotificationCallback hresult(ptr);" Global Const $IID_IMMDevice = "{D666063F-1587-4E43-81F1-B948E807363F}" Global Const $tagIMMDevice = "Activate hresult(ptr;dword;variant*;ptr*);" & _ "OpenPropertyStore hresult(dword;ptr*);" & _ "GetId hresult(ptr*);" & _ "GetState hresult(dword*);" Global Const $IID_IPropertyStore = "{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}" Global Const $tagIPropertyStore = "GetCount hresult(dword*);" & _ "GetAt hresult(dword;ptr*);" & _ "GetValue hresult(struct*;variant*);" & _ "SetValue hresult(struct*;variant);" & _ "Commit hresult();" Global Const $sPKEY_Device_FriendlyName = "{a45c254e-df1c-4efd-8020-67d146a850e0}, 14" Global Const $sPKEY_Audio_Endpoint_GUID = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E}, 4" Global Const $STGM_READ = 0 Global Const $DEVICE_STATE_ACTIVE = 0x00000001 Global Const $eRender = 0 Global Const $eCapture = 1 Global Const $eAll = 2 Global Const $EDataFlow_enum_count = 3 Global Const $eConsole = 0 Global Const $eMultimedia = 1 Global Const $eCommunications = 2 Global Const $ERole_enum_count = 3 Func _WinAPI_PKEYFromString($sPKEY, $pID = Default) Local $tPKEY = DllStructCreate("byte GUID[16]; dword PID;") DllCall("propsys.dll", "long", "PSPropertyKeyFromString", "wstr", $sPKEY, "struct*", $tPKEY) If $pID <> Default Then DllStructSetData($tPKEY, "PID", $pID) Return $tPKEY EndFunc ;========================================================== Local $oEnumerator = ObjCreateInterface($sCLSID_MMDeviceEnumerator, $sIID_IMMDeviceEnumerator, $tagIMMDeviceEnumerator) Local $pDefaultEndpoint $oEnumerator.GetDefaultAudioEndpoint($eRender, $DEVICE_STATE_ACTIVE, $pDefaultEndpoint) Local $oEndpoint = ObjCreateInterface($pDefaultEndpoint, $IID_IMMDevice, $tagIMMDevice) ; PropertyStore stores properties Local $pProps $oEndpoint.OpenPropertyStore($STGM_READ, $pProps) $oProps = ObjCreateInterface($pProps, $IID_IPropertyStore, $tagIPropertyStore) ; Collect FriendlyName property Local $tPKEY_Device_FriendlyName = _WinAPI_PKEYFromString($sPKEY_Device_FriendlyName) Local $sName $oProps.GetValue($tPKEY_Device_FriendlyName, $sName) ConsoleWrite($sName & @CRLF) Local $tPKEY_Audio_Endpoint_GUID = _WinAPI_PKEYFromString($sPKEY_Audio_Endpoint_GUID) Local $sGuid $oProps.GetValue($tPKEY_Audio_Endpoint_GUID, $sGuid) ConsoleWrite($sGuid & @CRLF) ;------------MICROPHONE $oEnumerator.GetDefaultAudioEndpoint($eCapture, $DEVICE_STATE_ACTIVE, $pDefaultEndpoint) $oEndpoint = ObjCreateInterface($pDefaultEndpoint, $IID_IMMDevice, $tagIMMDevice) ; PropertyStore stores properties $oEndpoint.OpenPropertyStore($STGM_READ, $pProps) $oProps = ObjCreateInterface($pProps, $IID_IPropertyStore, $tagIPropertyStore) ; Collect FriendlyName property $tPKEY_Device_FriendlyName = _WinAPI_PKEYFromString($sPKEY_Device_FriendlyName) $oProps.GetValue($tPKEY_Device_FriendlyName, $sName) ConsoleWrite($sName & @CRLF) $tPKEY_Audio_Endpoint_GUID = _WinAPI_PKEYFromString($sPKEY_Audio_Endpoint_GUID) $oProps.GetValue($tPKEY_Audio_Endpoint_GUID, $sGuid) ConsoleWrite($sGuid & @CRLF) Edited March 26, 2018 by Bilgus Subz 1
Subz Posted March 26, 2018 Author Posted March 26, 2018 Thanks Bilgus Sorry for the delay, it turned out I required the Instance ID rather than the Guid, was attempting to get this when I found another post by Trancexx which included the instance id and I was able to make a few adjustments to return the instance Id, Type (Microphone or Playback) and the name. (see code below) nb: I tried to figure out how to use the ERoles to determine the type but reverted to using the registry as not very familiar with converting C++ into AutoIt code. Thanks again. expandcollapse popup#include <Array.au3> #include <WinAPI.au3> #include <Constants.au3> Global Const $sCLSID_MMDeviceEnumerator = "{BCDE0395-E52F-467C-8E3D-C4579291692E}" Global Const $sIID_IMMDeviceEnumerator = "{A95664D2-9614-4F35-A746-DE8DB63617E6}" Global Const $tagIMMDeviceEnumerator = "EnumAudioEndpoints hresult(dword;dword;ptr*);" & _ "GetDefaultAudioEndpoint hresult(dword;dword;ptr*);" & _ "GetDevice hresult(wstr;ptr*);" & _ "RegisterEndpointNotificationCallback hresult(ptr);" & _ "UnregisterEndpointNotificationCallback hresult(ptr);" Global Const $sCLSID_CPolicyConfigClient = "{870af99c-171d-4f9e-af0d-e63df40c2bc9}" Global Const $sIID_IPolicyConfig = "{f8679f50-850a-41cf-9c72-430f290290c8}" Global Const $tagIPolicyConfig = "GetMixFormat hresult(wstr;ptr*);" & _ "GetDeviceFormat hresult(wstr;int;ptr*);" & _ "ResetDeviceFormat hresult(wstr);" & _ "SetDeviceFormat hresult(wstr;ptr;ptr);" & _ "GetProcessingPeriod hresult(wstr;int;int64*;int64*);" & _ "SetProcessingPeriod hresult(wstr;int64*);" & _ "GetShareMode hresult(wstr;ptr);" & _ "SetShareMode hresult(wstr;ptr);" & _ "GetPropertyValue hresult(wstr;struct;variant*);" & _ "SetPropertyValue hresult(wstr;struct;variant*);" & _ "SetDefaultEndpoint hresult(wstr;int);" & _ "SetEndpointVisibility hresult(wstr;int);" Global Const $IID_IMMDevice = "{D666063F-1587-4E43-81F1-B948E807363F}" Global Const $tagIMMDevice = "Activate hresult(ptr;dword;variant*;ptr*);" & _ "OpenPropertyStore hresult(dword;ptr*);" & _ "GetId hresult(ptr*);" & _ "GetState hresult(dword*);" Global Const $IID_IMMDeviceCollection = "{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}" Global Const $tagIMMDeviceCollection = "GetCount hresult(uint*);" & _ "Item hresult(uint;ptr*)" Global Const $IID_IPropertyStore = "{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}" Global Const $tagIPropertyStore = "GetCount hresult(dword*);" & _ "GetAt hresult(dword;ptr*);" & _ "GetValue hresult(ptr;variant*);" & _ "SetValue hresult(ptr;variant);" & _ "Commit hresult();" Global Const $sPKEY_Device_FriendlyName = "{a45c254e-df1c-4efd-8020-67d146a850e0} 14" Global Const $STGM_READ = 0 Global Const $DEVICE_STATE_ACTIVE = 0x00000001 Global Const $eRender = 0 Global Const $eCapture = 1 Global Const $eAll = 2 Global Const $EDataFlow_enum_count = 3 Global Const $eConsole = 0 Global Const $eMultimedia = 1 Global Const $eCommunications = 2 Global Const $ERole_enum_count = 3 ;========================================================== Global $aArray = _EnumerateDevices() _ArrayDisplay($aArray) Func _EnumerateDevices() ;~ Error monitoring Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") #forceref $oErrorHandler ;~ Registry Key for Audio Devices Local $sRegAudio = @OSArch = "x64" ? "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio" : "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio" ;~ Create MMDeviceEnumerator object Local $oEnumerator = ObjCreateInterface($sCLSID_MMDeviceEnumerator, $sIID_IMMDeviceEnumerator, $tagIMMDeviceEnumerator) ;~ Get collection out of it Local $pCollection $oEnumerator.EnumAudioEndpoints($eAll, $DEVICE_STATE_ACTIVE, $pCollection) ;~ Turn it into object Local $oCollection = ObjCreateInterface($pCollection, $IID_IMMDeviceCollection, $tagIMMDeviceCollection) ;~ Check the number of devices in collection Local $iCount $oCollection.GetCount($iCount) ;~ Array for out Local $aArray[$iCount][4] Local $pEndpoint, $oEndpoint Local $pID, $sId, $pProps, $oProps Local $sName Local $tPKEY_Device_FriendlyName = _WinAPI_PKEYFromString($sPKEY_Device_FriendlyName) ;~ Actual enumeration For $i = 0 To $iCount - 1 ;~ Item at "i" index is audio endpoint device $oCollection.Item($i, $pEndpoint) $oEndpoint = ObjCreateInterface($pEndpoint, $IID_IMMDevice, $tagIMMDevice) ;~ Collect ID $oEndpoint.GetId($pID) $sId = DllStructGetData(DllStructCreate("wchar ID[" & _WinAPI_PtrStringLenW($pID) & "]", $pID), "ID") _WinAPI_CoTaskMemFree($pID) $aArray[$i][2] = $sId ;~ Detect Instance ID is Microphone(capture) or Playback(render) $aGuid = StringSplit($sId, ".") $aArray[$i][1] = $aGuid[$aGuid[0]] $aArray[$i][0] = RegRead($sRegAudio & "\Capture\" & $aGuid[$aGuid[0]], "DeviceState") >= 1 ? "Microphone" : "" If $aArray[$i][0] = "" Then $aArray[$i][0] = RegRead($sRegAudio & "\Render\" & $aGuid[$aGuid[0]], "DeviceState") >= 1 ? "Playback" : "" ;~ PropertyStore stores properties, lol $oEndpoint.OpenPropertyStore($STGM_READ, $pProps) $oProps = ObjCreateInterface($pProps, $IID_IPropertyStore, $tagIPropertyStore) ;~ Collect FriendlyName property $sName = 0 $oProps.GetValue(DllStructGetPtr($tPKEY_Device_FriendlyName), $sName) $aArray[$i][3] = $sName Next Return $aArray EndFunc ;==>_EnumerateDevices Func _SwitchToDevice($sId) Local $oPolicyConfig = ObjCreateInterface($sCLSID_CPolicyConfigClient, $sIID_IPolicyConfig, $tagIPolicyConfig) Local $hResult = $oPolicyConfig.SetDefaultEndpoint($sId, $eConsole) If $hResult = $S_OK Then $hResult = $oPolicyConfig.SetDefaultEndpoint($sId, $eCommunications) Return $hResult = $S_OK EndFunc ;==>_SwitchToDevice Func _WinAPI_PKEYFromString($sPKEY, $pID = Default) Local $tPKEY = DllStructCreate("byte GUID[16]; dword PID;") DllCall("propsys.dll", "long", "PSPropertyKeyFromString", "wstr", $sPKEY, "ptr", DllStructGetPtr($tPKEY)) If @error Then ; alternative for unsupported systems Local $tGUID = _WinAPI_GUIDFromString($sPKEY) If Not @error Then DllStructSetData($tPKEY, "GUID", DllStructGetData(DllStructCreate("byte Data[16]", DllStructGetPtr($tGUID)), 1)) EndIf DllStructSetData($tPKEY, "PID", Number(StringRegExpReplace($sPKEY, ".*?}", ""))) EndIf If $pID <> Default Then DllStructSetData($tPKEY, "PID", $pID) Return $tPKEY EndFunc ;==>_WinAPI_PKEYFromString Func _WinAPI_PtrStringLenW($pString) Local $aCall = DllCall("kernel32.dll", "dword", "lstrlenW", "ptr", $pString) If @error Then Return SetError(1, 0, 0) Return $aCall[0] EndFunc ;==>_WinAPI_PtrStringLenW Func _WinAPI_CoTaskMemFree($pMem) DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pMem) If @error Then Return SetError(1, 0, False) Return True EndFunc ;==>_WinAPI_CoTaskMemFree Func _ErrFunc($oError) ConsoleWrite("COM Error, ScriptLine(" & $oError.scriptline & ") : Number 0x" & Hex($oError.number, 8) & " - " & $oError.windescription & @CRLF) EndFunc ;==>_ErrFunc
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now