I'm working on a Win32 application and am currently trying to implement multi-display features. For this, I want to use EnumDisplayMonitors, a feature that is only present in Windows 2000-upwards. I've done my best to maintain backwards compatibility up to Windows 95 thus far.
I want to, therefore, ignore this related section of code when the program runs on older versions of Windows. However, its mere presence anywhere in the code, even if it's not executed, crashes the program. I want to use #ifdef to ignore this section of code, however I can't seem to figure out a way to get the current Windows version from the Preprocessor. I've seen suggestions to use WINVER or _WIN32_WINNT but both need to be set by me as far as I can understand, defeating the whole point. Any attempts to use them predictably did not work as intended.
Is there a way to get the current version of Windows from the preprocessor? If not, is there another way to disable this function completely depending on the OS? Again, regardless whether it's used, its mere presence crashes on Windows 95.
The correct way to handle this is not with the preprocessor at all. You need to use the Win32 API GetProcAddress() function at runtime instead, eg:
typedef BOOL (WINAPI *LPFN_EDM)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
LPFN_EDM lpEnumDisplayMonitors = (LPFN_EDM) GetProcAddress(GetModuleHandle("user32.dll"), "EnumDisplayMonitors");
if (lpEnumDisplayMonitors)
{
// use lpEnumDisplayMonitors as needed...
}
else
{
// use something else...
}
This is even described in Microsoft's documentation:
Operating System Version
Identifying the current operating system is usually not the best way to determine whether a particular operating system feature is present. This is because the operating system may have had new features added in a redistributable DLL. Rather than using the Version API Helper functions to determine the operating system platform or version number, test for the presence of the feature itself.
To determine the best way to test for a feature, refer to the documentation for the feature of interest. The following list discusses some common techniques for feature detection:
You can test for the presence of the functions associated with a feature. To test for the presence of a function in a system DLL, call the LoadLibrary function to load the DLL. Then call the GetProcAddress function to determine whether the function of interest is present in the DLL. Use the pointer returned by GetProcAddress to call the function. Note that even if the function is present, it may be a stub that just returns an error code such as ERROR_CALL_NOT_IMPLEMENTED.
You can determine the presence of some features by using the GetSystemMetrics function. For example, you can detect multiple display monitors by calling GetSystemMetrics(SM_CMONITORS). There are several versions of the redistributable DLLs that implement shell and common control features. For information about determining which versions are present on the system your application is running on, see the topic Shell and Common Controls Versions.
If your compiler toolchain supports Delay Loading, then you can use that instead of calling GetProcAddress() manually. Set your project to delay-load user32.dll and then call EnumDisplayMonitors() normally after first validating the OS supports what you need, such as checking if Windows is Win2K or later via GetVersionEx(), or checking if multiple monitors are installed, eg:
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
if (osvi.dwMajorVersion >= 5) // Win2K = 5.0
{
// use EnumDisplayMonitors as needed...
}
else
{
// use something else...
}
if (GetSystemMetrics(SM_CMONITORS) > 1)
{
// use EnumDisplayMonitors as needed...
}
else
{
// use something else...
}
Compile targeting the lowest Windows you support with WINVER/_WIN32_WINNT (whatever your SDK supports), then load whatever functions you need dynamically at runtime (LoadLibrary etc.) after knowing where you are actually running.
Related
I want to use some Windows API functions specific to the latest Windows 10 versions. E.g. functions like CreatePseudoConsole() supporting Windows Pseudo Console (ConPTY) were introduced only in Windows 10 version 1809 (the fall update of Windows 10 released in 2018).
The classic approach is to load Windows kernel dynamic library where the needed functions are implemented (using LoadLibrary() function) and to check every needed function via GetProcAddress() call.
The newer approach introduced in Visual C++ 6.0 is called Delay Loading.
Is there any modern (simple, clear, and transparent) way to check what parts of Windows API are available for a running application? Or is it a way to check what is an exact Windows 10 version an application is running on? I want to use functions like CreatePseudoConsole() only if they are available (if they are not available some other code should be executed).
GetProcAddress() is the only way to do what you are asking for. Definitely DO NOT rely on detecting the OS version (in recent Windows versions, it gets increasingly more difficult to do that reliably), DO rely on whether the desired function(s) actually exist instead.
Even a linker's delay-load feature uses GetProcAddress() internally. In this case, you can use a delay-load notification hook to determine the result of the load so you can flag your code accordingly for later checks, or even supply a pointer to an alternative fallback function if needed.
This last part is important, because a delay-loaded function is not loaded until it is called for the first time, so if you call a delay-loaded function that does not exist at runtime, and a notification hook does not provide an alternative function, your code will likely crash trying to execute a function via a NULL pointer. To avoid that, you can just call GetProcAddress() explicitly before making any calls to the function.
If the API belongs to an API set, it's recommended to use IsApiSetImplemented instead of GetProcAddress().
The traditional approach for testing whether a Win32 API is available is to use LoadLibrary or GetProcAddress. However, these are not a reliable means for testing API sets because of the reverse forwarding support in Windows 10.
To identify whether a particular Win32 API belongs to an API set, review the requirements table in the reference documentation for the API.
I'm using Visual C++ and Windows API.
On MSDN, each function's description page has a requirements section that shows minimum supported client (as in the example below; CreateFile function).
Do I have to manually check each Win32 function in my program in order to determine the minimum supported client or is there an automatic way?
Ideally you would actually test your program on the versions of Windows your program supports. If you link directly to a function that does not exist then Windows will display an error message and the program will not run at all.
As mentioned in the comments, you cannot fully trust version information on MSDN. CreateFile has existed since Windows 95/Win32S/NT3.x but only CreateFileA actually worked on non-NT systems, CreateFileW just fails with a "not implemented" error code. If your minimum target is Windows XP or higher then you don't have to worry about the 9x/NT split but you should still test your software to make sure.
You also need to be careful if you change WINVER because it can change the size of some structures and then be rejected by certain functions on older Windows versions.
How I can get a list with openGl extensions that I am used in my program at runtime in C++. Clarifying, I don't want extensions available in my platform, I don't want extensions I can execute, I want a list of extensions I am using in my code. This is to check if this extensions are availables before start the execution. I am looking GLEW but GLEW is for
determining which OpenGL extensions are supported on the target platform.
And what I want is a way to get what extensions I am using. If anyone knows not runtime way please tell me because maybe is useful too.
Also, I want tho know how to determine minimum opengl version to use.
Actually the standard way to handle extensions is in-situ: test for availability before trying to call it.
if (GLEW_ARB_vertex_program)
{
... // Do something with ARB_vertex_program
}
More complexes OpenGl programs will perform tests on several extensions availability and make decision from that:
if (GLEW_ARB_vertex_array_object && other stuff)
{
renderingTechnic = VERTEX;
}
else
{
renderingTechnic = BEGIN_END;
}
... etc
If you want the list of actually used extension it's become tricky.
You have to detect cases like this:
if (GLEW_ARB_vertex_program && 0) // YOU SHALL NOT PASS
{
... // Do something with ARB_vertex_program
}
In this case, you will never enter in the then-statement but your tool may have difficulty to detect it.
Code coverage tools are here to perform this kind of job, but embed ones to perform the comparison with available extension at runtime is not an option here.
Take a look in the symbol table of your output is neither a solution:
The one for you exe will contain none of OpenGl functions.
The one for the OpenGl library will contain all of possible (not available nether used) functions.
If your codebase is anything but humongous, you can simply do this with a bit of searching for "gl_EXT_", "gl_ARB_", etc. and manual inspection and a dash of discipline afterwards to try and document all the extensions you use.
For minimum version; again, this is something pretty basic that you need to know already when writing the code. But here I think using GLEW can help you. If memory serves, GLEW uses preprocessor macros that you can define to set the version of OpenGL standard you are expecting. You start by setting this to a low value (e.g. 1.1) and see if your code compiles and runs. If it does, that's probably the minimum version you need. If it doesn't, you increment the version and try again.
The usual approach is to decide which extensions you're going to use before you're starting the actual coding. And if you change it later on, you immediately put the availability tests somewhere close to initialization so that you can either terminate with a runtime error message or fall back to an alternate code path.
Of course the preferred way is to not use extensions at all and stick to a plain OpenGL version profile. Yes, anything after OpenGL-1.2 is loaded through the extension mechanism, but that doesn't make it extensions. So if you know you absolutely need OpenGL-3.0 for your program to work, but nothing else then you can just test for that and be done.
maybe stupid question, but i dont know answer. What is difference between using GetModuleHandle or LoadLibrary to load dll(and then to use function of that dll) and to include directly desired header. For example, with using GetModuleHandle:
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
// Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
PGNSI pGNSI;
SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO));
pGNSI = (PGNSI) GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")),
"GetNativeSystemInfo");
if(NULL != pGNSI)
pGNSI(&si); //calling function through pointer
else GetSystemInfo(&si);
But I can include windows.h header to directly call that function from my code:
#include <windows.h>
SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO));
GetNativeSystemInfo(&si);
The same applies for example to opengl32.dll, i dont know if it is better to include header file for opengl functions in my project or to use Getmodulehandle and GetProcAdress to invoke desired functions. What is the difference? Is first method with using getmodulehandle benefit in some way? Thanks for answers.
First, make sure you understand that GetModuleHandle and LoadLibrary are not exactly equivalent. But since that's not directly part of your question, I'll leave off a big explanation and just suggest you make sure to understand the documentation in those two links.
To use a dll function directly as if it were like any other function, you don't just include the header. In addition to the header, somewhere in your project it is being told to link against a corresponding lib file. In your example, it would be kernel32.lib. This might be done through various means, such as linker settings in the project or having a #pragma comment (lib, ...) in a file.
When a program is built like that, code is written by the compiler to load that dll when the program starts. If the dll in question cannot be found when you actually try to run the program, then it will fail with an error message. You have no way to write code to catch the failure and take some alternative action.
For dlls that are part of the operating system (like kernel32.dll) or at least typically supplied with it, this immediate loading behavior isn't an issue since you can safely assume the dll will always be there. On the other hand, if you were to build against a dll which is not typically present, then you would have more of a concern. Either you would have to make sure such a dll is distributed with your program or else somehow try to make sure the user installs whatever other package is necessary to get that dll on their system.
Also, if the dll loads but any of the functions you're trying to use from that dll don't actually exist in it, then it will immediately fail with an error message. (It doesn't wait until your program tries to call the function. It finds this discrepancy when the program starts and aborts then.) This can be an issue if different versions of the dll exist out in the world.
Now, when you use LoadLibrary/GetProcAddress, you are asking for the dll to be loaded at the time of your choosing and asking to find a particular function provided by that dll. If either of those steps fails, you have the ability to write code to deal with it in some reasonable manner.
This can be used for various purposes. For instance, you could make a plugin mechanism where the program searches for and loads plugin dlls from some particular folder on the fly. Since the program doesn't know ahead of time which plugins will be present, LoadLibrary is the only way to do this.
Another thing LoadLibrary/GetProcAddress can be used for is to load a dll and call a function from it even when you don't have the proper header and lib files. If you know the name of the dll, the name of the function, and exact signature of the function (parameter types, return type, calling convention) then you have enough to write the code to load that dll and call the function successfully. Occasionally this can be useful. For instance, it's one way that people are able to use certain "undocumented" functions provided by Windows dlls.
Lastly, LoadLibrary/GetModuleHandle/GetProcAddress can be used to let you use functionality that doesn't necessarily exist on all the operating systems you want to support. This appears to be the reason for the code snippet you have that calls either GetNativeSystemInfo or GetSystemInfo. The former is only available from WinXP/2003 on up while the latter is available on Win2000. If the code had just been written as a direct call to GetNativeSystemInfo, then the program would fail to run on Windows 2000. But instead, what you have there checks to see if GetNativeSystemInfo exists on the current operation system and only uses it if so, otherwise it falls back on the more widely supported GetSystemInfo.
So in the case of your example, which technique you choose to call that function depends on which operating systems you intend to support. If your software does not need to run on Windows 2000, then just directly calling GetNativeSystemInfo is a lot easier (and most likely the preferable way to go).
Some functions don't exist in older versions of Windows and when you call a function directly, that function ends up in the import table of your program. If Windows fails to find one of the functions in the import table, the program will not run at all.
In your specific example, GetNativeSystemInfo was added in Windows XP and if you call it directly then your program will not run on Windows 2000 or older.
LoadLibrary is also useful if you want to support 3rd-party plug-ins etc.
GetModuleHandle enables you to load dlls dynamically, what can be used for instance for implementing plug-ins or loading some resources on-demand.
Underneath, there is no difference between the two methods -- static library that you link just contains code that does dynamic linking when program starts (in C).
It depends, in this case I'd say its being used so that the dll/exe won't get loading errors from the windows LDR if the system(kernel32.dll etc) doesn't have exports that the binary might use, onr good example of this is the DEP functions for windows XP, which only exist in SP 2+, but its not a good idea to force a required SP, as it can cut down on the avaiable audience for the program.
OpenGL uses the same sorta principle, due to the fact one can't predict the API support (and extensions), so one must check for it, then import it or an alternative with wglGetProcAddress
Another reason, which is more 'cheap' is so that one doesn't not have to link to certain libs and include certain headers, especially if your using say only 1 function from a very large SDK, this prevents other developers wasting time tring to get the huge SDK(they ofc will need the binary contianing the export)
LoadLibrary and GetModulehandle both will work for the same stuff i.e; they will map the module on to the process at run time but in case of LoadLibrary it increases the reference count in the kernel perspective where as the later will not do so..
I am new to Windows programming and I'm trying to discover the best way to check for the existence of Windows Shell API functions. I want to use some of the new taskbar features in Windows7.
https://msdn.microsoft.com/en-us/library/dd378460%28VS.85%29.aspx#custom_jump_lists
But I still want my program to be usable by previous versions of Windows. Is there an easy way to know if the functions are available to be called in the end users system. I'm programming in C++.
It depends on the kinds of the functions.
For plain (non-COM) functions, the only way is to use LoadLibrary and GetProcAddress. If either fails, you know the OS is missing that function. Writing those function pointer type declarations for function pointers duplicating existing function signatures can be tedious, though in VC++2010 you can use decltype for that. For example:
HMODULE user32 = LoadLibraryW(L"user32");
if (user32 != NULL)
{
auto messageBoxW = reinterpret_cast<decltype(MessageBoxW)*>(GetProcAddress(user32, "MessageBoxW"));
if (messageBoxW != NULL)
{
messageBoxW(HWND_DESKTOP, L"Hello!", NULL, MB_OK);
}
}
However, many Shell APIs are exposed via COM components and interfaces. Those cases are different. Sometimes you need to deal with entirely new components; e.g. IApplicationDestinations is a new interface in Win7, and the coclass that implements it is also new. In those cases, you can just do CoCreateInstance, and check the return value for REGDB_E_CLASSNOTREG - this means that such coclass isn't registered on the system (and, effectively, isn't supported).
Sometimes, however, new OS versions introduce new interfaces on existing coclasses. An example is ITaskbarList3, new in Win7, but provided on existing coclass that implements ITaskbarList and dates back to Win95. In those cases, you should first instantiate the coclass for the most basic interface, and then use QueryInterface to obtain new interface versions, and detect that they're not supported by checking return value for E_NOINTERFACE.
I believe MSDN is your best bet for this. Every MSDN page for a function's documentation contains a section in the end which states that which version of Windows support this function.
As an example, Check the doumentation of GetModuleHandle. This contains a section named Requirements under which there is a field Minimum Supported Client and Minimum Supported Server.
However, if you want to check for the existence of functions dynamically, then you can do this through LoadLibrary and GetProcAddress.
I disagree with the currrent solutions. You'll end up with quite a bit of unreadable code.
A nicer alternative is to wrap the functionality in a custom Windows 7-only DLL. For other systems, provide another version of the DLL that implements the same functions. This can often be a no-op. E.g. a function to set the taskbar extensions would be a no-op on older Windows versions.
The dynamic switching between these DLLs is done by using the delay-load feature of MSVC. You can use a custom hook in your EXE to pick the correct DLL version when the first function in your DLL is called, at which time you know whether you're running on Windows 7.
you should use LoadLibrary and GetProcAddress to dynamically load and invoke the new functionality.
Yes you can always check for the existence of function within a library at runtime and take suitable actions.
Check the LoadLibrary and GetProcAddress APIs.
http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx
If you want to find out at compile time so as to get a build break if the function is not available on the OS you are targetting (eg Win 95), then you can define some macros, documented here:NTDDI_VERSION, _WIN32_WINNT, WINVER.
If you want your app to work fine when the functionality is not available (eg JumpLists on OSes older than Win7), then you should do combination of LoadLibrary/GetProcAddress to figure out whether the function you are looking for is available.
Use LoadLibarary to get library handle and GerProcAddress to get pointer to a function. For those functions that are not supported by current OS you will get ERROR_CALL_NOT_IMPLEMENTED error from GetLastError.