【问题标题】:c++ win32 prevent application from running on windows xpc++ win32阻止应用程序在windows xp上运行
【发布时间】:2011-11-28 15:07:45
【问题描述】:

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

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

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

 #define _WIN32_WINNT 0x0600

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

【问题讨论】:

  • 如果你不喜欢系统默认的弹出消息,那么你需要自己编写。执行操作系统检查,如果不是您喜欢的,请提供您的自定义消息。
  • 系统默认弹出消息?我得到的只是无法识别的 DLL

标签: c++ windows winapi


【解决方案1】:

为了显示弹出消息,您需要运行可执行文件。这意味着您必须将您的 Windows 版本降低到您打算“支持”的最低版本(这里的支持意味着能够运行,并显示一个弹出窗口说它不会运行)。如果您链接到相关的 DLL,这将需要您延迟这一点,否则将找不到它们,您仍然会看到您知道的相同消息框。

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

【讨论】:

    【解决方案2】:

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

    理想情况下,您的分发渠道(网站等)会在允许用户下载之前检查用户是否拥有受支持的 Windows 版本。

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

    【讨论】:

    • 这里有很好的建议。包装应用程序的一个可能缺点是,启动该应用程序并希望等待它完成的其他进程可能会被包装应用程序伪造。显然,您可以让包装应用程序闲置,但它可能会变得有点不整洁。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      使用VerifyVersionInfoGetVersionEx检查版本

      【讨论】:

        【解决方案5】:

        您可以将_WIN32_WINNT 定义为较低的值,适用于2000 或XP。但是,您将需要对仅限 Vista 的 API 使用显式链接。更改_WIN32_WINNT 也会导致缺少仅适用于Vista 的API 的类型声明。因此,如果您知道需要哪些 API,您可以将 _WIN32_WINNT 留在 0x0600 并为这些 API 使用显式链接。显然,您还需要进行版本检查才能向用户提供有用的信息。

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

        【讨论】:

        • 我要把它放在安装程序中。只是想知道是否有其他方法可以做到这一点
        【解决方案6】:

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

        您可以将您的应用程序放入 DLL 并创建一个存根程序来执行操作系统检查,就像 Mystical 在他的回答中描述的那样。

        编辑:

        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 有一个很酷的操作系统版本号列表。

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-10-08
            • 1970-01-01
            • 1970-01-01
            • 2013-05-03
            • 1970-01-01
            • 2011-03-21
            相关资源
            最近更新 更多