求助:使用C语言utsname无法获取宿主系统Windows 10的系统名称
解决Cygwin环境下获取Windows宿主系统信息的问题
你当前用uname()和utsname结构体拿到的是Cygwin模拟层的系统信息,而非宿主Windows的原生信息——因为Cygwin是在Windows上提供POSIX兼容层的工具,uname()这类POSIX接口只会返回该兼容层的标识。要获取Windows 10的原生系统信息,需要使用Windows原生API或者直接调用Windows系统命令,以下是两种可行方案:
方案一:使用Windows原生API(推荐)
Windows提供了专门的系统版本查询API,推荐使用GetProductInfo和VerifyVersionInfo(替代已弃用的GetVersionEx),可以精准获取系统版本、产品名称等信息。
示例代码:
#include <stdio.h> #include <windows.h> int main(void) { OSVERSIONINFOEX osvi; DWORDLONG dwlConditionMask = 0; BOOL bOsVersionInfoEx; // 初始化OSVERSIONINFOEX结构 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); osvi.dwMajorVersion = 10; osvi.dwMinorVersion = 0; // 设置版本验证条件 VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); // 验证是否为Windows 10及以上 if (VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask)) { printf("操作系统: Windows 10 或更高版本\n"); } else { printf("非Windows 10系统\n"); return 1; } // 获取具体版本信息(如内部版本号) if (!GetVersionEx((OSVERSIONINFO*)&osvi)) { printf("GetVersionEx调用失败\n"); return 1; } printf("内部版本号: %lu\n", osvi.dwBuildNumber); // 获取产品名称(需要链接kernel32.lib) DWORD dwProductType; if (GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwProductType)) { switch(dwProductType) { case PRODUCT_HOME_BASIC: printf("产品名称: Windows 10 家庭版\n"); break; case PRODUCT_HOME_PREMIUM: printf("产品名称: Windows 10 家庭高级版\n"); break; case PRODUCT_PROFESSIONAL: printf("产品名称: Windows 10 专业版\n"); break; default: printf("产品名称: Windows 10 其他版本\n"); break; } } else { printf("无法获取产品名称\n"); } return 0; }
编译命令(Cygwin环境下):
gcc win_version.c -o win_version -lkernel32
方案二:调用Windows系统命令并解析输出
可以通过system()函数调用Windows自带的ver或systeminfo命令,捕获输出后解析系统信息。这种方法实现简单,但输出格式可能随Windows版本变化,稳定性不如API。
示例代码:
#include <stdio.h> #include <stdlib.h> int main(void) { printf("系统版本信息:\n"); // 调用ver命令输出基础系统版本 system("ver"); // 或者调用systeminfo筛选关键信息 system("systeminfo | findstr /B /C:\"OS Name\" /C:\"OS Version\""); return 0; }
额外说明
你代码中的execlp("start", "starting", NULL);语句如果执行成功会替换当前进程,导致后续的uname()代码不会执行。当前你的输出中能看到uname()的结果,说明这行调用失败了(Cygwin中没有名为start的POSIX命令,Windows的start需要通过cmd /c start调用)。如果不需要这行代码,建议直接删除。
内容的提问来源于stack exchange,提问作者Kevin Helloo
相关产品推荐
相关产品推荐

