c++ win32阻止应用程序在Windows xp上运行

c++ win32 prevent application from running on windows xp

本文关键字:Windows xp 运行 应用程序 win32 c++      更新时间:2023-10-16

我开发了一个使用Vista(或更高版本)API的应用程序,如果应用程序检测到不支持的操作系统,我想添加一个弹出消息。

我想添加一个弹出消息,当用户在windows XP上运行我的应用程序。目前,应用程序只是抛出一个弹出窗口(messageBox),说一些DLL无法加载。

我已经这样定义了windows版本:

 #define _WIN32_WINNT 0x0600

我必须做些什么来防止在低于Vista的版本上运行?当应用程序启动时,我是否必须检查操作系统版本(并向用户显示消息)?

如果您使用的是XP上不可用的api,则需要将应用程序分离为加载器和实际应用程序(或加载器和包含实际应用程序的DLL)。用#define _WIN32WINNT 0x0501编译加载器,以确保它可以在XP上运行并显示弹出窗口。

使用VerifyVersionInfo或GetVersionEx检查版本

为了显示弹出消息,您需要运行可执行文件。这意味着你必须将你的windows版本降低到你想要"支持"的最低版本(支持在这里意味着能够运行,并显示一个弹出框说它不会运行)。这就要求你在链接到相关dll时延迟点,否则它们不会被找到,你仍然会得到你所知道的相同的消息框。

总而言之,这种方法有许多缺点,因为你必须在XP和Vista上构建一个有效的可执行文件。如果您确实需要这个检查,那么您可以让一个可执行文件来执行它,并决定是显示一个弹出消息还是启动您的实际应用程序(在另一个可执行文件中)。

您可以编写一个非常小的包装程序,将_WIN32_WINNT定义为0x0501。然后,该程序可以做一个操作系统检查,要么显示一些漂亮的用户界面(如果它是错误的Windows版本),要么只是悄悄地启动你的其他可执行文件(如果它是一个支持的Windows版本)。

理想情况下,你的分销渠道(网站等)应该在允许用户下载之前检查用户是否支持windows版本。

如果你使用WiX(或MSI直接)来安装你的应用程序,你可以让安装程序处理不支持的操作系统检查

如果强制执行静态编译时行为,就不能期望动态运行时行为。您需要定义XP windows版本,以便您的exe与XP dll链接,然后在运行时,您需要动态更改行为并加载Vista dll并"手动"找到入口点。正如您所预料的那样,这是痛苦且容易出错的。好运。

您可以将_WIN32_WINNT定义为一个较低的值,适合于2000或XP。但是你需要为Vista的api使用显式链接。改变_WIN32_WINNT也会导致缺少仅用于Vista api的类型声明。因此,如果您知道需要哪些api,您可以将_WIN32_WINNT留在0x0600,并为这些api使用显式链接。显然,你也需要一个版本检查来给用户一个有用的信息。

我个人会采取不同的途径来解决这个问题。我会在安装时检查版本并在那里阻止它。这允许您继续使用_WIN32_WINNT 0x0600以及它提供的所有便利。

实际情况是应用程序加载器正在加载dll,您甚至在应用程序启动之前就看到了错误消息。你需要防止这种情况发生。

你可以把你的应用程序放到一个DLL中,然后创建一个存根程序来执行操作系统检查,就像mystic在他的回答中描述的那样。

编辑:

它似乎神秘地删除了他的答案…像这样做:

OSVERSIONINFO OSversion;
OSversion.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
::GetVersionEx(&OSversion);
switch(OSversion.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
   if(OSversion.dwMajorVersion >= 6)
   {
      // Yay, load the DLL and call entry point
   }
default:
      // Show unsupported OS message
}

你可以调用LoadLibrary()来加载你的应用程序DLL,然后调用你定义的任何入口点。

注意这个答案有一个很酷的OS版本号列表

我不知道如何在Visual Studio或其他编译器中做到这一点,但在Borland/CodeGear/Embarcadero ide中,有一个选项可以在编译的可执行文件的PE头中设置最小支持的操作系统版本。如果操作系统加载程序试图运行具有不兼容版本的可执行文件,它将不会运行可执行文件,并将向用户显示关于版本不匹配的错误消息。检查你的编译器/IDE是否有类似的选项。

否则,您必须在运行时通过LoadLibrary()/GetModuleHandle()GetProcAddress()动态加载所需的api,而不是在编译时静态链接到它们。然后,在使用可能不可用的新API函数之前,可以在代码中执行自己的操作系统版本检查。