c++ win32阻止应用程序在Windows xp上运行
c++ win32 prevent application from running on windows xp
我开发了一个使用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函数之前,可以在代码中执行自己的操作系统版本检查。
- std::async from std::async in windows xp
- 如何在Visual Studio 2017中编译Windows XP的代码
- 如何构建使用Visual Studio 2017的Windows XP的Winsock2(WS2_32.LIB)应用程序
- WinHttpSendRequest and HTTPS on Windows XP
- 功能本地静态为Windows XP生成故障代码
- SHOpenWithDialog analog for windows XP?
- 如何检查操作系统是否至少是Windows XP SP3
- 使用Visual Studio 2012针对Windows XP构建Boost 1.52库
- 使用 Build Tools 2015 (不带 Visual Studio) 面向 Windows XP
- 有任何替代SHGetKnownFolderPath的Windows XP用户令牌的方案吗
- 当Windows XP(32位,SP3)播放声音时,随机应用程序暂停半秒钟
- 函数从windows XP中的数据包中检索标头目标地址
- GetConsoleScreenBufferInfoEx equivalent for windows XP?
- 如何跟踪Windows 7是否在C ++中以编程方式进入睡眠或休眠状态,就像在Windows XP中所做的那样
- 如何从Windows XP下的程序中知道或更改Windows事件日志的大小
- 带Realtek Alc888的活动耳机插孔(Windows XP)
- 如何使用Visual Studio 2012编译Windows XP
- Visual C 2012 Express Compied Application在Windows XP上不起作用
- 为 Windows XP 编译的应用程序无法在 Windows 7 上运行
- 检测本地化的 Windows XP 安装的系统语言