一个Window/Linux(Fedora测试平台)的CPU,磁盘,内存,PC,进程相关信息采集功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个Window/Linux(Fedora测试平台)的CPU,磁盘,内存,PC,进程相关信息采集功能相关的知识,希望对你有一定的参考价值。

说明:采用的是Multi-Byte Character Set,不支持Unicode。

Peer2PeerData.h

技术分享
#ifndef _PEER_2_PEER_DATA_H
#define _PEER_2_PEER_DATA_H

#include <cstring>
 
/* unsigned long long */
typedef unsigned long long ULLong;

#define ELAPSEDSECONDS                10000000
#define ADAYTOTALSECONDS            (1 * 24 * 60 * 60)

#define RECEIVED_BUFFER_LENGTH        (1024 * 4)

#define QUERY_SLEEP_TIMESTAMP_MS    1024     

#define MESSAGEMAXLENGGTH            (1024 * 1024 * 128)
#define HEADER                        0x02
#define PACKHEADERLENGTH            (1 + sizeof(int))

#define TYPE_CPUUSAGE                1
#define TYPE_MEMORYUSAGE            2
#define TYPE_DRIVEUSAGE                3
#define TYPE_RUNTHEFILE                4
#define TYPE_PROCESSINFO            5

#define TYPE_CMD_CURRENT            20
#define TYPE_CMD_AVERAGE            702
#define TYPE_CMD_APPOINT            888
#define TYPE_CMD_RESERVE            999

#define CMD_CALC_UNIT_MINUTES        101
#define CMD_CALC_UNIT_HOURS            45
#define UNIT_VALUE_ONE                1
#define UNIT_VALUE_THREE            3
#define UNIT_VALUE_SIX                6
#define UNIT_VALUE_TEN                10
#define UNIT_VALUE_TWELVE            12
#define UNIT_VALUE_TWENTYFOUR        24
#define UNIT_VALUE_THIRTY            30
#define UNIT_VALUE_SIXTY            60


/* 磁盘/挂载/盘符容量信息 */
struct CapacityInfo
{
    /* 总值(kB) */
    ULLong m_nTotal;
    /* 空闲值(kB) */
    ULLong m_nFree;
    /* 磁盘/挂载/盘符名称 */
    char m_szName[128];

    CapacityInfo() : m_nTotal(0), m_nFree(0)
    {
        memset(m_szName, 0, sizeof(m_szName));
    }
};

/* 进程信息 */
struct ProcessInfo
{
    /* Start-Time Year */
    unsigned short m_nStartTime_Year;
    /* Start-Time Month */
    unsigned short m_nStartTime_Month; 
    /* Start-Time Day */
    unsigned short m_nStartTime_Day;
    /* Start-Time Hour */
    unsigned short m_nStartTime_Hour;
    /* Start-Time Minute */
    unsigned short m_nStartTime_Minute;
    /* Start-Time Second */
    unsigned short m_nStartTime_Second; 
    /* Pid */
    unsigned short m_nPid;
    /* Run-Time(s) */
    unsigned long long m_nRunTime;
    /* Process Name */
    char m_szName[128];
    /* Process File-Name */
    char m_szFileName[256]; 
#ifdef WIN32
    /* Process Describe */
    char m_szDescribe[512];
#endif

    ProcessInfo() : m_nPid(0), m_nRunTime(0)
    {         
        m_nStartTime_Year = m_nStartTime_Month = m_nStartTime_Day = m_nStartTime_Hour = m_nStartTime_Minute = m_nStartTime_Second = 0;
        memset(m_szName, 0, sizeof(m_szName));
        memset(m_szFileName, 0, sizeof(m_szFileName));
#ifdef WIN32
        memset(m_szDescribe, 0, sizeof(m_szDescribe));
#endif
    }
};
#endif //_PEER_2_PEER_DATA_H
View Code

.h

#ifndef    _DATA_ACQUISITION_
#define    _DATA_ACQUISITION_

#include "Peer2PeerData.h"
#include <vector> 
#include <string>

using namespace std;

/*
    Data Acquisition (DAQ)
*/
class DataAcquisition
{
public:
    DataAcquisition(void);
    ~DataAcquisition(void);

    
/*------CPU Start------*/
public:    
    /**
     *  CPU核数.
     *
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version 
     **/
    int ProcessorCores(); 
    /**
     *  CPU各核的使用率(%).
     *
     *  @param        -[in,out]  vector<double> &vUtilization: [使用率]
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version 
     *    @example    cpu : 2.47525(%)
     *                cpu0: 1.96078(%)
     *                cpu1: 2.2703(%)
     *                ...
     **/
    int CpuUsageOfCores(vector<double> &vUtilization);
    /**
     *  进程的CPU使用率(%).
     *
     *  @param        -[in,out]  double &nUtilize: [使用率]
     *  @param        -[in]  int nPid: [PID] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version 
     *    @remark        -[Pid = -1] Mean Current Process
     *    @example    2.47525(%)
     **/
    int CpuUsageByProcess(double &nUtilize, int nPid = -1);

private:
    /* CPU Cores */
    int m_nProcessorCores;
/*------ CPU End ------*/

    
/*------Memory Start------*/
public:
    /**
     *  物理内存(kB).
     *
     *  @param        -[in,out]  ULLong &nTotal: [总值] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @example    1024(kB)
     **/
    int    PhysicalMemory(ULLong &nTotal);    
    /**
     *  空闲物理内存(kB).
     *
     *  @param        -[in,out]  ULLong &nFree: [空闲值] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @example    512(kB)
     **/
    int PhysicalMemoryFree(ULLong &nFree);    
    /**
     *  进程的物理内存使用值(kB).
     *
     *  @param        -[in,out]  ULLong &nUsage: [使用值] 
     *  @param        -[in]  int nPid: [PID] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @remark        -[Pid = -1] Mean Current Process
     *    @example    64(kB)
     **/
    int PhysicalMemroyUsageByProcess(ULLong &nUsage, int nPid = -1);
    /**
     *  虚拟内存(kB).
     *
     *  @param        -[in,out]  ULLong &nTotal: [总值] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @example    1024(kB)
     **/
    int    VirtualMemory(ULLong &nTotal);    
    /**
     *  空闲虚拟内存(kB).
     *
     *  @param        -[in,out]  ULLong &nFree: [空闲值] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @example    512(kB)
     **/
    int VirtualMemoryFree(ULLong &nFree);    
    /**
     *  进程的虚拟内存使用值(kB).
     *
     *  @param        -[in,out]  ULLong &nUsage: [使用值] 
     *  @param        -[in]  int nPid: [PID] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @remark        -[Pid = -1] Mean Current Process
     *    @example    64(kB)
     **/
    int VirtualMemroyUsageByProcess(ULLong &nUsage, int nPid = -1);

private:
    /* 物理内存(kB) */
    ULLong    m_nPhysicalMemory;
    /* 虚拟内存(kB) */
    ULLong    m_nVirtualMemory;
    
/*------ Memory End ------*/

    
/*------Disk Start------*/
public:
    /**
     *  磁盘数.
     *
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     **/
    int DiskCount();
    /**
     *  挂载/盘符数.
     *
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     **/
    int    DriveLetterCount();
    /**
     *  磁盘容量信息.
     *
     *  @param        -[in,out]  vector<CapacityInfo> &vCapacityInfo: [容量信息]  
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version    
     **/
    int TheDiskCapacityInfo(vector<CapacityInfo*> &vCapacityInfo);
    /**
     *  挂载/盘符容量信息.
     *
     *  @param        -[in,out]  vector<CapacityInfo> &vCapacityInfo: [容量信息] 
     *  @param        -[in]  const char* szDriveLetter: [挂载/盘符] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @remark        -[szDriveLetter = NULL] Mean All Drive-Letter 
     *    @example    Windows(szDriveLetter = ‘C:\‘), Linux(szDriveLetter = ‘/root‘)
     **/
    int TheDriveLetterCapacityInfo(vector<CapacityInfo*> &vCapacityInfo, const char* szDriveLetter = NULL);
/*------ Disk End ------*/
    

/*------Process Start------*/
public:
    /**
     *  打开文件.
     *
     *  @param        -[in]  const char* szFile: [文件] 
     *  @param        -[in]  const char* szParameters: [参数] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @remark        -[szParameters = NULL] Mean Without Parameter 
     **/
    int OpenTheFile(const char* szFile, const char* szParameters = NULL);    
    /**
     *  进程信息.
     *
     *  @param        -[in,out]  vector<ProcessInfo*> &vProcessInfo: [进程信息] 
     *  @param        -[in]  int nPid: [PID] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @remark        -[nPid = -1] Mean All Process-Info 
     **/
    int Processes(vector<ProcessInfo*> &vProcessInfo, int nPid = -1);    
    /**
     *  进程信息.
     *
     *  @param        -[in]  const char* szProcessName: [进程名称] 
     *  @param        -[in,out]  int &nPid: [PID] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @remark        -[nPid = -1] Mean Error Occurred 
     **/
    int TheProcessIDByName(const char* szProcessName, int &nPid);
/*------ Process End ------*/
    

/*------PC Start------*/
public:        
    /**
     *  Ping.
     *
     *  @param        -[in]  char* szHostName: [主机地址]  
     *  @return        bool.  
     *  @version    10/28/2016    W   Initial Version   
     **/
    bool Ping(const char *szIPAddress);
    /**
     *  主机名称.
     *
     *  @param        -[in]  char* szHostName: [主机名称] 
     *  @param        -[in,out]  unsigned long &nLength: [长度] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version  
     *    @remark        -[nPid = -1] Mean Error Occurred 
     **/
    int    TheHostName(char* szHostName, unsigned long &nLength);        
    /**
     *  当前用户名称.
     *
     *  @param        -[in]  char* szUserName: [用户名称] 
     *  @param        -[in,out]  unsigned long &nLength: [长度] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version   
     **/
    int TheUserName(char* szUserName, unsigned long &nLength);        
    /**
     *  主机IP.
     *
     *  @param        -[in,out]  vector<string> &vIPAddress: [IP] 
     *  @param        -[in]  unsigned short nFamily: [协议] 
     *  @return        int.  
     *  @version    10/28/2016    W   Initial Version   
     *    @remark             OS                Family        Value
     *                Windows            AF_INET                2
     *                Windows/Linux    AF_INET6        23/10
     *                Windows            AF_UNSPEC            0
     **/
    int TheHostIPAddress(vector<string> &vIPAddress, unsigned short nFamily /* = AF_INET or AF_INET6 or AF_UNSPEC*/);
/*------ PC End ------*/


/*------Net Start------*/

/*------ Net End ------*/
};

#endif //_DATA_ACQUISITION_

.cpp

技术分享
#include "DataAcquisition.h"

//#include <cstdio>
#include <stdio.h> 
#include <sstream>

#ifdef WIN32 
//#define WIN32_LEAN_AND_MEAN    1
#define    C_DRIVERLETTER        0x43

#include <tchar.h> 
#include <ctype.h>  
#include <Winsock2.h>
#include <WS2tcpip.h>
#include <Windows.h> 
#include <TlHelp32.h> 
#include <Pdh.h>
#pragma comment(lib, "Pdh.lib")
#include <Psapi.h> 
#pragma comment(lib, "Psapi.lib")
#include <IPHlpApi.h>
#pragma comment(lib, "Iphlpapi.lib")
#include <WinIoCtl.h>
#include <ShellAPI.h>
#include <devguid.h>
#include <Setupapi.h> 
#pragma comment(lib, "Setupapi.lib")

PDH_HQUERY g_Query = NULL;
PDH_HCOUNTER *g_pCounters = NULL; 
PDH_FMT_COUNTERVALUE *g_pCounterValue = NULL;

#else
 
#ifdef __GNUC__
#include "x86intrin.h"
#define __rdtsc() __builtin_ia32_rdtsc()
#endif

#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <cstring>
#include <sys/times.h>
#include <sys/vtimes.h>
#include <sys/socket.h> 
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <stdlib.h>
#include <dirent.h>
#include <fstream>
#include <unistd.h> 
#include <netdb.h>  
#include <arpa/inet.h> 
#include <map>

#define HERTZ (sysconf(_SC_CLK_TCK) * 1.0) 
#define READ_CHARS_LENGTH    256 

#endif

using namespace std;

DataAcquisition::DataAcquisition(void) : 
    m_nProcessorCores(0),
    m_nPhysicalMemory(0),
    m_nVirtualMemory(0)
{
} 
DataAcquisition::~DataAcquisition(void)
{
#ifdef WIN32 
    if(g_Query)
        PdhCloseQuery(g_Query); 
    if(g_pCounters != NULL || g_pCounterValue != NULL)
    {
        delete[] g_pCounters;
        delete[] g_pCounterValue;
    } 
#else

#endif
}

/*------Global Function Start------*/ 
#ifdef WIN32
bool AdjustTokenPrivilege(HANDLE hProcess, DWORD nDesiredAccess = TOKEN_ALL_ACCESS /* TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY */)
{
    HANDLE hToken = NULL;
    if(!OpenProcessToken(hProcess, nDesiredAccess, &hToken))
    {
        if(hToken != NULL)
            CloseHandle(hToken);
        if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 
             return true;
        else return false;
    }

    TOKEN_PRIVILEGES tokenPrivileges;  
    if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME/*SE_SECURITY_NAME*/, &tokenPrivileges.Privileges[0].Luid))
    {
        if(hToken != NULL)
            CloseHandle(hToken);
        return false;
    }

    tokenPrivileges.PrivilegeCount = 1;
    tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    BOOL bReturn = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL);
    if(hToken != NULL)
        CloseHandle(hToken);

    return bReturn == TRUE;
}

int TheProcessIDByWindowName(const char* szWinName)
{
    DWORD ProcessID = -1;
    HWND hWnd = FindWindow(NULL, szWinName);
    if (hWnd != NULL) 
        GetWindowThreadProcessId(hWnd, &ProcessID);  
    return ProcessID;
}

HANDLE TheProcessByID(int nPid, unsigned long nDesiredAccess = PROCESS_QUERY_INFORMATION /* PROCESS_ALL_ACCESS */)
{
    return OpenProcess(nDesiredAccess, FALSE, nPid);
}

#else

void LinesFrom(FILE *pFile, vector<string> &vResult)
{
    vResult.clear();
    char szLine[READ_CHARS_LENGTH] = { 0 };
    while(fgets(szLine, READ_CHARS_LENGTH, pFile) != NULL)
    {
        int nLength = strlen(szLine);
        if(szLine[nLength - 1] == \n)
            szLine[nLength - 1] = \0;
        vResult.push_back(szLine);
    }
}

int ExecuteCommand(const char *szCommand, vector<string> &vResult)
{    
    FILE *pCmd = popen(szCommand, "r");
    if(pCmd == NULL) 
        return -1; 
    LinesFrom(pCmd, vResult);
    return pclose(pCmd);
}

int OpenTheFileWithMode(const char *szFile, vector<string> &vResult, const char *szMode = "r")
{
    FILE *pFile = fopen(szFile, szMode);
    if(pFile == NULL) 
        return -1; 
    LinesFrom(pFile, vResult);
    return fclose(pFile);
}

int CPUCurrentUsageCalculator(vector<ULLong> &vltTotal, vector<ULLong> &vltIdle)
{
    vltTotal.clear();
    vltIdle.clear();    
    // /proc/stat | grep cpu | awk -F ‘ ‘ ‘{ print $2 + $3 + $4 + $5 + $6 + $7 + $8 + $9, $5 }‘
    vector<string> vResult;
    ExecuteCommand("cat /proc/stat | grep cpu | awk -F ‘ ‘ ‘{ print $2 + $3 + $4 + $5 + $6 + $7 + $8 + $9, $5 }‘", vResult);
        
    int nCores = vResult.size();
    for(int i = 0; i < nCores; i++)
    {
        ULLong ltTotal, ltIdle;
        sscanf(vResult[i].c_str(), "%llu %llu", &ltTotal, &ltIdle);
        vltTotal.push_back(ltTotal);
        vltIdle.push_back(ltIdle);
    }
    return nCores;
}
#endif
/*------Global Function End------*/ 


/*------CPU Start------*/ 
int DataAcquisition::ProcessorCores()
{
    if(m_nProcessorCores == 0)
    {
#ifdef WIN32
        SYSTEM_INFO sysInfo;
        GetSystemInfo(&sysInfo);
        m_nProcessorCores = sysInfo.dwNumberOfProcessors;
#else 
        m_nProcessorCores = sysconf(_SC_NPROCESSORS_ONLN);
#endif
    }
    return m_nProcessorCores;
}

int DataAcquisition::CpuUsageOfCores(vector<double> &vUtilization)
{
    vUtilization.clear();
    int nCores = ProcessorCores();
    vUtilization.assign(nCores + 1, 0);
    
#ifdef WIN32
    /*also by FILETIME  GetSystemTimes()
        utilization = (1 - idle / (kernel + user)) * 100;
    */
    if(g_Query == NULL || g_pCounters == NULL)    
    {
        g_pCounters = new PDH_HCOUNTER[nCores + 1];
        g_pCounterValue = new PDH_FMT_COUNTERVALUE[nCores + 1];

        PdhOpenQuery(NULL, NULL, &g_Query);
        PdhAddCounter(g_Query, "\\Processor(_Total)\\% Processor Time", NULL, &g_pCounters[0]);

        char szCounterPath[64] = { 0 };
        for(int i = 1; i <= nCores; i++)
        {
            sprintf(szCounterPath, "\\Processor(%d)\\%% Processor Time", i);
            PdhAddCounter(g_Query, szCounterPath, NULL, &g_pCounters[i]);
        }
        PdhCollectQueryData(g_Query);
        for(int i = 0; i <= nCores; i++)
        {
            PdhGetFormattedCounterValue(g_pCounters[i], PDH_FMT_DOUBLE, NULL, &g_pCounterValue[i]);
        }
        Sleep(QUERY_SLEEP_TIMESTAMP_MS / 8);
    }    
    PdhCollectQueryData(g_Query);
    for(int i = 0; i <= nCores; i++)
    {
        PdhGetFormattedCounterValue(g_pCounters[i], PDH_FMT_DOUBLE, NULL, &g_pCounterValue[i]);
        vUtilization[i] = g_pCounterValue[i].doubleValue;
    }
    //Sleep(QUERY_SLEEP_TIMESTAMP_MS / 16);//WaitForSingleObject
#else
    vector<ULLong> vltTotalFirst, vltIdleFirst;  
    nCores = CPUCurrentUsageCalculator(vltTotalFirst, vltIdleFirst);
         
    sleep(1); 

    vector<ULLong> vltTotalSecond, vltIdleSecond;
    nCores = CPUCurrentUsageCalculator(vltTotalSecond, vltIdleSecond);

    for(int i = 0; i < nCores; i++)
    {
        double divisor = (vltIdleSecond[i] - vltIdleFirst[i]) * 1.0;
        double dividend = (vltTotalSecond[i] - vltTotalFirst[i]) * 1.0;
        double utilizate = (dividend <= 0 || divisor <= 0) ? 0 : (dividend - divisor) <= 0 ? 0 : (dividend - divisor) / dividend;
        vUtilization[i] = utilizate >= 1 ? 100 : utilizate * 100; 
    }  
#endif
    return 0;      
}

int DataAcquisition::CpuUsageByProcess(double &nUtilize, int nPid)
{
    nUtilize = 0; 

#ifdef WIN32 
    /*also by "\\Process(%s)\\% Processor Time"  
        %s=The Process Name;
    */
    ULARGE_INTEGER uiPFistIdle, uiPFistKernel, uiPFistUser;
    FILETIME ftPFistIdle, ftPFistKernel, ftPFistUser;
    
    GetSystemTimeAsFileTime(&ftPFistIdle);
    memcpy(&uiPFistIdle, &ftPFistIdle, sizeof(FILETIME));
     
    HANDLE hProcess = nPid == -1 ? GetCurrentProcess() : TheProcessByID(nPid);
    AdjustTokenPrivilege(hProcess);

    if(FALSE == GetProcessTimes(hProcess, &ftPFistIdle, &ftPFistIdle, &ftPFistKernel, &ftPFistUser))
        return -1;
    memcpy(&uiPFistUser, &ftPFistUser, sizeof(FILETIME));      
    memcpy(&uiPFistKernel, &ftPFistKernel, sizeof(FILETIME));
         
    Sleep(QUERY_SLEEP_TIMESTAMP_MS / 16);//WaitForSingleObject(hProcess, QUERY_SLEEP_TIMESTAMP_MS / 4);
       
    DWORD eCode = 0;
    GetExitCodeProcess(hProcess, &eCode);    
    if(eCode != STILL_ACTIVE)  
        return -1;

    ULARGE_INTEGER uiPSecondIdle, uiPSecondKernel, uiPSecondUser; 
    FILETIME ftPSecondIdle, ftPSecondKernel, ftPSecondUser;

    GetSystemTimeAsFileTime(&ftPSecondIdle);
    memcpy(&uiPSecondIdle, &ftPSecondIdle, sizeof(FILETIME));
      
    if(FALSE == GetProcessTimes(hProcess, &ftPSecondIdle, &ftPSecondIdle, &ftPSecondKernel, &ftPSecondUser))
        return -1;
    memcpy(&uiPSecondUser, &ftPSecondUser, sizeof(FILETIME));      
    memcpy(&uiPSecondKernel, &ftPSecondKernel, sizeof(FILETIME));

    //(kernel + user) / (idle * cors) * 100; 
    double divisor = (uiPSecondKernel.QuadPart - uiPFistKernel.QuadPart + uiPSecondUser.QuadPart - uiPFistUser.QuadPart) * 1.0;
    double dividend = (uiPSecondIdle.QuadPart - uiPFistIdle.QuadPart) * 1.0; 
    double utilization = (dividend <= 0 || divisor <= 0) ? 0 : divisor / dividend * ProcessorCores();    
    nUtilize = utilization >= 1 ? 100 : utilization * 100; 
#else 
    // also "ps -p {pid} h -o %cpu"
    // cat /proc/{pid}/stat | awk -F ‘ ‘ ‘{     print $14 + $15 + $16 + $17 }‘
    if(nPid == 0)
        return -1;
    if(nPid <= -1)
        nPid = getpid();
        
    char cmd[128] = { 0 };
    sprintf(cmd, "cat /proc/%i/stat | awk -F ‘ ‘ ‘{ print $14 + $15 + $16 + $17 }‘", nPid);

    vector<string> vResult;      
    ExecuteCommand(cmd, vResult);  
    if(vResult.size() == 0)
        return -1;  
        
    ULLong nTotalFirst;
    sscanf(vResult[0].c_str(), "%llu", &nTotalFirst);
    vector<ULLong> vltTotalFirst, vltIdleFirst;  
    CPUCurrentUsageCalculator(vltTotalFirst, vltIdleFirst);

    sleep(1); 
      
    ExecuteCommand(cmd, vResult);  
    if(vResult.size() == 0)
        return -1;  
    
    ULLong nTotalSecond;
    sscanf(vResult[0].c_str(), "%llu", &nTotalSecond);
    vector<ULLong> vltTotalSecond, vltIdleSecond;
    CPUCurrentUsageCalculator(vltTotalSecond, vltIdleSecond);
               
    double divisor = (nTotalSecond - nTotalFirst) * 1.0;
    double dividend = (vltTotalSecond[0] - vltTotalFirst[0]) * 1.0;
    double utilization = (dividend <= 0 || divisor <= 0) ? 0 : divisor / dividend * ProcessorCores();
    nUtilize = utilization >= 1 ? 100 : utilization * 100; 
#endif
    return 0;
}     
/*------ CPU End ------*/


/*------Memory Start------*/
int    DataAcquisition::PhysicalMemory(ULLong &nTotal)
{
    if(m_nPhysicalMemory == 0)
    {
#ifdef WIN32
        MEMORYSTATUSEX vMemory;
        vMemory.dwLength = sizeof(MEMORYSTATUSEX);
        GlobalMemoryStatusEx(&vMemory);

        m_nPhysicalMemory = vMemory.ullTotalPhys / 1024;
#else
        struct sysinfo pMemory;
        sysinfo(&pMemory); 
    
        m_nPhysicalMemory = pMemory.totalram * pMemory.mem_unit / 1024;
#endif
    }
    nTotal = m_nPhysicalMemory;
    return 0;
}

int DataAcquisition::PhysicalMemoryFree(ULLong &nFree)
{
    nFree = 0;

#ifdef WIN32
    /*also by "\\Memory\\Available Bytes";
    */
    MEMORYSTATUSEX vMemory;
    vMemory.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&vMemory);

    if(m_nPhysicalMemory == 0)
        m_nPhysicalMemory = vMemory.ullTotalPhys / 1024;
    nFree = vMemory.ullAvailPhys / 1024; 
#else
    /*also /proc/meminfo
    */
    struct sysinfo pMemory;
    sysinfo(&pMemory); 

    if(m_nPhysicalMemory == 0)
        m_nPhysicalMemory = pMemory.totalram * pMemory.mem_unit / 1024;
    nFree = pMemory.freeram * pMemory.mem_unit / 1024;
#endif
    return 0;
}

int DataAcquisition::PhysicalMemroyUsageByProcess(ULLong &nUsage, int nPid)
{
    nUsage = 0;    

#ifdef WIN32
    PROCESS_MEMORY_COUNTERS pMemCounter; 
    GetProcessMemoryInfo(nPid == -1 ? GetCurrentProcess() : TheProcessByID(nPid), &pMemCounter, sizeof(PROCESS_MEMORY_COUNTERS)); 

    nUsage = pMemCounter.WorkingSetSize / 1024;
#else
    /*also "ps -p {pid} h -o %mem"
    */
    if(nPid == 0)
        return -1;
    if(nPid <= -1)
        nPid = getpid();

    //            grep VmRSS /proc/{nPid}/status
    //            RssAnon :system-monitor value
    char buf[32] = { 0 };
    sprintf(buf, "grep VmRSS /proc/%i/status", nPid); 
    vector<string> vResult;
    ExecuteCommand(buf, vResult);
    
    if(vResult.size() == 0)
        return -1; 
     
    sscanf(vResult[0].c_str(), "VmRSS:%llukB", &nUsage); 
#endif
    return 0;
}

int    DataAcquisition::VirtualMemory(ULLong &nTotal)
{
    if(m_nVirtualMemory == 0)
    {
#ifdef WIN32
        MEMORYSTATUSEX vMemory;
        vMemory.dwLength = sizeof(MEMORYSTATUSEX);
        GlobalMemoryStatusEx(&vMemory);

        m_nVirtualMemory = vMemory.ullTotalVirtual / 1024;
#else
        struct sysinfo vMemory;
        sysinfo(&vMemory);
        
        m_nVirtualMemory = vMemory.totalswap * vMemory.mem_unit / 1024;   
#endif
    }
    nTotal = m_nVirtualMemory;
    return 0;
}

int DataAcquisition::VirtualMemoryFree(ULLong &nFree)
{
    nFree = 0;    

#ifdef WIN32
    MEMORYSTATUSEX vMemory;
    vMemory.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&vMemory);

    if(m_nVirtualMemory == 0)
        m_nVirtualMemory = vMemory.ullTotalVirtual / 1024;
    nFree = vMemory.ullAvailVirtual / 1024; 
#else
    struct sysinfo vMemory;
    sysinfo(&vMemory); 

    if(m_nVirtualMemory == 0)
        m_nVirtualMemory = vMemory.totalswap * vMemory.mem_unit / 1024; 
    nFree = vMemory.freeswap * vMemory.mem_unit / 1024; 
#endif
    return 0;
}

int DataAcquisition::VirtualMemroyUsageByProcess(ULLong &nUsage, int nPid)
{
    nUsage = 0; 

#ifdef WIN32
    PROCESS_MEMORY_COUNTERS pMemCounter; 
    GetProcessMemoryInfo(nPid == -1 ? GetCurrentProcess() : TheProcessByID(nPid), &pMemCounter, sizeof(PROCESS_MEMORY_COUNTERS)); 

    nUsage = pMemCounter.PagefileUsage / 1024;
#else  
    if(nPid == 0)
        return -1;
    if(nPid <= -1)
        nPid = getpid(); 

    char buf[32] = { 0 };
    sprintf(buf, "ps p %i -o vsz h", nPid); 
    vector<string> vResult;
    ExecuteCommand(buf, vResult);
    
    if(vResult.size() == 0)
        return -1; 
     
    sscanf(vResult[0].c_str(), "%llu", &nUsage); 
#endif
    return 0;
}
/*------ Memory End ------*/


/*------Disk Start------*/
int    DataAcquisition::DiskCount()
{
    int nCount = 1;//At Least 1

#ifdef WIN32
    HDEVINFO hDeviceInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL,  DIGCF_PRESENT);
    if (hDeviceInfoSet == INVALID_HANDLE_VALUE)   
        return nCount; 
   
    SP_DEVINFO_DATA deviceInfoData;
    deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 
    DWORD nDeviceIndex  = 0;   
    while(SetupDiEnumDeviceInfo(hDeviceInfoSet, nDeviceIndex, &deviceInfoData)) 
        nDeviceIndex++;   
    if(hDeviceInfoSet)
        SetupDiDestroyDeviceInfoList(hDeviceInfoSet); 
    nCount = nDeviceIndex;
#else
    //lsblk -nd | grep -w disk
    vector<string> vResult;
    ExecuteCommand("lsblk -dn | grep -w disk", vResult);
    int nSize = vResult.size();
    if(nSize > 0)
        return nSize;
#endif
    return nCount;
}

int    DataAcquisition::DriveLetterCount()
{ 
    int nCount = 0;

#ifdef WIN32 
    //Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on.
    DWORD nDrive = GetLogicalDrives();
    while(nDrive)
    {
        if(nDrive & 1) 
             ++nCount;
        nDrive >>= 1;
    } 
#else
    //df --output=target
    vector<string> vResult;
    ExecuteCommand("df --output=target", vResult);
    int nSize = vResult.size();
    if(nSize > 0)
        return nSize - 1;
#endif
    return nCount;
}    

int DataAcquisition::TheDiskCapacityInfo(vector<CapacityInfo*> &vCapacityInfo)
{
    vCapacityInfo.clear();    

#ifdef WIN32
    int nPhsicalDriveCount = DiskCount();
    while(nPhsicalDriveCount-- > 0)
    {
        char szPhysicalDrive[32] = { 0 };
        sprintf(szPhysicalDrive, "\\\\.\\PhysicalDrive%d", nPhsicalDriveCount);  

        HANDLE hDevice = CreateFile(szPhysicalDrive, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
        if (hDevice == INVALID_HANDLE_VALUE)
            return -1;
 
        DWORD nReturn = 0;
        DISK_GEOMETRY outBuffer; 
        if(DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &outBuffer, sizeof(DISK_GEOMETRY), &nReturn, (LPOVERLAPPED)NULL)) 
        {
            CapacityInfo *pCI = new CapacityInfo();
            pCI->m_nTotal = outBuffer.Cylinders.QuadPart * (ULONG)outBuffer.TracksPerCylinder * (ULONG)outBuffer.SectorsPerTrack * (ULONG)outBuffer.BytesPerSector / 1024; 
            vCapacityInfo.push_back(pCI);
        }
        CloseHandle(hDevice);   
    }    
#else
    //lsblk -ndbo name,size,type | grep -w disk | awk -F ‘ ‘ ‘{print $1, $2 / 1024}‘
    vector<string> vResult;
    ExecuteCommand("lsblk -ndbo name,size,type | grep -w disk | awk -F ‘ ‘ ‘{print $1, $2 / 1024}‘", vResult);

    if(vResult.size() == 0)
        return -1;

    for(vector<string>::iterator item = vResult.begin(); item != vResult.end(); item++)
    {
        CapacityInfo *pCI = new CapacityInfo();
        sscanf(item->c_str(), "%s %llu", pCI->m_szName, &pCI->m_nTotal); 
        vCapacityInfo.push_back(pCI);
    }
#endif
    return 0;
}
    
int DataAcquisition::TheDriveLetterCapacityInfo(vector<CapacityInfo*> &vCapacityInfo, const char* szDriveLetter)
{
    vCapacityInfo.clear();    

#ifdef WIN32  
    int nDriveCount = 0, nIndex = 0;
    if(szDriveLetter == NULL) 
        nDriveCount = DriveLetterCount();

    char szDriveLetterFormat[4] = { 0 };
    ULARGE_INTEGER atc, nTotal, nFree; 
    do
    {
        if(szDriveLetter == NULL) 
            sprintf(szDriveLetterFormat, "%c:\\", C_DRIVERLETTER + nIndex++);

        UINT nType = GetDriveType(szDriveLetter == NULL ? szDriveLetterFormat : szDriveLetter);
        if(nType != DRIVE_REMOVABLE && nType != DRIVE_FIXED) 
            continue; 

        if(GetDiskFreeSpaceEx(szDriveLetter == NULL ? szDriveLetterFormat : szDriveLetter, &atc, &nTotal, &nFree))
        { 
            CapacityInfo *pCI = new CapacityInfo();
            pCI->m_nTotal = nTotal.QuadPart / 1024;
            pCI->m_nFree = nFree.QuadPart / 1024;
            strncpy(pCI->m_szName, szDriveLetter == NULL ? szDriveLetterFormat : szDriveLetter, strlen(szDriveLetter == NULL ? szDriveLetterFormat : szDriveLetter));
            vCapacityInfo.push_back(pCI);
        } 

        if(szDriveLetter != NULL) 
            break;

    }while(nIndex < nDriveCount);
#else
    vector<string> vResult;
    //all of mounted partitions
    if(szDriveLetter == NULL)
    {
        //df -l | grep -E ‘^/|/mnt/‘
        ExecuteCommand("df -l | grep -E ‘^/|/mnt/‘", vResult); 
    }
    else//just the special one
    {
        //df -l | grep -w {szPartition}
        if(szDriveLetter[0] != /)
            return -1;
        string cmd("df -l | grep -w ");
        cmd.append(szDriveLetter);
        ExecuteCommand(cmd.c_str(), vResult);    
        printf(cmd.c_str());
    }
    
    if(vResult.size() == 0)
        return -1;
        
    for(vector<string>::iterator item = vResult.begin(); item != vResult.end(); item++)
    {
        CapacityInfo *pCI = new CapacityInfo();
        sscanf(item->c_str(), "%*s %llu %*llu %llu %*i%% %s", &pCI->m_nTotal, &pCI->m_nFree, pCI->m_szName);  
        vCapacityInfo.push_back(pCI);
    }  
#endif
    return 0;
}    
/*------ Disk End ------*/


/*------Process Start------*/
int DataAcquisition::OpenTheFile(const char* szFile, const char* szParameters)
{
#ifdef WIN32
    ShellExecute(NULL, "open", szFile, szParameters, NULL, SW_SHOWNORMAL);
    return 0;
#else 
    //execve(szFile, argv, envp);
    string cmd(szFile);
    if(szParameters != NULL)
    {
        cmd.append(" ");
        cmd.append(szParameters);
    }
    return system(cmd.c_str());
#endif
}

int DataAcquisition::Processes(vector<ProcessInfo*> &vProcessInfo, int nPid)
{
    vProcessInfo.clear();

#ifdef WIN32
    AdjustTokenPrivilege(GetCurrentProcess());

    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  
    if (hSnapshot == INVALID_HANDLE_VALUE) 
        return -1; 
     
    PROCESSENTRY32 proEntry32; 
    proEntry32.dwSize = sizeof(PROCESSENTRY32);
    if(!Process32First(hSnapshot, &proEntry32))
    {
        CloseHandle(hSnapshot);
        return -1;
    } 

    while(Process32Next(hSnapshot, &proEntry32))
    {    
        if(nPid != -1)
        {
            if(proEntry32.th32ProcessID != nPid)
                continue;
        }
        ProcessInfo *pi = new ProcessInfo(); 
        pi->m_nPid = proEntry32.th32ProcessID;  
        strncpy(pi->m_szName, proEntry32.szExeFile, strlen(proEntry32.szExeFile));
        //WideCharToMultiByte(CP_ACP, 0, proEntry32.szExeFile, -1, pi.m_szName, sizeof(pi.m_szName), NULL, NULL);

        HANDLE theProcess = TheProcessByID(proEntry32.th32ProcessID);
        DWORD dwSize = sizeof(pi->m_szFileName);
        QueryFullProcessImageName(theProcess, 0/*PROCESS_NAME_NATIVE or 0*/, pi->m_szFileName, &dwSize); 
        if(dwSize > 0)
        {
                /*
                    Comments  InternalName  ProductName  CompanyName  LegalCopyright  ProductVersion
                    FileDescription  LegalTrademarks  PrivateBuild  FileVersion  OriginalFilename  SpecialBuild
                */
            DWORD nHandle = 0;
            DWORD nSize = GetFileVersionInfoSize(pi->m_szFileName, &nHandle); 
            if(nSize > 0)
            {
                char *szVersionInfo = new char[nSize + 1]();
                if(GetFileVersionInfo(pi->m_szFileName, 0, nSize + 1, szVersionInfo))
                {
                    DWORD *nLangCode = NULL;
                    UINT nLen = 0;
                    VerQueryValue(szVersionInfo, "\\VarFileInfo\\Translation", (LPVOID*)&nLangCode, &nLen); 
        
                    char szDes[64] = { 0 }; 
                    sprintf(szDes, "\\StringFileInfo\\%04x%04x\\FileDescription", LOWORD(nLangCode[0]), HIWORD(nLangCode[0]));

                    UINT nLenFileDes = 0;
                    char *szFileDes = NULL;
                    VerQueryValue(szVersionInfo, szDes, (LPVOID*)&szFileDes, &nLenFileDes); 
                    memcpy(pi->m_szDescribe, szFileDes, nLenFileDes);
                        //WideCharToMultiByte(CP_ACP, 0, proEntry32.szExeFile, -1, pi.m_szName, sizeof(pi.m_szName), NULL, NULL); 

                        //char szPN[64] = { 0 }; 
                        //sprintf(szPN, "\\StringFileInfo\\%04x%04x\\ProductName", LOWORD(nLangCode[0]), HIWORD(nLangCode[0]));

                        //UINT nLenProName = 0;
                        //char *szProName = NULL;
                        //VerQueryValue(szVersionInfo, szPN, (LPVOID*)&szProName, &nLenProName);  
                        //pi->m_pProductName = new char[nLenProName + 1]();
                        ////WideCharToMultiByte(CP_ACP, 0, proEntry32.szExeFile, -1, pi.m_szName, sizeof(pi.m_szName), NULL, NULL); 
                        //memcpy(pi->m_pProductName, szProName, nLenProName);
                }
                delete[] szVersionInfo;
            }
        } 
        FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime; 
        if(GetProcessTimes(theProcess, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime))
        {
            //or ULARGE_INTEGER uiStart;
            //     memcpy(&uiStart, &creationTime, sizeof(ULARGE_INTEGER)); 
            FILETIME ftNowTime;
            GetSystemTimeAsFileTime(&ftNowTime);
            pi->m_nRunTime = (reinterpret_cast<ULARGE_INTEGER*>(&ftNowTime)->QuadPart - reinterpret_cast<ULARGE_INTEGER*>(&ftCreationTime)->QuadPart) / ELAPSEDSECONDS;

            FILETIME ftLocalCreationTime;
            FileTimeToLocalFileTime(&ftCreationTime, &ftLocalCreationTime);
            SYSTEMTIME stLocalUTC8CreationTime;
            FileTimeToSystemTime(&ftLocalCreationTime, &stLocalUTC8CreationTime);
            pi->m_nStartTime_Year = stLocalUTC8CreationTime.wYear;
            pi->m_nStartTime_Month = stLocalUTC8CreationTime.wMonth;
            pi->m_nStartTime_Day = stLocalUTC8CreationTime.wDay;
            pi->m_nStartTime_Hour = stLocalUTC8CreationTime.wHour;
            pi->m_nStartTime_Minute = stLocalUTC8CreationTime.wMinute;
            pi->m_nStartTime_Second = stLocalUTC8CreationTime.wSecond;            
        }
        vProcessInfo.push_back(pi); 

        if(nPid != -1) 
            break; 
    }
    CloseHandle(hSnapshot);
#else 
    static map<string, int> Month = { };
    if(Month.size() == 0)
    {
        Month["Jan"] = 1;Month["Feb"] = 2; Month["Mar"] = 3; Month["Apr"] = 4; Month["May"] = 5; Month["Jun"] = 6; 
        Month["Jul"] = 7; Month["Aug"] = 8; Month["Sep"] = 9; Month["Oct"] = 10; Month["Nov"] = 11; Month["Dec"] = 12; 
    }

    DIR *dir = opendir("/proc");
    if(dir == NULL)
        return -1;

    char cmd[128] = { 0 };
    char month[4] = { 0 };
    vector<string> vResult;
    struct dirent *dirEnt;
    while(dirEnt = readdir(dir))
    {
        if(dirEnt->d_type != DT_DIR)
            continue;

        pid_t pid = (pid_t)atoi(dirEnt->d_name);
        if(pid <= 0)
            continue;
        
        //ps -p 950 -o pid,etimes,lstart h
        sprintf(cmd, "ps -p %i -o etimes,lstart h", pid);
        ExecuteCommand(cmd, vResult);

        ProcessInfo *pi = new ProcessInfo();  

        if(vResult.size() > 0)
        {
            sscanf(vResult[0].c_str(), "%llu %*s %s %d %d:%d:%d %d", &pi->m_nRunTime, month, &pi->m_nStartTime_Day, &pi->m_nStartTime_Hour, &pi->m_nStartTime_Minute, &pi->m_nStartTime_Second, &pi->m_nStartTime_Year);
            pi->m_nStartTime_Month = Month[string(month)]; 
        } 
        sprintf(cmd, "/proc/%i/exe", pid);
        readlink(cmd, pi->m_szFileName, sizeof(pi->m_szFileName));
        int nLength = strlen(pi->m_szFileName);
        if(nLength > 0)   
            strncpy(pi->m_szName, basename(pi->m_szFileName), nLength); 
        else
        {
            sprintf(cmd, "cat /proc/%i/comm", pid);
            ExecuteCommand(cmd, vResult);
            if(vResult.size() > 0) 
                strncpy(pi->m_szName, vResult[0].c_str(), strlen(vResult[0].c_str()));  
            else
                printf("%d %s\n", pid, "No Result.");
        }
        pi->m_nPid = static_cast<unsigned short>(pid);
        vProcessInfo.push_back(pi); 
    } 
    closedir(dir);
#endif
    return 0;
}

int DataAcquisition::TheProcessIDByName(const char* szProcessName, int &nPid)
{
    nPid = -1;

#ifdef WIN32
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    if (hSnapshot == INVALID_HANDLE_VALUE) 
        return -1; 

    PROCESSENTRY32 process; 
    process.dwSize = sizeof(PROCESSENTRY32); 
    if(!Process32First(hSnapshot, &process))
    {
        CloseHandle(hSnapshot);
        return -1;
    } 
    while(Process32Next(hSnapshot, &process))
    {  
        if (strcmp(process.szExeFile, szProcessName) == 0)
        { 
            nPid = process.th32ProcessID;
            break;
        }
    } 
    CloseHandle(hSnapshot); 
#else  
    DIR *dir = opendir("/proc");
    if(dir == NULL)
        return -1;
    
    struct dirent *dirEnt;
    vector<string> vResult;
    while(dirEnt = readdir(dir))
    {
        if(dirEnt->d_type != DT_DIR)
            continue;

        pid_t pid = (pid_t)atoi(dirEnt->d_name);
        if(pid <= 0)
            continue;
        /* also ls -l /proc/{pid}/exe  (better)
            //  http://man7.org/linux/man-pages/man2/readlink.2.html
        */
        //Not Recommended (/proc/{pid}/cmdline)
        string cmdPath = string("/proc/") + dirEnt->d_name + "/cmdline";    
        OpenTheFileWithMode(cmdPath.c_str(), vResult);  
        
        if(vResult.size() == 0)
            continue;     
        /*
        if(strlen(vResult[0].c_str()) >= TASK_COMM_LEN)
            vResult[0][TASK_COMM_LEN] = ‘\0‘;
        if(strcmp(szProcessName, vResult[0].c_str()) != 0)
                continue;
        */
        /*The code below has a bug!!!
            also cout << strrchr(vResult[0].c_str(), ‘/‘) + 1 << endl;
         */
        string::size_type pos = vResult[0].rfind(/);
        if(pos != string::npos)
        {
            if(string(szProcessName) != vResult[0].substr(pos + 1))
                continue;
        }
        else
        { 
            if(strcmp(szProcessName, vResult[0].c_str()) != 0)
                continue;
        }
        
        nPid = pid;
        break;
    } 
    closedir(dir);
#endif
    return 0;
}
/*------ Process End ------*/


/*------PC Start------*/
bool DataAcquisition::Ping(const char *szIPAddress)
{
#ifdef WIN32    
    string cmd("cmd /C ping -n 3 -w 1024 ");
    cmd.append(szIPAddress); 
    //WinExec(cmd.c_str(), SW_HIDE); 
    return system(cmd.c_str()) == 0;
#else
    string cmd("ping -c 3 -W 1 ");
    cmd.append(szIPAddress);
    cmd += " | grep received";
    cmd += " | awk -F , ‘{ print $2 }‘ | awk ‘{ print $1 }‘";
    vector<string> vResult;
    ExecuteCommand(cmd.c_str(), vResult);
    if(vResult.size() == 0)
        return false;
    if(vResult[0] == "0")
        return false;
    return true; 
#endif 
}

int    DataAcquisition::TheHostName(char* szHostName, unsigned long &nLength)
{
#ifdef WIN32  
    if(!GetComputerName(szHostName, &nLength)) //char*,DWORD*
        return -1; 
#else    
    if(gethostname(szHostName, nLength) == 0)
        nLength = strlen(szHostName);
    else return -1;
#endif
    return 0;
}

int DataAcquisition::TheUserName(char* szUserName, unsigned long &nLength)
{
#ifdef WIN32
    if(!GetUserName(szUserName, &nLength))//(w)char*,DWORD*
        return -1;
#else
    /* also getlogin()
    */
    if(getlogin_r(szUserName, nLength) == 0)
        nLength = strlen(szUserName);
    else return -1;
#endif
    return 0;
}

int DataAcquisition::TheHostIPAddress(vector<string> &vIPAddress, unsigned short nFamily)
{
    vIPAddress.clear();

#ifdef WIN32 
    DWORD nSize = 0; 
    IP_ADAPTER_ADDRESSES *pAdapterAddress = NULL;
    GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAddress, &nSize); 
    pAdapterAddress = (IP_ADAPTER_ADDRESSES*)malloc(nSize); 
    if(GetAdaptersAddresses(nFamily, GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAddress, &nSize) != ERROR_SUCCESS) 
    {
        free(pAdapterAddress);
        return -1;
    } 

    IP_ADAPTER_ADDRESSES *pAdapter = pAdapterAddress; 
    for(; pAdapter; pAdapter = pAdapter->Next)
    {
        // Skip loopback adapters
        if (IF_TYPE_SOFTWARE_LOOPBACK == pAdapter->IfType) 
          continue;  
        // Parse all IPv4 and IPv6 addresses
        for(IP_ADAPTER_UNICAST_ADDRESS* pAddress = pAdapter->FirstUnicastAddress; pAddress; pAddress = pAddress->Next)
        {
            auto family = pAddress->Address.lpSockaddr->sa_family;
            if (AF_INET == family)
            {
                // IPv4
                SOCKADDR_IN* Ipv4 = reinterpret_cast<SOCKADDR_IN*>(pAddress->Address.lpSockaddr);
                vIPAddress.push_back(inet_ntoa(Ipv4->sin_addr));
                //char v4Buf[16] = { 0 };
                //InetNtop(AF_INET, &(Ipv4->sin_addr), v4Buf, sizeof(v4Buf));  
                //vIPAddress.push_back(string(v4Buf));
            }
            else if(AF_INET6 == family)
            {
                // IPv6
                SOCKADDR_IN6* Ipv6 = reinterpret_cast<SOCKADDR_IN6*>(pAddress->Address.lpSockaddr); 
                char v6Buf[64] = { 0 }; 
                DWORD nAddrSize = sizeof(sockaddr_storage);
                WSAAddressToString((LPSOCKADDR)Ipv6, nAddrSize, NULL, v6Buf, &nAddrSize);
                //WCHAR  v6Buf[64] = { 0 }; 
                //InetNtop(AF_INET6, &(Ipv6->sin6_addr), v6Buf, sizeof(v6Buf));  
                vIPAddress.push_back(string(v6Buf));
            }
        }
    }
    free(pAdapterAddress);
#else 
      /* also https://linux.die.net/man/3/getnameinfo
    */
    addrinfo hints, *result, *next; 
      memset(&hints, 0, sizeof(hints));
      hints.ai_family = nFamily;//PF_UNSPEC (IPv4 r IPv6)
      hints.ai_flags |= AI_CANONNAME;
      hints.ai_socktype = SOCK_STREAM;//SOCK_DGRAM
 
    char szHostName[256] = { 0 };
    unsigned long length = sizeof(szHostName);
    TheHostName(szHostName, length);
    
      if(getaddrinfo(szHostName, NULL, &hints, &result) != 0) 
          return -1; 
          
      char szAddress[128] = { 0 };
    for(next = result; next != NULL; next = next->ai_next)
    {
        void *addr;
        switch(next->ai_family)
        {
            case AF_INET:
                  addr = &(((sockaddr_in*)next->ai_addr)->sin_addr);
              break;
            case AF_INET6:
                  addr = &(((sockaddr_in6*)next->ai_addr)->sin6_addr);
              break;
        }        
        //convert ip address to human-readable form
          inet_ntop(next->ai_family, addr, szAddress, sizeof(szAddress));
          vIPAddress.push_back(string(szAddress));
    }
       freeaddrinfo(result);
    return vIPAddress.size(); 
#endif
    return 0;
}
/*------ PC End ------*/


#ifdef WIN32

#else

#endif
View Code

 

以上是关于一个Window/Linux(Fedora测试平台)的CPU,磁盘,内存,PC,进程相关信息采集功能的主要内容,如果未能解决你的问题,请参考以下文章

fedora30平台安装docker 19.03

Fedora 25 (linux平台)开源的PDF文件编辑工具——PDF mod

Fedora 25文件对比目录对比工具——Meld——Linux平台的对比工具

sh 在fedora上使用rbenv安装rails的脚本(正在进行跨平台工作)

在 CentOS/Fedora 下安装 JAVA 环境

总结Fedora 22跨版本升级到Fedora 24方法