【问题标题】:Determine OS during runtime在运行时确定操作系统
【发布时间】:2012-01-03 01:21:03
【问题描述】:

ISO C 和 POSIX 都不提供在运行时确定底层操作系统的功能。从理论的角度来看,这并不重要,因为 C 为最常见的系统调用提供了包装器,而且从挑剔的角度来看,甚至不必成为底层操作系统。

然而,在许多现实世界的场景中,事实证明,了解比 C 愿意分享的主机环境更多的信息是有帮助的,例如为了找出存储配置文件的位置或如何调用select(),所以:

对于用 C 编写的应用程序,是否有一种惯用的方法可以在运行时确定底层操作系统?

至少,我可以轻松地在 Linux、Windows、BSD 和 MacOS 之间做出选择吗?

我目前的猜测是检查某些文件/目录是否存在,例如C:\/,但这种方法似乎不可靠。也许查询一系列此类来源可能有助于建立“操作系统指纹”的概念,从而提高可靠性。无论如何,我期待您的建议。

【问题讨论】:

  • 呃,这个信息你在编译的时候就知道了
  • 尝试运行程序一段时间。如果它在崩溃中被杀死,那么你就在 Windows 上。如果操作系统更新为 5G 或猫,那么您使用的是 Mac。如果你在 180 天后被黑客入侵,那就是 Linux。否则就是 BSD。
  • @Philip 嗯,#ifdef在这里是必不可少的,即使你不能让自己喜欢它也必须学会与它相处
  • @rsaxvc,但就您的应用而言,wine+linux is windows,在 solaris is linux 上运行 linux 二进制文件,并且正在运行它们在 BSD 上仍然是 linux。
  • @rsaxvc 然后由模拟器来做好模拟系统的工作。当你在 Wine 上运行时,从程序的角度来看,操作系统就是 Windows。

标签: c windows linux macos bsd


【解决方案1】:

实际上,大多数系统都有一个uname 命令来显示当前正在使用的内核。在 Mac OS 上,这通常是“Darwin”,在 Linux 上只是普通的“Linux”,在 Windows 上是“ERROR”,FreeBSD 将返回“FreeBSD”。

More complete list of uname outputs

我很确定 uname 有一个 C 等价物,所以你不需要 system()

【讨论】:

  • 看来我打败了你们所有人:-)
  • @Tom 你确定在 Windows 上会发生什么吗?对于所有 C 编译器?
  • @DavidHeffernan 哈哈,我确定它不会返回字符串“ERROR”。但是,Windows 上的结果差异很大。据我所知,只有 cygwin 返回正确的 uname,但某些编译器实际上可能会编译它。因此,uname 在 Wine 或 Crossover 下运行时不可靠。
  • @TomvanderWoerdt - 我发表了一篇文章说'你是对的,不能对所有操作系统都这样做',但后来意识到 OP 只是询问 BSD/OSX/Windows/Linux。跨度>
【解决方案2】:

如果您在 POSIX 系统上,您可以从 <sys/utsname.h> 调用 uname()。

这显然不是 100% 可移植的,但我认为不会有任何方法可以在运行时授予它。

详情请见the man page

【讨论】:

    【解决方案3】:

    运行时不是确定这一点的时候,因为一个平台没有史诗般的二进制文件将无法在另一个平台上运行,您应该在平台敏感代码周围使用#ifdefs。

    【讨论】:

    • -1 因为问题是关于如何在运行时确定操作系统,而不是你是否应该这样做。
    • 是的,但这对 OP 没有帮助。对于 VAST 的大多数情况,为 FreeBSD 发出的对象无论如何都不会在 Linux 上工作(这适用于他的大多数情况),所以在运行时这样做是他最小的麻烦。
    【解决方案4】:

    接受的答案是uname,但没有提供一个最小的工作示例,所以这里适合任何有兴趣的人-希望它可以节省您为我花费的时间:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/utsname.h>
    
    int main(void) {
       struct utsname buffer;
       if (uname(&buffer) != 0) {
          perror("uname");
          exit(0);
       }
       printf("OS: %s\n", buffer.sysname);
    
       return 0;
    }
    

    (可能的)输出:

    操作系统:Linux

    PS:不幸的是,这使用了 POSIX 标头:Compilation fails due to missing file sys/utsname.h,这很可能在 Windows 中不起作用。

    【讨论】:

    • 错误 C1083:无法打开包含文件:'sys/utsname.h':没有这样的文件或目录。这在 Linux 上有效,但在 Windows 上无效。
    【解决方案5】:
    if (strchr(getenv("PATH"),'\\'))
        puts("You may be on windows...");
    

    我什至同意“运行时不是确定这个的时间......”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 2017-07-01
      • 1970-01-01
      • 2015-12-10
      • 2014-12-18
      • 2012-05-21
      • 2013-01-02
      • 1970-01-01
      相关资源
      最近更新 更多