In an application I've been using the piece of code below to automatically set the 'Default Format' of the microphone to '2 channel, 16 bit, 48000Hz'.
This code works in Windows 7 an 8 en until recently also in Windows 10. Since some update of Windows 10 this year the code doesn't work anymore as expected. When I manually set the format to another value, like 44.1KHz in Sound - Mic - Advanced and I run the code, then the format is changed to '2 channel, 16 bit, 48000Hz', but I get no sound from the microphone. When I set the format manually to the correct value, then there are no problems.
Here is the piece of code:
IMMDevice* pEndpointRead = NULL;
IMMDevice* pEndpointWrite = NULL;
IMMDeviceEnumerator* pEnumerator = NULL;
IPropertyStore* propertyStoreRead = NULL;
IPropertyStore* propertyStoreWrite = NULL;
IAudioClient *audioClient = NULL;
PROPVARIANT propRead;
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pEnumerator);
hr = pEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &pEndpointRead);
hr = pEndpointRead->OpenPropertyStore(STGM_READ, &propertyStoreRead);
if (FAILED(hr))
{
std::cout << "OpenPropertyStore failed!" << std::endl;
}
hr = propertyStoreRead->GetValue(PKEY_AudioEngine_DeviceFormat, &propRead);
if (FAILED(hr))
{
std::cout << "GetValue failed!" << std::endl;
}
deviceFormatProperties =(WAVEFORMATEXTENSIBLE *)propRead.blob.pBlobData;
deviceFormatProperties->Format.nChannels = 2;
deviceFormatProperties->Format.nSamplesPerSec = 48000;
deviceFormatProperties->Format.wBitsPerSample = 16;
deviceFormatProperties->Samples.wValidBitsPerSample = deviceFormatProperties->Format.wBitsPerSample;
deviceFormatProperties->Format.nBlockAlign = (deviceFormatProperties->Format.nChannels*deviceFormatProperties->Format.wBitsPerSample) / 8;
deviceFormatProperties->Format.nAvgBytesPerSec = deviceFormatProperties->Format.nSamplesPerSec*deviceFormatProperties->Format.nBlockAlign;
deviceFormatProperties->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
deviceFormatProperties->Format.cbSize = 22;
deviceFormatProperties->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
hr = pEndpointRead->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&audioClient);
if (FAILED(hr))
{
std::cout << "pDevice->Activate failed!" << std::endl;
}
hr = audioClient->IsFormatSupported(/*AUDCLNT_SHAREMODE_SHARED*/AUDCLNT_SHAREMODE_EXCLUSIVE, (PWAVEFORMATEX)&deviceFormatProperties->Format, NULL);
if (FAILED(hr))
{
std::cout << "IsFormatSupported failed" << std::endl;
}
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pEnumerator);
hr = pEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &pEndpointWrite);
hr= pEndpointWrite->OpenPropertyStore(STGM_WRITE, &propertyStoreWrite);
if (FAILED(hr))
{
std::cout << "OpenPropertyStore failed!" << std::endl;
}
hr = propertyStoreWrite->SetValue(PKEY_AudioEngine_DeviceFormat, propRead);
if (FAILED(hr))
{
std::cout << "SetValue failed!" << std::endl;
}
hr = propertyStoreWrite->Commit();
pEndpointWrite->Release();
pEnumerator->Release();
propertyStoreWrite->Release();
pEndpointRead->Release();
propertyStoreRead->Release();
pEndpointRead = NULL;
PropVariantClear(&propRead);
Any idea what could be the problem?
Related
Good afternoon, I am writing a program that will extract pixels from the desktop, but unfortunately I ran into a problem, Map gives an error "Access Violation". Help me please.
I've divided all the code by function to make it clear to you.
I hope you can help me because I have little experience with directx and dxgi so far.
ID3D11Device *m_pDevice;
ID3D11DeviceContext *m_pDeviceContext;
IDXGIDevice *m_pDXGIDevice;
ID3D11Texture2D* m_pDesktopTexture;
ID3D11Texture2D* m_pCompatibleTexture;
//ID3D11Device* m_pDevice;
IDXGIAdapter* m_pDXGIAdapter;
IDXGIOutput* m_pDXGIOutput;
IDXGIOutput1* m_pDXGIOutput1;
IDXGIOutputDuplication* m_pOutputDuplication = nullptr;
DXGI_OUTDUPL_DESC m_OutputDuplicationDescription;
DXGI_OUTPUT_DESC m_OutputDescription;
D3D11_MAPPED_SUBRESOURCE m_mappedResource;
HRESULT CreateD3DDevice()
{
HRESULT hResult = S_OK;
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_9_1;
hResult = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr,
0, &featureLevel, (UINT)(1), D3D11_SDK_VERSION, &m_pDevice, 0, &m_pDeviceContext);
return hResult;
}
HRESULT CreateDXGIDevice()
{
return m_pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&m_pDXGIDevice));;
}
HRESULT CreateCompatibleTexture()
{
D3D11_TEXTURE2D_DESC textureDescription;
textureDescription.Width = m_OutputDuplicationDescription.ModeDesc.Width;
textureDescription.Height = m_OutputDuplicationDescription.ModeDesc.Height;
textureDescription.Format = m_OutputDuplicationDescription.ModeDesc.Format;
textureDescription.ArraySize = 1;
textureDescription.BindFlags = 0;
textureDescription.MiscFlags = 0;
textureDescription.SampleDesc.Count = 1;
textureDescription.SampleDesc.Quality = 0;
textureDescription.MipLevels = 1;
textureDescription.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
textureDescription.Usage = D3D11_USAGE_STAGING;
return m_pDevice->CreateTexture2D(&textureDescription, 0, &m_pCompatibleTexture);
}
HRESULT CreateDXGIOutput()
{
return m_pDXGIAdapter->EnumOutputs((UINT)(0), &m_pDXGIOutput);
}
HRESULT DuplicateOutput()
{
return m_pDXGIOutput1->DuplicateOutput(m_pDevice, &m_pOutputDuplication);
}
HRESULT CreateDXGIAdapter()
{
return m_pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&m_pDXGIAdapter));
}
HRESULT CreateDXGIOutput1()
{
return m_pDXGIOutput->QueryInterface(__uuidof(m_pDXGIOutput1), reinterpret_cast<void**>(&m_pDXGIOutput1));
}
HRESULT GetOutputDescription()
{
return m_pDXGIOutput->GetDesc(&m_OutputDescription);
}
HRESULT CaptureScreen()
{
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
IDXGIResource* DesktopResource = nullptr;
HRESULT hResult = m_pOutputDuplication->AcquireNextFrame(9999, &FrameInfo, &DesktopResource);
if (FAILED(hResult))
{
return hResult;
}
hResult = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&m_pDesktopTexture));
DesktopResource->Release();
DesktopResource = nullptr;
if (FAILED(hResult))
{
return hResult;
}
m_pDeviceContext->CopyResource(m_pCompatibleTexture, m_pDesktopTexture);
m_pDeviceContext->Map(m_pCompatibleTexture, D3D11CalcSubresource(0, 0, 0), D3D11_MAP_READ_WRITE, 0, &m_mappedResource);
BYTE* sptr = reinterpret_cast<BYTE*>(m_mappedResource.pData);
m_pDeviceContext->Unmap(m_pCompatibleTexture, 0);
m_pOutputDuplication->ReleaseFrame();
return hResult;
}
int main()
{
HRESULT hr;
hr = CreateD3DDevice();
std::cout << hr << std::endl;
hr = CreateDXGIDevice();
std::cout << hr << std::endl;
hr = CreateDXGIAdapter();
std::cout << hr << std::endl;
hr = CreateDXGIOutput();
std::cout << hr << std::endl;
hr = GetOutputDescription();
std::cout << hr << std::endl;
hr = CreateDXGIOutput1();
std::cout << hr << std::endl;
hr = DuplicateOutput();
std::cout << hr << std::endl;
m_pOutputDuplication->GetDesc(&m_OutputDuplicationDescription);
hr = CaptureScreen();
std::cout << hr << std::endl;
}
HRESULT hr;
IWbemClassObject *pInClass = NULL;
IWbemClassObject *pOutClass = NULL;
IWbemContext *pCtx = 0;
IWbemCallResult *pResult = 0;
BSTR snapshotClassPath = SysAllocString(L"Msvm_VirtualSystemSnapshotService");
hr = m_pWbemServices->GetObject(
snapshotClassPath,
0,
NULL,
&m_pWbemClassObject,
NULL);
if (FAILED(hr))
{
std::cout << "Failed to get class object(Msvm_VirtualSystemSnapshotService). Error code = 0x" << hex << hr << std::endl;
return;
}
// Create snapshot method
BSTR MethodNameOne = SysAllocString(L"CreateSnapshot");
hr = m_pWbemClassObject->GetMethod(
MethodNameOne,
0,
&pInClass,
&pOutClass
);
if (FAILED(hr))
{
std::cout << "Failed to get method(CreateSnapshot). Error code = 0x" << hex << hr << endl;
}
cout << "Succeeded to get method(CreateSnapshot)." << endl;
BSTR virtualSystemSnaphotSettingData = SysAllocString(L"Msvm_VirtualSystemSnapshotSettingData");
// Get the Msvm_VirtualSystemSnapshotSettingData Class object
IWbemClassObject * pvirtualSystemSnaphotSettingData = NULL;
hr = m_pWbemServices->GetObject(
virtualSystemSnaphotSettingData,
0,
pCtx,
&pvirtualSystemSnaphotSettingData,
&pResult
);
if (FAILED(hr))
{
wprintf(L"Error GetObject Msvm_VirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
std::cout << "Succeeded to get object(Msvm_VirtualSystemSnapshotSettingData)." << std::endl;
// Create instance of Msvm_VirtualSystemSnapshotSettingData class
IWbemClassObject * pInpInstOfSnapshotSettingData = NULL;
hr = pvirtualSystemSnaphotSettingData->SpawnInstance(
0,
&pInpInstOfSnapshotSettingData);
if (FAILED(hr))
{
wprintf(L"Error SpawnInstance Msvm_VirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
std::cout << "Succeeded to created instance(Msvm_VirtualSystemSnapshotSettingData )." << std::endl;
// Set the property(Consistency Level)
BSTR memberOneForVirtualSystemSnapshotSettingData = SysAllocString(L"ConsistencyLevel");
VARIANT consistencyLevel;
VariantInit(&consistencyLevel);
V_VT(&consistencyLevel) = VT_BSTR;
V_BSTR(&consistencyLevel) = SysAllocString(L"1");
hr = pInpInstOfSnapshotSettingData->Put(
memberOneForVirtualSystemSnapshotSettingData,
0,
&consistencyLevel,
0);
if (FAILED(hr))
{
wprintf(L"Error memberOneForVirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(ConsistencyLevel), Consistency level:%s\n", consistencyLevel.bstrVal);
VariantClear(&consistencyLevel);
The CreateSnapshot method was called on Windows Hyper-V 2016 and the execution was successful, but the generated virtual machine snapshot was not visible in the Hyper-V GUI.
// Set the property(ElementName)
BSTR memberThreeForVirtualSystemSnapshotSettingData = SysAllocString(L"ElementName");
VARIANT elementName;
VariantInit(&elementName);
V_VT(&elementName) = VT_BSTR;
V_BSTR(&elementName) = SysAllocString(vmName);
hr = pInpInstOfSnapshotSettingData->Put(
memberThreeForVirtualSystemSnapshotSettingData,
0,
&elementName,
0);
if (FAILED(hr))
{
wprintf(L"Failed to set property(ElementName), Erorr code:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(ElementName):%s\n", elementName.bstrVal);
VariantClear(&elementName);
// Set the property(ignore disks that aren't compatible with snapshots)
BSTR memberTwoForVirtualSystemSnapshotSettingData = SysAllocString(L"IgnoreNonSnapshottableDisks");
VARIANT ignoreNonSnapshottableDisks;
ignoreNonSnapshottableDisks.vt = VT_BOOL;
ignoreNonSnapshottableDisks.boolVal = true;
hr = pInpInstOfSnapshotSettingData->Put(
memberTwoForVirtualSystemSnapshotSettingData,
0,
&ignoreNonSnapshottableDisks,
0);
if (FAILED(hr))
{
wprintf(L"Error memberTwoForVirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(IgnoreNonSnapshottableDisks):%d\n", ignoreNonSnapshottableDisks.boolVal);
VariantClear(&ignoreNonSnapshottableDisks);
// Create or update instance
hr = m_pWbemServices->PutInstance(
pInpInstOfSnapshotSettingData,
0,
pCtx,
&pResult);
if (FAILED(hr))
{
wprintf(L"Error PutInstance:0x%08lx\n", hr);
}
wprintf(L"Succeeded to update the instance.\n");
// Get textual rendering of the object in the MOF syntax
BSTR objString = NULL;
hr = pInpInstOfSnapshotSettingData->GetObjectText(0, &objString);
if (FAILED(hr))
{
wprintf(L"Error GetObjectText:0x%08lx\n", hr);
}
wprintf(L"Succeeded to get textual rendering.\n");
BSTR ArgNameTwo = SysAllocString(L"SnapshotSettings");
VARIANT v;
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = objString;
wprintf(L"Object text: %s\n", objString);
// Pass the second Argument to CreateSnapshot method
hr = pInClass->Put(ArgNameTwo, 0, &v, 0);
if (FAILED(hr))
{
wprintf(L"Error ArgNameTwo:0x%08lx\n", hr);
}
VariantClear(&v);
wprintf(L"Succeeded to set property(SnapshotSettings).\n");
// set property(AffectedSystem)
VARIANT vtProp;
m_pWbemClassObject->Get(L"__Path", 0, &vtProp, 0, 0);
hr = pInClass->Put(L"AffectedSystem", 0, &vtProp, NULL);
if (FAILED(hr))
{
std::cout << "Failed to set property(AffectedSystem)." << std::endl;
}
wprintf(L"AffectedSystem: %s\n", vtProp.bstrVal);
VariantClear(&vtProp);
// Pass the Third Argument to CreateSnapshot method
BSTR ArgNameThree = SysAllocString(L"SnapshotType");
VARIANT var;
VariantInit(&var);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(L"32768");
hr = pInClass->Put(ArgNameThree, 0, &var, 0);
if (FAILED(hr))
{
std::cout << "Failed to set property(SnapshotType)." << std::endl;
}
wprintf(L"SnapshotType: %s\n", var.bstrVal);
VariantClear(&var);
// Call the CreateSnapshot method.
IEnumWbemClassObject* pEnumOb1 = NULL;
hr = m_pWbemServices->ExecQuery(
BSTR(L"WQL"),
BSTR(L"SELECT * FROM Msvm_VirtualSystemSnapshotService"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumOb1
);
if (FAILED(hr)) {
std::cout << "SELECT * FROM Msvm_VirtualSystemSnapshotService, Error code:0x%08lx" << hex << hr << endl;
}
std::cout << "Succeeded to query snapshot." << std::endl;
IWbemClassObject *pclsObj1 = NULL;
ULONG uReturn1 = 0;
std::cout << "Create snapshot..." << std::endl;
while (1)
{
HRESULT hr = pEnumOb1->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn1);
if (FAILED(hr) || !uReturn1)
{
break;
}
VARIANT vt;
// Get the value of the path property from Msvm_VirtualSystemSnapshotService Class
hr = pclsObj1->Get(L"__Path", 0, &vt, 0, 0);
if (FAILED(hr))
{
std::wcout << "Failed to get vm's path." << std::endl;
break;
}
wprintf(L"__PATH:%s \n", vt.bstrVal);
//Call the CreateSnapshot method
hr = m_pWbemServices->ExecMethod(
vt.bstrVal,
MethodNameOne,
0,
NULL,
pInClass,
&pOutClass,
NULL);
if (FAILED(hr))
{
wprintf(L"Failed to execute(CreateSnapshot), Erorr code:0x%08lx\n", hr);
break;
}
wprintf(L"Succeeded to create snapshot.\n");
Sleep(10);
pclsObj1->Release();
pclsObj1 = NULL;
}
The return value of ExecMethod() is 0, that is, the call succeeds, but I did not see the snapshot just created on Hyper-V.
I use this PowerShell script and it works. The only problem is to set snapshot name:
function Create-VMSnapshot{
$vm = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Query "select * from msvm_computersystem where elementname='$VMName'"
if($vm -eq $null){
throw "Failed to get VM with display name '$VMName'"
}
$Msvm_VirtualSystemSnapshotService = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Class Msvm_VirtualSystemSnapshotService
if($Msvm_VirtualSystemSnapshotService -eq $null)
{
throw "Failed to get Msvm_VirtualSystemSnapshotService instance"
}
[WMI]$Msvm_VirtualSystemSnapshotSettingData = ([WMIClass]"\\.\root\virtualization\v2:Msvm_VirtualSystemSnapshotSettingData").CreateInstance()
if($Msvm_VirtualSystemSnapshotSettingData -eq $null)
{
throw "Failed to get Msvm_VirtualSystemSnapshotSettingData instance"
}
$Msvm_VirtualSystemSnapshotSettingData.ConsistencyLevel = 1
$Msvm_VirtualSystemSnapshotSettingData.IgnoreNonSnapshottableDisks = $true
$Msvm_VirtualSystemSnapshotSettingData.ElementName = $SnapshotName
$Msvm_VirtualSystemSnapshotSettingData.Description = $SnapshotDescription
$Msvm_VirtualSystemSnapshotSettingData
[System.Management.ManagementBaseObject]$result = $Msvm_VirtualSystemSnapshotService.CreateSnapshot(
$vm,
$Msvm_VirtualSystemSnapshotSettingData.GetText(2),
32768)
[int]$res = Job-Observation -WMIJobResult $result -JobAction "Creating snapshot" -JobProgressCaption "Create snapshot"
$snapshot = (([WMI]$result.Job).GetRelated("Msvm_VirtualSystemSettingData") | % {$_})
$snapshot
}
#include <windows.h>
#include <exdisp.h>
class CWebBrowser{
public:
HRESULT hr;
IWebBrowserApp *www;
HRESULT init(){
CLSID clsid;
const IID IID_IEApplication = {0x0002DF05,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
if(www) hr = www->put_Visible(-1);
if(hr!=0 || www==NULL){
QuitBrowser();
hr=CLSIDFromProgID(L"InternetExplorer.Application",&clsid);
if(hr==0) hr=CoCreateInstance(clsid,NULL,CLSCTX_ALL,IID_IEApplication,reinterpret_cast<void**>(&www));
if(hr==0) hr = www->put_Visible(-1);
}
return hr;
}
HRESULT browse(BSTR addr){
VARIANT vEmpty;
VariantInit(&vEmpty);
hr=www->Navigate(addr, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
VariantClear(&vEmpty);
return hr;
}
void QuitBrowser(){
if(www){
www->Quit();
www->Release();
www=NULL;
}
}
CWebBrowser(){
hr=CoInitialize(NULL);
}
~CWebBrowser(){
if(www){
www->Quit();
www->Release();
www=NULL;
}
CoUninitialize();
}
};
I am calling the init() function to check if Web Browser is still open before browse() another webpage.
When I run the app the first time there are 2 processes showing in Task Manager (iexplorer.exe) & (iexplorer.exe *32)
When I close the app sometimes processes close and sometimes they don't.
Sometimes (iexplorer.exe *32) closes and only (iexplorer.exe) is open. When I try calling init() in this case the app crashes.
Using CodeBlocks 17.12, Windows 2000 & IE 11.
This works fine for me. Maybe you are calling www->Release() prematurely.
Here is my MCVE:
#include <Windows.h>
#include <assert.h>
#include <Exdisp.h>
#include <iostream>
#pragma comment (lib, "SHDOCVW.lib")
IWebBrowserApp *www;
HRESULT init()
{
CLSID clsid;
const IID IID_IEApplication = {0x0002DF05,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
HRESULT hr = CLSIDFromProgID (L"InternetExplorer.Application", &clsid);
if (hr)
{
std::cout << std::hex << "CLSIDFromProgID failed, error " << hr << "\n";
return hr;
}
hr = CoCreateInstance (clsid, NULL, CLSCTX_ALL, IID_IEApplication, reinterpret_cast<void**>(&www));
if (hr)
{
std::cout << std::hex << "CoCreateInstance failed, error " << hr << "\n";
return hr;
}
hr = www->put_Visible(-1);
if (hr)
{
std::cout << std::hex << "put_Visible failed, error " << hr << "\n";
www->Release ();
www = nullptr;
return hr;
}
return S_OK;
}
HRESULT browse(BSTR addr)
{
HRESULT hr;
if (www)
{
VARIANT vEmpty;
VariantInit (&vEmpty);
hr = www->Navigate (addr, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
VariantClear (&vEmpty);
}
return hr;
}
int main ()
{
HRESULT hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
assert (hr == 0);
int mb_result;
while (1)
{
hr = init ();
if (hr == 0)
{
mb_result = MessageBoxW (NULL, L"About to browse", L"Browser Test", MB_OKCANCEL);
if (mb_result == IDOK)
{
BSTR url = SysAllocString (L"https://www.google.com");
hr = browse (url);
SysFreeString (url);
if (hr)
std::cout << "browse () returned: " << std::hex << hr << "\n";
}
mb_result = MessageBoxW (NULL, L"About to quit", L"Browser Test", MB_OKCANCEL);
if (mb_result == IDOK)
www->Quit ();
www->Release ();
www = nullptr;
}
mb_result = MessageBoxW (NULL, L"Again?", L"Browser Test", MB_YESNO);
if (mb_result == IDNO)
break;
}
CoUninitialize ();
}
And if I close the browser (Edge, in my case, running on Windows 10) between the calls to init and browse I get:
browse () returned: 800706ba
which is entirely understandable, since this error means "The RPC server unavailable". It certainly doesn't crash.
Edit
Stupid Vista bugs, see the OP's recent comments. After calling www->Quit() the next call to CoCreateInstance() fails, if you're too quick about it at least.
So, two suggestions.
1 (might work):
for (int i = 0; i < 10; ++i)
{
hr = CoCreateInstance (clsid, NULL, CLSCTX_ALL, IID_IEApplication, reinterpret_cast<void**>(&www));
if (hr != ERROR_SHUTDOWN_IS_SCHEDULED) // not really
break;
Sleep (1000);
}
2 (a bit more drastic, error handling omitted for brevity):
// www->Quit ();
HWND hWnd;
hr = www->get_HWND ((SHANDLE_PTR *) &hWnd);
if (hr == S_OK)
{
DWORD processID;
if (GetWindowThreadProcessId (hWnd, &processID))
{
HANDLE hProcess = OpenProcess (PROCESS_TERMINATE, FALSE, processID);
if (hProcess)
{
TerminateProcess (hProcess, (DWORD) -1);
CloseHandle (hProcess);
}
}
}
Want to give it a try, OP, and report back?
I'm currently working on a "Volume mixer" to control the volume of each program on my PC (Windows 10).
How do I get the volume level of each program/audio session as a scalar from 0 to 100?
As you can see, in the code below, I found the GetPeakValue function, but it returns values like 0.0812654 or 0.021352.
I'm sure that these values are the volume of each audio session in a scalar from 1.0 to 0.0. But what I want is the volume limitation, which you can set in the windows audio mixer for example, and not the current level. So if I set the program volume level to 50%, I want a value like 0.5.
In the second function (getVolume), you'll see that I already got the master volume in a 0-100 scalar, but there the endpoint device has a function for the scalar level already. So I'll need the same function at least, or a calculation, to get such a scalar for every audio session as well.
void getSessions() {
CoInitialize(NULL);
IMMDeviceEnumerator *pDeviceEnumerator = NULL;
IMMDevice *pDevice = NULL;
IAudioSessionManager2 *pAudioSessionManager2 = NULL;
IAudioSessionEnumerator *pAudioSessionEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDeviceEnumerator);
pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void **) &pAudioSessionManager2);
pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);
int nSessionCount;
pAudioSessionEnumerator->GetCount(&nSessionCount);
std::cout << "Session Count: " << nSessionCount << std::endl;
while (true) {
for (int nSessionIndex = 0; nSessionIndex < nSessionCount; nSessionIndex++) {
IAudioSessionControl *pSessionControl = NULL;
if (FAILED(pAudioSessionEnumerator->GetSession(nSessionIndex, &pSessionControl)))
continue;
IAudioMeterInformation *pAudioMeterInformation = NULL;
pSessionControl->QueryInterface(&pAudioMeterInformation);
float fPeak = NULL;
pAudioMeterInformation->GetPeakValue(&fPeak);
std::cout << "fPeak Value: " << fPeak << std::endl;
}
std::cout << "\n\n";
Sleep(1000);
}
CoUninitialize();
}
double getVolume() {
float currentVolume = 0;
CoInitialize(NULL);
IMMDeviceEnumerator *deviceEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
IMMDevice *defaultDevice = NULL;
deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
deviceEnumerator->Release();
deviceEnumerator = NULL;
IAudioEndpointVolume *endpointVolume = NULL;
defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
defaultDevice->Release();
defaultDevice = NULL;
float fLevel;
endpointVolume->GetMasterVolumeLevel(&fLevel);
qDebug() << "FLevel: ";
qDebug() << fLevel;
endpointVolume->GetMasterVolumeLevelScalar(¤tVolume);
endpointVolume->Release();
CoUninitialize();
return (double)(currentVolume * 100);
}
Ok guys, I've found the solution for my problem!
I had to call QueryInterface on the SessionControl to gain access to ISimpleAudioVolume where you can use the functions GetMasterVolume and SetMasterVolume. It's a 0-1 scalar, but you can just multiply it with 100 to get a 0-100 scalar. If the system's master volume is on 50%, you get a output of 1 if the program volume is on 50% too, so the output is based on the system's master volume!
Thanks for every comment and help!
Here the working code:
void getSessions() {
CoInitialize(NULL);
IMMDeviceEnumerator *pDeviceEnumerator;
IMMDevice *pDevice;
IAudioSessionManager2 *pAudioSessionManager2;
IAudioSessionEnumerator *pAudioSessionEnumerator;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDeviceEnumerator);
pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void **) &pAudioSessionManager2);
pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);
int nSessionCount;
pAudioSessionEnumerator->GetCount(&nSessionCount);
while (true) {
for (int nSessionIndex = 0; nSessionIndex < nSessionCount; nSessionIndex++) {
IAudioSessionControl *pSessionControl;
if (FAILED(pAudioSessionEnumerator->GetSession(nSessionIndex, &pSessionControl)))
continue;
ISimpleAudioVolume *pSimpleAudioVolume;
pSessionControl->QueryInterface(&pSimpleAudioVolume);
float fLevel;
pSimpleAudioVolume->GetMasterVolume(&fLevel);
std::cout << "fLevel Value: " << fLevel << std::endl;
}
Sleep(1000);
}
CoUninitialize();
}
I have read most questions like this .But there are still some problems when try get the value of cpu usage in WMI using c++.
I have tried two ways to solve this problem:
query the value of PercentProcessorTime in Win32_PerfFormattedData_PerfOS_Processor.But the value is much bigger than I want . It can reach 10802692. some pieces of my codeļ¼
hres = m_pWbemSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor where Name='_Total' "),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&m_pEnumClsObj
);
hres = m_pWbemClsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);
wcout << "CPU Usage : " << vtProp.ullVal << endl;
VariantClear(&vtProp);
get the some data form Win32_PerfRawData_PerfOS_Processor,then using the formula.However,when I try this method , I always get same value about PercentProcessorTime and TimeStamp_Sys100NS.That is to say N1=N2 and D1=D2.I think there must be some wrong in my code
Formula - (1- ((N2 - N1) / (D2 - D1))) x 100
unsigned __int64 N1;
unsigned __int64 D1;
unsigned __int64 N2;
unsigned __int64 D2;
bool result = false;
if (getCPUData(&N1, &D1))
{
Sleep(1000);
if (getCPUData(&N2, &D2))
{
result = true;
}
}
//(1 - ((N2 - N1) / (D2 - D1))) * 100;
bool WMI_Util::getCPUData(unsigned __int64 *N, unsigned __int64 *D)
{
HRESULT hres;
ULONG uReturn = 0;
VARIANT vtProp;
m_pEnumClsObj = NULL;
bool result = false;
hres = m_pWbemSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_PerfRawData_PerfOS_Processor where Name='_Total' "),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&m_pEnumClsObj
);
if (FAILED(hres))
{
wcout << L"Query for operating system name failed."
<< L" Error code = 0x"
<< hex << hres << endl;
m_pWbemSvc->Release();
m_pWbemLoc->Release();
CoUninitialize();
}
else{
m_pWbemClsObj = NULL;
while (m_pEnumClsObj)
{
hres = m_pEnumClsObj->Next(WBEM_INFINITE, 1, &m_pWbemClsObj, &uReturn);
if (0 == uReturn)
break;
hres = m_pWbemClsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);
*N = vtProp.ullVal;
VariantClear(&vtProp);
hres = m_pWbemClsObj->Get(L"TimeStamp_Sys100NS", 0, &vtProp, 0, 0);
*D = vtProp.ullVal;
VariantClear(&vtProp);
m_pWbemClsObj->Release();
}
result = true;
}
return result;
ReleaseWMI();
}
As for initialization of WMI, I followed the step1-5 in MSDN. Do I need to get the value of them in two different WMI connection? In current situation , I just query the class in two different time .Is this reason why I always get the same value?
My advice is to use 'vtProp.bstrVal' instead of 'vtProp.ullVal'.
I implemented very similar function and as you said got constant values in numeric fields but I got correct value in string field.
Here is my method (without debug printings):
HRESULT WMI_sdk_services::GetCpuUsage(int &cpuUsage)
{
bool shouldUninitializeComAfterWmiRequest; //out parameter
HRESULT hres = PrepareEnumWbemClassObject(true, shouldUninitializeComAfterWmiRequest, L"SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor where Name='_Total'");
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if(SUCCEEDED(hres)){
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
VARIANT vtProp;
// Get the value of the 'PercentProcessorTime' property
hr = pclsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);
if (WBEM_S_NO_ERROR != hr) {
if(pclsObj){
VariantClear(&vtProp);
pclsObj->Release(); pclsObj = NULL;
}
break;
}
cpuUsage = std::stoi(vtProp.bstrVal);
VariantClear(&vtProp);
pclsObj->Release(); pclsObj = NULL;
}
}
return hres;
}
Another remark: You get here total CPU usage not your process CPU usage.