Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get-AudioDevice -List, error when disabled device present #35

Closed
semce2 opened this issue Nov 30, 2019 · 15 comments · Fixed by #52 or #55
Closed

Get-AudioDevice -List, error when disabled device present #35

semce2 opened this issue Nov 30, 2019 · 15 comments · Fixed by #52 or #55
Labels

Comments

@semce2
Copy link

semce2 commented Nov 30, 2019

Maybe I did something wrong but this doesn't work for me. I get : Element not found. (Exception from HRESULT: 0x80070490). FullyQualifiedErrorId: System.Runtime.InteropServices.COMException,AudioDeviceCmdlets.GetAudioDevice.

@cebaa
Copy link

cebaa commented Jan 16, 2020

Agreed:

> Get-AudioDevice -List
Get-AudioDevice : Element not found. (Exception from HRESULT: 0x80070490)
At line:1 char:1
+ Get-AudioDevice -List
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-AudioDevice], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,AudioDeviceCmdlets.GetAudioDevice

Not sure how to get more information / troubleshoot further, @frgnca any pointers?

@frgnca
Copy link
Owner

frgnca commented Jan 17, 2020

Never seen this before. What is the output of say
Get-AudioDevice -Index 1

Does it give a different error message?

@cebaa
Copy link

cebaa commented Jan 17, 2020

@frgnca

No, same:

> Get-AudioDevice -Index 1
Get-AudioDevice : Element not found. (Exception from HRESULT: 0x80070490)
At line:1 char:1
+ Get-AudioDevice -Index 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-AudioDevice], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,AudioDeviceCmdlets.GetAudioDevice

One more detail that I just become aware of. I have multiple audio devices. The above fails only when issued against a non-default audio device. It succeeds when issued against a default device. I've tested by changing all combinations.

This is with AudioDeviceCmdlets 3.0.0.4 by the way.

@TheEngineerGuy
Copy link

TheEngineerGuy commented Nov 25, 2020

Same issue.

As described above, all switch parameters are working, other than List.

> Get-AudioDevice -List
Get-AudioDevice : Element not found. (Exception from HRESULT: 0x80070490)
At line:1 char:1
+ Get-AudioDevice -List
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-AudioDevice], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,AudioDeviceCmdlets.GetAudioDevice

In regards to your question @frgnca , I don't have an active device on Index 1, but if I look for 3, I get a result as expected.

>Get-AudioDevice -Index 3


Index   : 3
Default : True
Type    : Playback
Name    : Speakers (Realtek High Definition Audio)
ID      : {0.0.0.00000000}.{94f04e23-d7a2-485e-bd3b-35debef6ba0e}
Device  : CoreAudioApi.MMDevice

I have re-installed the module as well. Just to make sure that it wasn't an import issue.

> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Binary     3.0.0.0    AudioDeviceCmdlets                  {Get-AudioDevice, Set-AudioDevice, Write-AudioDevice}

Kindly assist.

@TheEngineerGuy
Copy link

TheEngineerGuy commented Nov 25, 2020

Performed some additional tests.

If I disable all devices, leaving only the active device enabled. I get the result. But the moment any other device gets enabled, it stops working again.

> Get-AudioDevice -List


Index   : 1
Default : True
Type    : Playback
Name    : Speakers (Realtek High Definition Audio)
ID      : {0.0.0.00000000}.{94f04e23-d7a2-485e-bd3b-35debef6ba0e}
Device  : CoreAudioApi.MMDevice

Another interesting finding, if all devices above the Default device are disabled and the ones below the default device are enabled, the list works till it hits the first non-default device.

Get-AudioDevice -List


Index   : 1
Default : True
Type    : Playback
Name    : Speakers (Realtek High Definition Audio)
ID      : {0.0.0.00000000}.{94f04e23-d7a2-485e-bd3b-35debef6ba0e}
Device  : CoreAudioApi.MMDevice

Get-AudioDevice : Element not found. (Exception from HRESULT: 0x80070490)
At line:1 char:1
+ Get-AudioDevice -List
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-AudioDevice], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,AudioDeviceCmdlets.GetAudioDevice

To me, it seems that (possibly after the new windows update) non-default devices are no longer providing an element of data required to populate this list, which makes the query to stop on first non-default device, and stop recursing through the rest of the list.

What do you think @frgnca ?

@costafrancesco94
Copy link

I'm also affected by this bug, I installed the dll only with Install-Module -Name AudioDeviceCmdlets and I confirm I can see the device with Get-AudioDevice -Index 2 and I can set the audio playback with Set-AudioDevice -PlaybackVolume 50.

I cannot exec Set-AudioDevice 2 -PlaybackVolume 50 nor Set-AudioDevice "{...}" -PlaybackVolume 50 nor with Set-AudioDevice (Get-AudioDevice -Index 2) -PlaybackVolume 50 but I don't know if the behaviour is intentional.
They all gave to me

Set-AudioDevice : Impossibile trovare un parametro posizionale che accetta l'argomento <whatever>
+ CategoryInfo          : InvalidArgument: (:) [Set-AudioDevice], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,AudioDeviceCmdlets.SetAudioDevice

@snowmountainer
Copy link

I could see the same error.
Personally, I suspect that the error only occurs on computers with newer hardware.

@TheEngineerGuy
Copy link

I could see the same error.
Personally, I suspect that the error only occurs on computers with newer hardware.

This has nothing to do with newer hardware. My PC is Haswell 4790k from 2015. I found exactly what causes the issue. When Mic is connected issue disappears, when mic is disconnected issue appears.

As posted in my previous message, latest windows update removes certain details from disconnected devices that this query is looking for. So, instead of gracefully moving to the next device, this query just crashes.

@frgnca
Copy link
Owner

frgnca commented Aug 15, 2021

#@TheEngineerGuy

To me, it seems that (possibly after the new windows update) non-default devices are no longer providing an element of data required to populate this list, which makes the query to stop on first non-default device, and stop recursing through the rest of the list.

Here is where the error is probably occuring

// For every MMDevice in DeviceCollection
for (int i = 0; i < DeviceCollection.Count; i++)
{
// If this MMDevice's ID is either, the same the default playback device's ID, or the same as the default recording device's ID
if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eMultimedia).ID)
{
// Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, and a default value of true
WriteObject(new AudioDevice(i + 1, DeviceCollection[i], true));
}
else
{
// Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself
WriteObject(new AudioDevice(i + 1, DeviceCollection[i]));
}
}

[...] latest windows update removes certain details from disconnected devices that this query is looking for. So, instead of gracefully moving to the next device, this query just crashes.

Hopefuly my goal of adding support for disabled/disconnected AudioDevice will bypass this problem.

@frgnca frgnca added the bug label Aug 15, 2021
@TheEngineerGuy
Copy link

TheEngineerGuy commented Aug 15, 2021

Good find. I think you are correct. It should bypass the issue when there is something in 'recoding device' list, even if it is disabled or disconnected.

Even before this condition we could branch out the 'if', to execute 'iff' there is a device in default recording device list. If there is a default device execute as is, and if not execute modified conditions without recording device conditions. Just a thought, I leave it to you how you think it would be best.

@Rochkiller
Copy link

I just got this error when I disconnected my default recording device, just re-connected it the error is gone.

I have manually compiled "Dev v3.0.1 communicationdevice #30" and "add -ShowDisabled parameter support to List parameter (#24)". I don't try to see if this occurs with the lastest available release (3.0).

It's a shame that this wonderful tweak didn't update anymore ...

@frgnca frgnca linked a pull request Jan 23, 2022 that will close this issue
@frgnca frgnca changed the title Element not found error Get-AudioDevice -List, error when disabled device present Jan 23, 2022
@frgnca
Copy link
Owner

frgnca commented Jan 23, 2022

I just want to confirm being able to replicate this bug by calling the -List parameter when there is no enabled playback device and/or no enabled recording device.
I intent to fix this bug before merging #52 into the master branch.

@frgnca frgnca mentioned this issue Jan 27, 2022
@frgnca
Copy link
Owner

frgnca commented Jan 27, 2022

With the code as it is now in #52, I think the problem possibly exists in 3 places.

  • List parameter
    // If this MMDevice's ID is either, the same as the default playback device's ID, or the same as the default recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eMultimedia).ID)
    {
    // If the MMDevice's ID is either, the same as the default communication playback device's ID, or the same as the default communication recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eCommunications).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eCommunications).ID)
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of true, and a default communication value of true
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], true, true));
    }
    else
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of true, and a default communication value of false
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], true, false));
    }
    }
    else
    {
    // If the MMDevice's ID is either, the same as the default communication playback device's ID, or the same as the default communication recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eCommunications).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eCommunications).ID)
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of false, and a default communication value of true
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], false, true));
    }
    else
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of false, and a default communication value of false
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], false, false));
    }
    }
  • ID parameter
    // If this MMDevice's ID is either, the same as the default playback device's ID, or the same as the default recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eMultimedia).ID)
    {
    // If the MMDevice's ID is either, the same as the default communication playback device's ID, or the same as the default communication recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eCommunications).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eCommunications).ID)
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of true, and a default communication value of true
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], true, true));
    }
    else
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of true, and a default communication value of false
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], true, false));
    }
    }
    else
    {
    // If the MMDevice's ID is either, the same as the default communication playback device's ID, or the same as the default communication recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eCommunications).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eCommunications).ID)
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of false, and a default communication value of true
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], false, true));
    }
    else
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of false, and a default communication value of false
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], false, false));
    }
    }
  • Index parameter
    // If this MMDevice's ID is either, the same as the default playback device's ID, or the same as the default recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eMultimedia).ID)
    {
    // If the MMDevice's ID is either, the same as the default communication playback device's ID, or the same as the default communication recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eCommunications).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eCommunications).ID)
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of true, and a default communication value of true
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], true, true));
    }
    else
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of true, and a default communication value of false
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], true, false));
    }
    }
    else
    {
    // If the MMDevice's ID is either, the same as the default communication playback device's ID, or the same as the default communication recording device's ID
    if (DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eCommunications).ID || DeviceCollection[i].ID == DevEnum.GetDefaultAudioEndpoint(EDataFlow.eCapture, ERole.eCommunications).ID)
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of false, and a default communication value of true
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], false, true));
    }
    else
    {
    // Output the result of the creation of a new AudioDevice while assining it an index, and the MMDevice itself, a default value of false, and a default communication value of false
    WriteObject(new AudioDevice(i + 1, DeviceCollection[i], false, false));
    }
    }

@frgnca frgnca linked a pull request Jan 28, 2022 that will close this issue
@frgnca
Copy link
Owner

frgnca commented Jan 28, 2022

Having fixed the way the List, ID, and Index parameters work, I came to the conclusion that this bug could also happen in the same way in pretty much all of the other parameters. I will continue to work on those from pull request #55

@frgnca
Copy link
Owner

frgnca commented Feb 18, 2022

I will continue to work on those from pull request #55

Pull request #55 having been merged into the dev_v3.1 branch, I can say that this issue will be fixed when pull request #52 is merged into the master branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants