windows 如何以编程方式更改默认声音播放设备?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2175318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:05:45  来源:igfitidea点击:

How to change default sound playback device programmatically?

windowswinapivisual-c++mci

提问by Ashish

How to change the default default audio device for playback and recording in vista programmatically ?

如何以编程方式更改用于在 vista 中播放和录制的默认默认音频设备?

Is there any registry setting for it like sound manager in window XP?

是否有任何注册表设置,如 Windows XP 中的声音管理器?

Which API does it?

哪个 API 做到了?

采纳答案by ReinstateMonica Larry Osterman

There is no public API which allows you to change the default audio device, that is functionality that is considered to be under the users control. This has always been the case in Windows.

没有允许您更改默认音频设备的公共 API,即被认为受用户控制的功能。在 Windows 中一直都是这种情况。

Having said that, if you search the web, there are a number of people who have reverse engineered the APIs that are used in Windows Vista to do this, but I'm not going to point you to them (the reverse engineered APIs are internal unsupported APIs and may change without notice from Microsoft). You use these solutions at your own peril.

话虽如此,如果您在网络上搜索,有很多人对 Windows Vista 中使用的 API 进行了逆向工程来执行此操作,但我不会向您指出他们(逆向工程的 API 是内部的)不受支持的 API,如有更改,恕不另行通知 Microsoft)。您自行承担使用这些解决方案的风险。

回答by stacker

System Tray Audio Device Switcher uses "Software\Microsoft\Multimedia\Sound Mapper", "Playback"to set the index of the sound device which was obtained by enumeration the devices. mciSendCommandfrom "winmm.dll" is also used

System Tray Audio Device Switcher 用于"Software\Microsoft\Multimedia\Sound Mapper", "Playback"设置通过枚举设备获得的声音设备的索引。 还使用了来自“winmm.dll”的mciSendCommand

In this source code you will find the registry keys used to achieve that.

在此源代码中,您将找到用于实现此目的的注册表项。

If this doesn't work you could give Process Monitora try and monitor all registry activities of windows when you change the default device. On my Vista installation the control panel twiddles with "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\"

如果这不起作用,你可以给进程监视器尝试一下,当您更改默认的设备监控窗口的所有注册表活动。在我的 Vista 安装中,控制面板显示"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\"

For Vistasee http://www.vistaaudiochanger.com/

对于Vista,请参阅 http://www.vistaaudiochanger.com/

回答by Battlechicken

I really don't know if anyone still needs this, but here is my solution. Actually, it's for the capture device, but it can be changed easily to the render device.

我真的不知道是否还有人需要这个,但这是我的解决方案。实际上,它用于捕获设备,但可以轻松更改为渲染设备。

It sets 3 registry values in the device's key to the current time. Magic, but that's how it works. Note: only tested on Win7 x64

它将设备密钥中的 3 个注册表值设置为当前时间。魔术,但这就是它的工作原理。注意:仅在 Win7 x64 上测试

void SetDefaultRecordDevice(tstring strDeviceName){
    const int BUFF_LEN = 260;
    //HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture\{79434968-09f6-4dff-8086-c5e618b21473}\Role:0:
    //"DE 07 08 00 06 00 10 00 15 00 38 00 1E 00 48 03"
    HKEY hkCaptureDevices;
    RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture") , 0, KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY, &hkCaptureDevices);
    TCHAR lpwstrDeviceGuidKey[BUFF_LEN];
    DWORD dwDeviceGuidKeySize = BUFF_LEN;
    for(int i=0;RegEnumKeyEx(hkCaptureDevices, i, lpwstrDeviceGuidKey, &dwDeviceGuidKeySize, 0, 0, 0, 0) != ERROR_NO_MORE_ITEMS; ++i){
        dwDeviceGuidKeySize = BUFF_LEN;
        HKEY hkProps;
        RegOpenKeyEx(hkCaptureDevices, (tstring(lpwstrDeviceGuidKey) + _T("\Properties")).c_str() , 0, KEY_READ | KEY_WOW64_64KEY, &hkProps);
        TCHAR data[BUFF_LEN];
        DWORD dwDataSize = BUFF_LEN;
        if(RegQueryValueEx(hkProps, _T("{a45c254e-df1c-4efd-8020-67d146a850e0},2"), 0, 0, (LPBYTE)data, &dwDataSize) !=  ERROR_SUCCESS){
            continue;
        } else {
            tstring strCurrentDeviceName(data);
            // TODO név általánosítás
            if(strDeviceName == strCurrentDeviceName){
                HKEY hkGuid;
                RegOpenKeyEx(hkCaptureDevices, lpwstrDeviceGuidKey , 0, KEY_READ | KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_64KEY | KEY_NOTIFY , &hkGuid);

                time_t CurrentTime;
                time(&CurrentTime);

                time_t     now = time(0);
                struct tm  tstruct;


                gmtime_s(&tstruct, &now);
                // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
                // for more information about date/time format

                char CustomRegistryDateValue[16];

                WORD year = tstruct.tm_year + 1900;
                WORD month = tstruct.tm_mon+1;
                WORD dayOfTheWeek = tstruct.tm_wday;
                WORD day = tstruct.tm_mday;
                WORD hour = tstruct.tm_hour;
                WORD minute = tstruct.tm_min;
                WORD second = tstruct.tm_sec;
                WORD millisec = 0x0; // hasrautés

                int k = 0;
                *((WORD*)CustomRegistryDateValue + k++) = year;
                *((WORD*)CustomRegistryDateValue + k++) = month;
                *((WORD*)CustomRegistryDateValue + k++) = dayOfTheWeek;
                *((WORD*)CustomRegistryDateValue + k++) = day;
                *((WORD*)CustomRegistryDateValue + k++) = hour;
                *((WORD*)CustomRegistryDateValue + k++) = minute;
                *((WORD*)CustomRegistryDateValue + k++) = second;
                *((WORD*)CustomRegistryDateValue + k++) = millisec;

                RegSetValueExA(hkGuid, ("Role:0"), 0, REG_BINARY, (LPBYTE)CustomRegistryDateValue, 16);
                RegSetValueExA(hkGuid, ("Role:1"), 0, REG_BINARY, (LPBYTE)CustomRegistryDateValue, 16);
                RegSetValueExA(hkGuid, ("Role:2"), 0, REG_BINARY, (LPBYTE)CustomRegistryDateValue, 16);
                RegFlushKey(hkGuid);
                RegCloseKey(hkGuid);
            }
        }
        RegCloseKey(hkProps);
    }
    RegCloseKey(hkCaptureDevices);
}