windows获取系统版本号和本机ip地址

前言

最近的这几年微软的部分接口开始声明废弃了。
加个宏可以继续使用旧的接口,但是会引起很多其他问题(项目简单了还好,如果调用微软接口多了,编译会报找不到接口的问题,因为那个宏的作用好像把新的接口给屏蔽掉)。

这里直接使用的微软提供的接口,如果你是使用Qt的话,就会很简单,Qt直接提供了相关的接口。

本机ip地址的获取方式

主要解决 “gethostbyname被getaddrinfo替换”的问题。

会需要几个依赖库,我懒,就不写了。
bool XXXDeviceInfo::getLocalIP(std::list<std::string> &ipList)
{
    //1.初始化wsa
    WSADATA wsaData;
    int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (ret != 0)
    {
        return false;
    }

    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    char hostname[256] = { 0 };
    int dwRetval = getaddrinfo(hostname, 0, &hints, &result);
    if (dwRetval != 0)
    {
        printf("getaddrinfo response error:%d \n", dwRetval);
        return false;
    }
    else
    {
        for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
        {

            //printf("getaddrinfo response %d\n", dwRetval);
            //printf("\tFlags: 0x%x\n", ptr->ai_flags);
            //printf("\tFamily: ");
            switch (ptr->ai_family) {
            case AF_UNSPEC:
                //printf("Unspecified\n");
                break;
            case AF_INET:
            {
                //printf("AF_INET (IPv4)\n");
                struct sockaddr_in *sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
                //printf("\tIPv4 address %s\n",
                //  inet_ntoa(sockaddr_ipv4->sin_addr));
                char str[INET_ADDRSTRLEN] = { 0 };
                inet_ntop(AF_INET, &sockaddr_ipv4->sin_addr, str, sizeof(str));
                //printf("\tIPv4 address %s\n", str);
                ipList.push_back(str);
            }
            break;
            case AF_INET6:
            {
                //printf("AF_INET6 (IPv6)\n");
                // the InetNtop function is available on Windows Vista and later
                // sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
                // printf("\tIPv6 address %s\n",
                //    InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstringbuffer, 46) );

                // We use WSAAddressToString since it is supported on Windows XP and later
                LPSOCKADDR sockaddr_ip = (LPSOCKADDR)ptr->ai_addr;
                // The buffer length is changed by each call to WSAAddresstoString
                // So we need to set it for each iteration through the loop for safety
                DWORD ipbufferlength = 46;
                TCHAR ipstringbuffer[46] = { 0 };
                int iRetval = WSAAddressToString(sockaddr_ip, (DWORD)ptr->ai_addrlen, NULL,
                    ipstringbuffer, &ipbufferlength);
                //if (iRetval)
                //  printf("WSAAddressToString failed with %u\n", WSAGetLastError());
                //else
                //  printf("\tIPv6 address %s\n", TCHAR2STRING(ipstringbuffer).c_str());
                ipList.push_back(TCHAR2STRING(ipstringbuffer));
            }
            break;
            case AF_NETBIOS:
                printf("AF_NETBIOS (NetBIOS)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_family);
                break;
            }
        }

    }

    int t_rtn = WSACleanup();

    return true;

}

代码的来源是windows的官方代码(具体链接,搜相关的接口吧)。

当前windows系统版本

像是Qt,都有这些接口,但是如果调用微软的接口的话,会发现很多问题。

1,vs2013 如果调用 IsWindows10OrGreater(),会报找不到的错误。
因为 我的vs2013下依赖的是win8.1的sdk。

2,如果调用 IsWindows10OrGreater() 、IsWindows8OrGreater(),之类的接口,貌似还要添加一个xml的依赖文件。然后我就放弃了。然后我就直接获取的windows内部版本号。也就是5.1 、5.2 、6.1 、6.2 之类的。

bool XXXXXXDeviceInfo::getOperatingSystemVersion(std::string &strVersion)
{
    //我知道可以用 IsWindows8Point1OrGreater 这种函数,但是限制条件太多了。

    DWORD dwVersion = 0;
    WKSTA_INFO_100 *wkstaInfo = NULL;
    DWORD dwMajVer = 0;
    DWORD dwMinVer = 0;
    NET_API_STATUS netStatus = NetWkstaGetInfo(NULL, 100, (BYTE **)&wkstaInfo);
    if (netStatus == NERR_Success)
    {
        dwMajVer = wkstaInfo->wki100_ver_major;
        dwMinVer = wkstaInfo->wki100_ver_minor;
        dwVersion = (DWORD)MAKELONG(dwMinVer, dwMajVer);
        NetApiBufferFree(wkstaInfo);
    }
    if (0 == dwMajVer
        && 0 == dwMinVer)
    {
        return false;
    }
    std::string t_internalVersion;
    t_internalVersion += to_string(dwMajVer);
    t_internalVersion += ".";
    t_internalVersion += to_string(dwMinVer);

    if ("5.0" == t_internalVersion)
    {
        strVersion = "Windows 2000";
    }
    else if ("5.1" == t_internalVersion)
    {
        strVersion = "Windows XP (x86)";
    }
    else if ("5.2" == t_internalVersion)
    {
        strVersion = "Windows XP (x64)";
    }
    else if ("6.0" == t_internalVersion)
    {
        strVersion = "Windows Vista";
    }
    else if ("6.1" == t_internalVersion)
    {
        strVersion = "Windows 7";
    }
    else if ("6.2" == t_internalVersion)
    {
        strVersion = "Windows 8";
    }
    else if ("6.3" == t_internalVersion)
    {
        strVersion = "Windows 8.1";
    }
    else if ("10.0" == t_internalVersion)
    {
        strVersion = "Windows 10";
    }
    else
    {
        strVersion = "";
    }

    double t_fVersion = atof(t_internalVersion.c_str());
    if (t_fVersion > 10.0)
    {
        strVersion = "Windows 10 or greater";
    }

    return true;
}

参考地址1
参考地址2

你可能感兴趣的:(学习)