【问题标题】:Get the current operating system during runtime in C++在 C++ 运行时获取当前操作系统
【发布时间】:2011-03-05 00:51:09
【问题描述】:

我需要弄清楚我的程序在运行时运行的操作系统。

我将 Qt 4.6.2、MinGW 和 Eclipse 与 CDT 一起使用。我的程序将在 Windows 或 Linux 上运行命令行 QProcess。现在我需要一种开关来根据操作系统运行不同的代码。

【问题讨论】:

    标签: c++ qt operating-system


    【解决方案1】:

    实际上操作系统是由 Q_OS_... 宏定义的。只是说。 Q_WS_... 是窗口系统。不完全一样。 (我只是在阅读问题作者所写的内容......“操作系统”。)

    这些声明可以在 qglobal.h 文件中找到。

    Use Q_OS_x with x being one of:
    
     DARWIN   - Darwin OS (synonym for Q_OS_MAC)
     SYMBIAN  - Symbian
     MSDOS    - MS-DOS and Windows
     OS2      - OS/2
     OS2EMX   - XFree86 on OS/2 (not PM)
     WIN32    - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008)
     WINCE    - WinCE (Windows CE 5.0)
     CYGWIN   - Cygwin
     SOLARIS  - Sun Solaris
     HPUX     - HP-UX
     ULTRIX   - DEC Ultrix
     LINUX    - Linux
     FREEBSD  - FreeBSD
     NETBSD   - NetBSD
     OPENBSD  - OpenBSD
     BSDI     - BSD/OS
     IRIX     - SGI Irix
     OSF      - HP Tru64 UNIX
     SCO      - SCO OpenServer 5
     UNIXWARE - UnixWare 7, Open UNIX 8
     AIX      - AIX
     HURD     - GNU Hurd
     DGUX     - DG/UX
     RELIANT  - Reliant UNIX
     DYNIX    - DYNIX/ptx
     QNX      - QNX
     QNX6     - QNX RTP 6.1
     LYNX     - LynxOS
     BSD4     - Any BSD 4.4 system
     UNIX     - Any UNIX BSD/SYSV system
    

    窗口系统定义如下:

    Use Q_WS_x where x is one of:
    
     MACX     - Mac OS X
     MAC9     - Mac OS 9
     QWS      - Qt for Embedded Linux
     WIN32    - Windows
     X11      - X Window System
     S60      - Symbian S60
     PM       - unsupported
     WIN16    - unsupported
    

    使用#ifdef 的主要问题之一是确保如果您在“新”平台上编译(从未在该平台上编译过该软件),那么您希望使用#elif defined(...) 和至少一个#else + #error ...

    #ifdef Q_OS_LINUX
      std::cout << "Linux version";
    #elif defined(Q_OS_CYGWIN)
      std::cout << "Cygwin version";
    #else
    #error "We don't support that version yet..."
    #endif
    

    【讨论】:

    • 不确定为什么这是被接受的答案,因为 OP 询问了 runtime 并且这涵盖了 compilation time
    • @TranslucentCloud,因为当你在编译时已经可以获取信息时,不需要在运行时进行。然后,您可以在正确的#ifdef 块内执行您需要执行的任何操作。
    • 那么您要说明的是,绝对没有必要确定实际启动代码的机器的特定于操作系统的详细信息?想象一个简单的工具,用于向用户显示有关其操作系统和环境的所有可用信息。并为我提供一个示例,说明如何使用Qt#ifdef 指令来实现这一点。至少对于 CPU 架构而言。
    • @TranslucentCloud 正如您所指出的,QSysInfo() 可以获取一些运行时详细信息。但我不认为问题是关于在 MS-Windows 或 Linux 下运行完全相同的二进制文件,我也不确定 Kai Waltz 是否有兴趣了解使用的处理器或可用的内存量。但有时能够为一种操作系统或另一种操作系统提供专门的代码。
    • 事实是,问题正是关于“在 MS-Windows 或 Linux 下运行 <...> 二进制文件”,这里引用:My program shall run a command-line QProcess on Windows or LinuxI need a kind of switch to run the different code depending on the operating system。当然,OP 只对操作系统感兴趣,而不是 CPU 架构。我仅将 CPU 架构用作可在运行时确定的可行示例。
    【解决方案2】:

    从 Qt 5.9 开始,QSysInfo 的一些方法已经被贬低,例如QSysInfo::windowsVersion()

    从 Qt 5.9 开始,此类功能的替代类是 QOperatingSystemVersion

    例子

    bool onWindows = ( QOperatingSystemVersion::Windows == QOperatingSystemVersion::currentType() );
    

    【讨论】:

    • 请注意,对于 Qt 无法确定版本号 (see) 的任何操作系统类型,这将返回 QOperatingSystemVersion::Unknown,包括所有Linux。相比之下,QSysInfo::productType() 也可以返回 Linux 发行版名称,例如 ubuntu (see)。
    【解决方案3】:

    运行时QGuiApplication::platformName()

    这样可以更准确地区分,例如“eglfs”或“directfb”

    【讨论】:

    • +1 就提到 Qt4 的Q_WS_XXX 的其他答案而言,这是一个很好的 run-time 解决方案来确定 GUI - 如果它是这样的应用程序 - on Qt5.
    【解决方案4】:

    当您的应用在您的开发机器上编译时,这些答案中的大多数都提供了在编译时确定所需信息的解决方案。

    这是您在运行时期间获取所需信息的方法,此时您的应用由您的应用的用户在他们的机器上运行。

    qDebug() << "currentCpuArchitecture():" << QSysInfo::currentCpuArchitecture();
    qDebug() << "productType():" << QSysInfo::productType();
    qDebug() << "productVersion():" << QSysInfo::productVersion();
    qDebug() << "prettyProductName():" << QSysInfo::prettyProductName();
    

    典型结果:

    21:43:09.855 Debug: currentCpuArchitecture(): "x86_64"
    21:43:09.855 Debug: productType(): "windows"
    21:43:09.855 Debug: productVersion(): "10"
    21:43:09.855 Debug: prettyProductName(): "Windows 10 (10.0)"
    

    QSysInfo 的文档是 here

    【讨论】:

    【解决方案5】:

    在 Qt 中,为编译时选项定义了以下 OS 宏

    // Qt5 之前 Qt/X11 = Q_WS_X11 已定义。
    Qt/Windows = Q_WS_WIN 已定义。
    Qt/Mac OS X = Q_WS_MACX 已定义

    // 对于 Qt5 及更高版本 Qt/X11 = Q_OS_X11 已定义。
    Qt/Windows = Q_OS_WIN 已定义。
    Qt/Mac OS X = Q_OS_MACX 已定义

    然后QSysInfo 类在运行时为您提供操作系统版本和其他选项。

    【讨论】:

    • QT 特定的宏。我喜欢。 +1
    • 好的,但是我必须根据操作系统提供不同的版本?
    • @walle:是的,当然。这不是一件坏事。
    • 你应该为每个目标编译,所以完全没有问题。
    • @walle - 是的,没有像 python/java/c# 这样的运行时系统,每个操作系统的可执行格式都不同。 Qt 只是让您为每个编写相同的源文件。您通常还需要在每个平台上使用不同的安装程序
    【解决方案6】:

    由于 Qt5 宏 Q_WS_* 没有定义!

    您应该改用 Q_OS_* 宏:

    Q_OS_AIX
    Q_OS_ANDROID
    Q_OS_BSD4
    Q_OS_BSDI
    Q_OS_CYGWIN
    Q_OS_DARWIN - Darwin-based OS such as OS X and iOS, including any open source version(s) of Darwin.
    Q_OS_DGUX
    Q_OS_DYNIX
    Q_OS_FREEBSD
    Q_OS_HPUX
    Q_OS_HURD
    Q_OS_IOS
    Q_OS_IRIX
    Q_OS_LINUX
    Q_OS_LYNX
    Q_OS_MAC - Darwin-based OS distributed by Apple, which currently includes OS X and iOS, but not the open source version.
    Q_OS_NETBSD
    Q_OS_OPENBSD
    Q_OS_OSF
    Q_OS_OSX
    Q_OS_QNX
    Q_OS_RELIANT
    Q_OS_SCO
    Q_OS_SOLARIS
    Q_OS_ULTRIX
    Q_OS_UNIX
    Q_OS_UNIXWARE
    Q_OS_WIN32 - 32-bit and 64-bit versions of Windows (not on Windows CE).
    Q_OS_WIN64
    Q_OS_WIN - all supported versions of Windows. That is, if Q_OS_WIN32, Q_OS_WIN64 or Q_OS_WINCE is defined.
    Q_OS_WINCE
    Q_OS_WINPHONE
    Q_OS_WINRT
    

    QtGlobal文档中的更多详细信息

    【讨论】:

      【解决方案7】:

      Qt 提供QSysInfo,如果你真的需要在运行时解决这个问题。对于附加到崩溃报告很有用,但对于其他任何尝试在编译时执行的操作。

      【讨论】:

        【解决方案8】:

        这通常使用预编译器指令来控制构建中包含/排除的代码块。

        #ifdef WIN32
          // ...
        #endif
        

        这导致(可以说)更丑陋的代码,但有针对性的二进制文件。

        【讨论】:

          【解决方案9】:

          在编译时使用#ifdef 进行。

          windows下,定义WIN32。

          所以,做:

          #ifdef WIN32
          // Windows code here
          #else
          // UNIX code here
          #endif
          

          【讨论】:

          • 问题明确指定运行时。 -1.
          • @TranslucentCloud:在运行时几乎没有理由这样做——无论如何你都会重新编译。此外,接受的答案也是运行时——只是对你隐藏它。
          • 1. OP明确询问运行时。 2. 如果你想知道确切的操作系统版本,或者说,CPU 架构,在运行时这样做是有原因的。例如,请参阅我的回答,它说明了为什么在某些情况下不应在编译时定义这些内容。
          • @TranslucentCloud:很明显 OP 实际上并不关心,这是一个初学者问题,很可能他们根本不知道您可以在编译时做到这一点和/或滥用术语。感谢您的回答,欢迎来到 SO。
          • 不管是不是初学者的问题,老实说你不能确定,规则是准确回答所问的问题。像我这样的人来这里是为了获得问题标题中的解决方案,而我们发现这是一个离题的问题。令人沮丧。
          猜你喜欢
          • 2018-12-07
          • 2018-03-14
          • 1970-01-01
          • 2017-09-15
          • 2010-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多