我开发了一个使用Vista(或更高版本)API的应用程序,如果应用程序检测到不支持的操作系统,我想添加弹出消息。
当用户在Windows XP上运行我的应用程序时,我想添加一条弹出消息。目前应用程序只是抛出一个弹出窗口(messageBox),说无法加载某些DLL。
我已经定义了这样的Windows版本:
#define _WIN32_WINNT 0x0600
如何防止在低于Vista的版本上运行,我该怎么做?我是否必须在应用程序启动时检查操作系统版本(并向用户显示消息)?
答案 0 :(得分:3)
为了显示弹出消息,您需要运行可执行文件。这意味着您必须将Windows版本降低到您打算“支持”的最低版本(此处支持意味着能够运行,并显示弹出窗口表示它不会运行)。如果您链接到相关的DLL,这将要求您延迟这一点,否则它们将无法找到,您仍然会得到您知道的相同消息框。
总而言之,这种方法存在许多缺点,因为您必须在XP和Vista上构建有效的可执行文件。如果你真的需要这个检查,那么你可以让一个可执行文件执行它并决定是显示弹出消息还是启动你的实际应用程序(在不同的可执行文件中)。
答案 1 :(得分:3)
如果您使用的是XP上没有的API,则需要将应用程序分为加载程序和真实应用程序(或包含实际应用程序的加载程序和DLL)。使用#define _WIN32WINNT 0x0501
编译加载程序以确保它可以在XP上运行并显示弹出窗口。
答案 2 :(得分:2)
您可以编写一个非常小的包装器应用程序,将_WIN32_WINNT定义为0x0501。然后该程序可以进行操作系统检查,并为您的用户显示一些不错的UI(如果它是Windows的错误版本),或者只是静静地启动您的其他可执行文件(如果它是受支持的Windows版本)。
理想情况下,您的分发渠道(网站等)会在允许用户下载之前检查用户是否拥有受支持的Windows版本。
如果您使用WiX(或MSI直接)安装您的应用程序,您可以让安装程序处理不受支持的操作系统检查。
答案 3 :(得分:1)
如果强制执行静态编译时行为,则无法期望动态运行时行为。您需要定义XP Windows版本,以便您的exe链接到XP DLL,然后在运行时,您需要动态更改行为并加载Vista DLL并“手动”找到入口点。正如您所料,这是痛苦和容易出错的。祝你好运。
答案 4 :(得分:1)
您可以将_WIN32_WINNT
定义为较低的值,适用于2000或XP。但是,您将需要为仅Vista的API使用显式链接。更改_WIN32_WINNT
也会导致仅Vista的API缺少类型声明。因此,如果您知道需要哪些API,可以将_WIN32_WINNT
保留在0x0600
,并为这些API使用显式链接。显然,您也需要进行版本检查,以便向用户提供有用的信息。
我个人会采取不同的方法来解决这个问题。我会在安装时检查版本并在那里阻止它。这使您可以继续_WIN32_WINNT 0x0600
以及提供的所有便利。
答案 5 :(得分:1)
正在发生的事情是应用程序加载器正在加载DLL,并且您在应用程序启动之前就会看到错误消息。你需要防止这种情况发生。
您可以将应用程序放入DLL中,并创建一个存根程序,执行操作系统检查,如Mystical在其答案中所述。
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,然后调用您定义的任何入口点。
注意this answer有一个很酷的操作系统版本号列表。
答案 6 :(得分:0)
我不知道如何在Visual Studio或其他编译器中执行此操作,但在Borland / CodeGear / Embarcadero IDE中,可以选择在已编译的可执行文件的PE头中设置支持的最低操作系统版本。如果OS加载程序尝试运行具有不兼容版本的可执行文件,则它将不会运行可执行文件,并将向用户显示有关版本不匹配的错误消息。检查您的编译器/ IDE是否有类似的选项。
否则,您必须在运行时通过LoadLibrary()
/ GetModuleHandle()
和GetProcAddress()
动态加载所需的API,而不是在编译时静态链接到它们。然后,您可以在使用可能无法使用的较新API函数之前,在代码中执行自己的操作系统版本检查。