question

xinluo-2776 avatar image
0 Votes"
xinluo-2776 asked Castorix31 commented

How to dynamically call/or not call Windows.Graphics.Capture's API based on Windows 10 version

Hi Team,
My Windows C++ desktop application is required to run on all versions of Windows 10 operating systems, and I do want to use Windows.Graphics.Capture APIs to capture other application's window. I Know that Windows.Graphics.Capture is only supported on Windows 10, version 1803 or above. So how to dynamically call/or not call Windows.Graphics.Capture APIs based on Windows 10 version. For example, at the run time, if my application detects that OS is Windows 10 version below 1803, my app will not load the Windows.Graphics.Capture API dll and will not call Windows.Graphics.Capture APIs; if version is 1803 or above, my app will load Windows.Graphics.Capture API dll and call Windows.Graphics.Capture APIs.

Thanks for your help for resolving this issue,

windows-api
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

7777 avatar image
1 Vote"
7777 answered XiaopoYang-MSFT commented

The best place to ask questions on Windows.Graphics.Capture is here: https://github.com/robmikh/Win32CaptureSample/issues/33#issuecomment-774807345

ApiInformation::IsApiContractPresent is the one you need.

· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi XiaopoYang,
Thanks for your response.
Since Windows.Graphics.Capture's API is created by Microsoft Windows API team, so I naturally ask Windows.Graphics.Capture's API related question to your team. I am not quite sure if a team of https://github.com/robmikh/Win32CaptureSample/issues/33#issuecomment-774807345 should be responsible for answering such Windows API question. But anyway, I have posted the same question there as well.

I did try ApiInformation::IsApiContractPresent with Win32CaptureSample on Windows 10, version 1607 machine, but when I ran this app under MSVC2017/2019IDE, I got the following runtime error before reaching main() routine:
The procedure entry point CreateDispatcherQueueController could not located.
Like what I said before, if I ran this app on Windows 10, version 19043, it works great without any errors.

My question is how to configure Visual studio C++ project to not load DLLs of Windows.Graphics.Capture's APIs at runtime if my application detects Windows 10 machine has a version below Win10 1803?
My app needs to be able to run on all versions of Windows 10 machines including Win10 1803, but it would be fine to not call Windows.Graphics.Capture's APIs if Windows version is below 1803.
Here I have attached two screenshots, one is win10 machine version and the other is run time error message.
Hope that this time, you can understand my question better and provide a solution for this runtime error,

0 Votes 0 ·

I haven't found a solution, But in order to not load Windows.Graphics.Capture, You may use Linker support for delay-loaded DLLs Or you need to implement manually by GetOSVersion.

0 Votes 0 ·
xinluo-2776 avatar image
0 Votes"
xinluo-2776 answered

Just added two screenshots here, one is win10 version on my machine, the other is runtime error message when running on Windows 10, version 1607. Thanks for your help again.

137100-win10-version.png137202-error-to-launch.png



win10-version.png (144.5 KiB)
error-to-launch.png (239.1 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Castorix31 avatar image
0 Votes"
Castorix31 answered Castorix31 commented

Maybe you can do a test like this (I cannot test if it fails as I have Windows 10 1909) :

 BOOL bOK = FALSE;
 HMODULE hInst = LoadLibrary(L"CoreMessaging.dll");
 if (hInst)
 {
  FARPROC pFunction = (FARPROC&)pFunction = GetProcAddress(hInst, "CreateDispatcherQueueController");
  if (pFunction)
  {
  static IGraphicsCaptureSessionStatics* pStatics;
  HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Capture_GraphicsCaptureSession).Get(), IID_PPV_ARGS(&pStatics));
  if (SUCCEEDED(hr))
  bOK = TRUE;
  }
 }

At beginning :

 #include <winrt/Windows.Foundation.h>
 #include <winrt/base.h>
 #include <wrl\wrappers\corewrappers.h>  // HString::MakeReference
 using namespace Microsoft::WRL::Wrappers;
 using namespace winrt;
 #include <roapi.h>
 #include <windows.graphics.capture.h>
 using namespace ABI::Windows::Graphics::Capture;
 #pragma comment (lib, "windowsapp")


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks, XiaopoYang and Castorix31 for your reply. Really appreciate!

Here are what I have done:

Once launching my app, will check Windows 10 build number. If OS build number >= 17763 (for Win10 version 1809), I will use/call Windows.Graphics.Capture's APIs.
In the linker option, I use Delayload CoreMessaging.dll with /DELAYLOAD:CoreMessaging.dll.
After making above changes, my app could run on all Windows10 versions. For Windows10 build 17763 or above, my app will call Windows.Graphics.Capture's API to capture an image of other application's window. For Windows 10 build below 17763, my app will Not call Windows.Graphics.Capture's API and will NOT have a functionality to capture an image of other application window.
Just wondering how to capture an image of other application window in Windows10, version lower than 1803.
Is there some other Windows API to do a capture since Windows.Graphics.Capture does not exist on Win10 version lower than 1803?

0 Votes 0 ·

Is there some other Windows API to do a capture since Windows.Graphics.Capture does not exist on Win10 version lower than 1803?

There are other methods like DwmRegisterThumbnail or PrintWindow with PW_RENDERFULLCONTENT


1 Vote 1 ·