PdhAddCounter no longer works in Windows 10 with new SDK 10.0.22621.0 - c++

C++, Visual Studio 2019, Windows 10, SDK 10.0.22621.0
As part of my app's log file, I have collected a few bits of information about the user's computer.
I would start the query with:
static PDH_HQUERY cpuQuery;
static PDH_HCOUNTER cpuTotal;
PDH_STATUS status;
status = PdhOpenQuery(NULL, NULL, &cpuQuery);
and then get the bits of information starting with:
status = PdhAddCounter(cpuQuery, L"\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal);
if (status != ERROR_SUCCESS) {
csData += _T("GetCPURAMStatsinThread - status Add Counter Processor Time Error 2 and return *********\n");
log_write(csData);
return -1;
}
I just noticed that I am now getting the error from PdhAddCounter as:
0xC0000BB8 (PDH_CSTATUS_NO_OBJECT) The specified object is not found on the system.
The only thing that I can think of that has changed since this used to work was that I updated to SDK 10.0.22621.0. I believe that it worked with 10.0.17763.0.
I have not been paying attention to these lines in the log file, but when a customer had a problem that had to do with how many cores his CPU had, and how many virtual processors it had, then that is when I realized that these lines have been erroring out.
I have a laptop that had Windows 7, but I upgraded it to Windows 10, and ran the app on that, and it did not error out. So, does this mean an issue with the Windows 10 update, or the SDK update?

Per my comments above with #Tony Lee I used the MS sample code to browse the counters on my local computer. There was a Processor Information selection vs my original Processor under which there was a Processor Time selection. In the choice box below that there was an all instances choice and a _Total choice. When I selected the _Total choice the buffer in the sample code stayed as NULL but if I selected the all instances the buffer filled with:
L"\Processor Information(*)\% Processor Time"
Plugging that string into PdhAddEnglishCounter() worked...
Edit it also worked with PdhAddCounter()
Using Processor instead of Processor Information and (_Total) Instead of (*) used to work in Windows 10. No telling why things have changed at least on some computer.
Ed
EDIT Important note. First is that the new code above also works on the laptop on which the original code worked. Second note is that I just realized that the desktop on which the original code failed is Windows 10 Home whereas the laptop on which the original code worked is Windows 10 Pro. That maybe the difference. Regardless, the new code works on both Home and Pro.
EDIT 2 The new code also ran fine on Windows 11 Home. I also see that my customer in whose log file I noticed the error line was on Windows 11 Home. That would insinuate that the Pro version still works with the legacy (see next comment by Tony Lee) Processor while the Home versions do not work with the legacy Processor but only with the new Processor Information

Related

D3DKMTQueryStatistics not found in d3dkmthk.h

I try to get the gpu usage for a running process programmatically. In previous posts, people refered to D3DKMTQueryStatistics which was part of the d3dkmthk.h header,
but it looks like they removed D3DKMTQueryStatistics in one of the newer windows sdk versions.
I'm using Windows SDK 10, 10.0.19041.0 and its gone.
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/d3dkmthk/nf-d3dkmthk-d3dkmtquerystatistics
C (Windows) - GPU usage (load %)
see the CollectReports method of gfxWindowsPlatform.cpp from Firefox source.
HMODULE gdi32Handle;
PFND3DKMTQS queryD3DKMTStatistics = nullptr;
if ((gdi32Handle = LoadLibrary(TEXT("gdi32.dll"))))
queryD3DKMTStatistics = (PFND3DKMTQS)GetProcAddress(gdi32Handle, "D3DKMTQueryStatistics");

Accessing Max Input Delay with C++ on Windows

I am having trouble obtaining certain data from Windows Performance Counters with C++. I will preface my question by stating that I am new to both C++ and to developing for Windows, but I have spent some time on this issue already so I feel familiar with the concepts I am discussing here.
Question:
How do I use Windows PDH (Performance Data Helper) C++ to obtain Max Input Delay--either per session or per process? Are there certain Performance Counters that are not available outside of perfmon?
Progress so far:
I have used this example to log some Performance Counters successfully, but the ones I want produce the error code 0xC0000BB8: "The specified object is not found on the system." This confuses me because I can access the objects--"User Input Delay per Process" or "User Input Delay per Session"--fine through perfmon. I even went as far as enabling the counter in the registry as outlined in the article I linked in my question, despite being on a build of Windows 10 that should have it enabled by default. I had to make a small change to get the code to compile, but I have changed only the definition of COUNTER_PATH during my testing because, again, the code works as advertised except when it comes to the counter I want to access. Specifically:
Does not compile:
CONST PWSTR COUNTER_PATH = L"\\Processor(0)\\% Processor Time";
Does compile and log:
CONST wchar_t *COUNTER_PATH = L"\\Processor(0)\\% Processor Timee";
OR
CONST PWSTR COUNTER_PATH = const_cast<PWSTR>(TEXT( "\\Processor(0)\\% Processor Time" ));
Compiles, but throws error code 0xC0000BB8 at runtime (This is the Counter I want to access):
CONST PWSTR COUNTER_PATH = const_cast<PWSTR>(TEXT( "\\User Input Delay per Session(1)\\Max Input Delay" ));
The hardcoded session ID of 1 in the string was for troubleshooting purposes, but wildcard (*) and 0 were also used with the same result. The counter path matches that shown in perfmon.
Essentially, all Performance Counters that I have attempted to access with this code--about 5 completely different ones--have successfully logged the data being requested, but the one I want to access continues to be evasive.
I asked this same question on Microsoft Q&A and received the answer:
The Performance Counters in question require administrator privileges to access. All I had to do was run this program in administrator command prompt, and that solved my issue.

Visual Studio C++ : same program using different amounts of RAM under different executable names

This might be a general question, but this problem is really getting me confused.
I have two different C++ applications, compiled with Visual Studio 2012, needing an instance of the same object. I have put a breakpoint before the creation of each object to measure the RAM usage by stepping my programs. The first one takes approximately 2.5 MiB more RAM after creating the object, while the second app is taking 30 MiB!
Both objects are created using a simple call to new with the same parameters. The code behind the constructors is the same.
As a detail: the first project contains much fewer .cpp files than the second one. So I thought it might be a problem of internal fragmentation of the exe. Plus, I've also tried to break BEFORE any code was executed inside the main function, and the memory usage was already much different (6 MiB for the first app, 35 MiB for the second one).
Does anyone have any idea what might be going on?
EDIT : The said object is a DirectX context, with a constructor creating a Direct3D instance and a device. Both the instance AND device are created the same way, but both have different RAM usage between the two apps.
Here is the code for the D3D device creation :
d3d_presentParams = new D3DPRESENT_PARAMETERS; ZeroMemory( d3d_presentParams, sizeof(D3DPRESENT_PARAMETERS) );
d3d_presentParams->Windowed = !window->isFullscreen();
d3d_presentParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
d3d_presentParams->hDeviceWindow = window->getHwnd();
d3d_presentParams->MultiSampleType = antiAlias;
d3d_presentParams->EnableAutoDepthStencil = true;
d3d_presentParams->AutoDepthStencilFormat = D3DFMT_D32F_LOCKABLE;
d3d_presentParams->PresentationInterval = (info.m_vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
{
d3d_presentParams->BackBufferCount = 1;
d3d_presentParams->BackBufferFormat = D3DFMT_A8R8G8B8;
d3d_presentParams->BackBufferWidth = m_viewportSize.x;
d3d_presentParams->BackBufferHeight = m_viewportSize.y;
}
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
window->getHwnd(),
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
d3d_presentParams,
&d3d_device);
EDIT 2 : Problem has been "solved" for now. See the answer below.
Alright, I "solved" it, kind of. You're not going to believe what the problem was.
TL;DR : Renaming the executable lowers the RAM usage from 80 MiB to 28 MiB. It seems that Windows is suspicious of non-verified applications, as I discovered a directory full of logs inside C:/Users/<Me>/AppVerifierLogs/.
It seemed that RAM usage was linked to how many sources files it contained. Thus, I tried copying one of my projects entirely. I had to rename it, because a solution cannot have two projects with the same name... And guess what, memory usage was down to 7.3 MiB at the beginning of main(), instead of 30 MiB previously.
Later, I found out that it was a specific executable name that caused it to use more memory. I simply renamed the .exe file, and the problem was gone. I even tried to rename Firefox's exe by my app's name, and it made it crash.
And finally, I discovered in C:/Users/<me>/AppVerifierLogs/ at least 3000 files named after my application. This immediately made me think about the way Windows tries to verify applications (e.g. in order to see if they're not viruses).
I have no idea where this is coming from, nor how to turn off this verfier, but it's really annoying as a dev to have Windows panicking about an application you're developping, and injecting (possibly useless) stuff inside it.
The fix for now is just to rename the executable. If anyone knows about which application might have access to this "AppVerifierLogs" directory, please mention it, because even Google searches dont't seem to be able to help at this point...

How to fix processor affinity for Qt 5.9 Thread on Windows with Ryzen 7

I have been developing a program for my Master's Thesis with OpenSceneGraph-3.4.0 and GUI from Qt 5.9 (otherwise in Visual Studio 2015 and 2017). At work everything works fine, but now that I have a new Computer at home I tried to get it running.
However, when I call the frame() method for the viewer, I get a Read Access Violation in QtThread.cpp at the setProcessorAffinity(unsigned int cpunum), specifically in the following line:
QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
Here is the complete function (QtThread.cpp is part of OpenThreads of OSG):
// Description: set processor affinity for the thread
//
// Use: public
//
int Thread::setProcessorAffinity(unsigned int cpunum)
{
QtThreadPrivateData* pd = static_cast<QtThreadPrivateData*>(_prvData);
pd->cpunum = cpunum;
if (!pd->isRunning) return 0;
// FIXME:
// Qt doesn't have a platform-independent thread affinity method at present.
// Does it automatically configure threads on different processors, or we have to do it ourselves?
return -1;
}
The viewer in OSG is set to osgViewer::Viewer::SingleThreaded, but if I remove that line I get an error "Cannot make QOpenGLContext current in a different thread" in GraphicsWindowQt.cpp(which is part of OsgQt), so that's probably a dead end.
Edit for clarification
I call frame()on the osgViewer::Viewer object.
In this function, the viewer calls realize() (which is a function of the Viewer class).
In there setUpThreading()is called (which is a function of the Viewer Base class).
This in turn calls OpenThreads::SetProcessorAffinityOfCurrentThread(0)
In there, the following code is executed:
Thread* thread = Thread::CurrentThread();
if (thread)
return thread->setProcessorAffinity(cpunum);
thread (after the first line) has a value 0x00000000fdfdfdfd which looks like an error to me.
In any case, the last call is the one I posted in my original question.
I don't even have an idea of where to start fixing this. I assume, it's some processor related problem. My processor is a Ryzen 7 1700 (at work it's an Intel i7 3770k), so maybe that helps.
Otherwise, at home I'm using Windows 10, wheras at work it's Windows 7.
I'd be thankful for any help at all.
So in the end, it seems to be a problem with OpenThreads (and thus the OpenSceneGraph part, which I can do nothing about). When using cmake for the OpenSceneGraph source, there is an option "BUILD_OPENTHREADS_WITH_QT" that needs to be disabled.
I found the solution in this thread in the OSG forum, so thanks to this guy.

Using "rundll32.exe" to access SpeechUX.dll

Good Day,
I have searched the Internet tirelessly trying to find an example of how to start Windows Speech Training from with in my VB.Net Speech Recognition Application.
I have found a couple examples, which I can not get working to save my life.
One such example is on the Visual Studios Fourms:
HERE
this particular example users the "Process.Start" call to try and start the Speech Training Session. However this does not work for me. Here is the exmaple from that thread:
Process.Start("rundll32.exe", "C:\Windows\system32\speech\speechux\SpeechUX.dll, RunWizard UserTraining")
What happens is I get and error that says:
There was a problem starting
C:\Windows\system32\speech\speechux\SpeechUX.dll
The specified module could not be found
So I tried creating a shortcut (.lnk) file and thought I could access the DLL this way. My short cut kind of does the same thing. In the short cut I call the "rundll32.exe" with parameters:
C:\Windows\System32\rundll32.exe "C:\Windows\system32\speech\speechux\SpeechUX.dll" RunWizard UserTraining
Then in my VB.Net application I use the "Process.Start" and try to run the shortcut.
This also gives me the same error. However the shortcut itself will start the SPeech Training session. Weird?!?
So, I then took it one step further, to see if it has something to do with my VB.Net Application and the "Process.Start" Call.
I created a VBScript, and using "Wscript.Shell" I point to the Shortcut.
Running the VBScript calls the Shortcut and low and behold the Speech Training starts!
Great! But...
when I try to run the VBscript from my VB.net Application, I get that error again.
What the heck is going on here?
Your problem likely is that your program is compiled as 32-bit and your OS is 64-bit, and thus, when you try to access "C:\Windows\System32\Speech\SpeechUX\SpeechUX.dll" from your program, you're really accessing "C:\Windows\SysWOW64\Speech\SpeechUX\SpeechUX.dll" which, as rundll32.exe is reporting doesn't exist.
Compile your program as 64-bit instead or try the pseudo directory %SystemRoot%\sysnative.
Also, instead of rundll32.exe, you may want to just run SpeechUXWiz.exe with an argument.
Eg.
private Process StartSpeechMicrophoneTraining()
{
Process process = new Process();
process.StartInfo.FileName = System.IO.Path.Combine(Environment.SystemDirectory, "speech\\speechux\\SpeechUXWiz.exe");
process.StartInfo.Arguments = "MicTraining";
process.Start();
return process;
}
private Process StartSpeechUserTraining()
{
Process process = new Process();
process.StartInfo.FileName = System.IO.Path.Combine(Environment.SystemDirectory, "speech\\speechux\\SpeechUXWiz.exe");
process.StartInfo.Arguments = "UserTraining";
process.Start();
return process;
}
Hope that helps.
Read more about Windows 32-bit on Windows 64-bit at http://en.wikipedia.org/wiki/WoW64
or your problem specifically at http://en.wikipedia.org/wiki/WoW64#Registry_and_file_system
If you are using a 64bit OS and want to access system32 folder you must use the directory alias name, which is "sysnative".
"C:\windows\sysnative" will allow you access to system32 folder and all it's contents.
Honestly, who decided this at Microsoft is just silly!!