在 C++ 运行时获取当前操作系统
Posted
技术标签:
【中文标题】在 C++ 运行时获取当前操作系统【英文标题】:Get the current operating system during runtime in C++ 【发布时间】:2011-03-05 00:51:09 【问题描述】:我需要弄清楚我的程序在运行时运行的操作系统。
我将 Qt 4.6.2、MinGW 和 Eclipse 与 CDT 一起使用。我的程序将在 Windows 或 Linux 上运行命令行 QProcess。现在我需要一种开关来根据操作系统运行不同的代码。
【问题讨论】:
【参考方案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 Linux
和 I 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。
【讨论】:
不应该是QSysInfo::windowsVersion()
吗?
不,应该是QSysInfo::WindowsVersion
。但是,从 Qt 5.9 开始,这已被弃用。我会立即更新答案。
实际上,它们似乎是相同的 doc.qt.io/qt-5/qsysinfo-obsolete.html#WindowsVersion-var 和 doc.qt.io/qt-5/qsysinfo-obsolete.html#windowsVersion - 是的,它们现在都已弃用
是的,只需使用QSysInfo::productType()
或点赞即可。【参考方案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。 不管是不是初学者的问题,老实说你不能确定,规则是准确回答所问的问题。像我这样的人来这里是为了获得问题标题中的解决方案,而我们发现这是一个离题的问题。令人沮丧。以上是关于在 C++ 运行时获取当前操作系统的主要内容,如果未能解决你的问题,请参考以下文章