enthought / enthought/comtypes
Asynchronous callbacks from Windows
- Dominant language
- Python
- Stars
- 345
- Forks
- 105
- PR merge metrics
- No merged PRs in 30d
Description
I'm working with comtypes through pyWinCoreAudio. Some of the interfaces exposed there have functions for registering callbacks when something happens such as the volume changing on an audio device, see https://github.com/reversefold/pyWinCoreAudio/blob/75c93a2e7bd38094ad7e151ddeb29e1ccf701a74/pyWinCoreAudio/volume.py#L168 and https://docs.microsoft.com/en-us/windows/win32/api/endpointvolume/nf-endpointvolume-iaudioendpointvolume-registercontrolchangenotify, for example. I can call the registration function just fine but it never does anything.
I'm hoping that the issue is that I'm not running some event loop code, but I haven't been able to find any. I found PumpEvents in the docs but running that seems to have no effect.
Is there something else I'm missing that would allow callbacks like this to work? Is there something further that needs to be implemented in comtypes for this to work? Does anyone know a workaround?
Here is the code I am using to test. You will need https://pypi.org/project/pywincoreaudio/ installed and you will need to replace the `"System"` string for part of the name of an audio device on your machine.
```
from pyWinCoreAudio import device
from pyWinCoreAudio.__core_audio import endpointvolumeapi
from pyWinCoreAudio.__core_audio import iid
devenum = device.AudioDeviceEnumerator()
devices = list(devenum.endpoints)
audevs = [device.AudioDevice(dev.GetId(), devenum) for dev in devenum.endpoints]
audevs.sort(key=lambda d: d.name if d.name else d.id)
found = False
for audev in audevs:
print(f"{audev.name} - {audev.id}")
for title, endpoints in [("Capture", audev.capture_endpoints), ("Render", audev.render_endpoints)]:
if endpoints:
print(f" {title}:")
for ep in endpoints:
print(f" {ep.name} - {ep.session_manager}")
if "System" in ep.name:
found = True
break
if found:
break
if found:
break
class cb(object):
def endpoint_volume_change(e, m, c, mt):
out = f"{e} | {m} | {c} | {mt}\n"
print(out[:-1])
with open("evc.txt", "a") as f:
f.write(out)
ep.volume.register_notification_callback(cb())
from comtypes.client import PumpEvents
import time
while True:
print("PumpEvents")
PumpEvents(1)
time.sleep(1)
```
Run the script, wait for `PumpEvents` then try changing the volume of said device in the windows mixer.
Contributor guide
Assessment
This issue has not been assessed yet.