The following is a complete example that demonstrates how to obtain statistics data asynchronously using PrlSrv_SubscribeToHostStatistics. Note that the same code could be used to receive statistics data for a virtual machine, instead of the host computer, by using PrlVm_SubscribeToGuestStatistics instead of PrlSrv_SubscribeToHostStatistics, and passing it a handle to a virtual machine that is running. This would also require using PrlVm_UnsubscribeFromGuestStatistics to stop receiving statistics data for the virtual machine.
#include "Parallels.h" #include "Wrappers/SdkWrap/SdkWrap.h" #include <stdio.h> #ifdef _WIN_ #include <windows.h> #else #include <unistd.h> #endif const char *szServer = "123.123.123.123"; const char *szUsername = "Your Username"; const char *szPassword = "Your Password"; // ------------------------------------------------------------------------- // Event handler. // ------------------------------------------------------------------------- // 1. Check for events of type PET_DSP_EVT_HOST_STATISTICS_UPDATES. // 2. Display a header if first call to this event handler. // 3. Get the event param (PHT_EVENT_PARAMETER) from the PHT_EVENT handle. // 4. Convert event param to a handle (will be type PHT_SYSTEM_STATISTICS). // 5. Use PHT_SYSTEM_STATISTICS handle to obtain CPU usage, memory usage, // and disk usage data. // ------------------------------------------------------------------------- static PRL_RESULT OurCallback(PRL_HANDLE handle, void *pData) { PRL_HANDLE_TYPE nHandleType; PRL_RESULT ret = PrlHandle_GetType(handle, &nHandleType); // Check for PrlHandle_GetType error here. if (nHandleType == PHT_EVENT) { PRL_EVENT_TYPE EventType; PrlEvent_GetType(handle, &EventType); // Check if the event type is a statistics update. if (EventType == PET_DSP_EVT_HOST_STATISTICS_UPDATED) { // Output a header if first call to this function. static PRL_BOOL bHeaderHasBeenPrinted = PRL_FALSE; if (!bHeaderHasBeenPrinted) { bHeaderHasBeenPrinted = PRL_TRUE; printf("CPU (%%) Used RAM (MB) Free RAM (MB) Used Disk Space (MB)" " Free Disk Space (MB)\n"); printf("---------------------------------------------------------" "--------------------\n"); } PRL_HANDLE hEventParameters; PRL_HANDLE hServerStatistics; // Get the event parameter (PHT_EVENT_PARAMETER) from the event handle. PrlEvent_GetParam(handle, 0, &hEventParameters); // Convert the event parameter to a handle (PHT_SYSTEM_STATISTICS). PrlEvtPrm_ToHandle(hEventParameters, &hServerStatistics); // Get CPU statistics (usage in %). PRL_HANDLE hCpuStatistics; ret = PrlStat_GetCpuStat(hServerStatistics, 0, &hCpuStatistics); PRL_UINT32 nCpuUsage = 0; ret = PrlStatCpu_GetCpuUsage(hCpuStatistics, &nCpuUsage); // Get RAM statistics. PRL_UINT64 nUsedRam, nFreeRam; PrlStat_GetFreeRamSize(hServerStatistics, &nFreeRam); PrlStat_GetUsageRamSize(hServerStatistics, &nUsedRam); nUsedRam /= (1024 * 1024); nFreeRam /= (1024 * 1024); // Get disk space statistics. PRL_UINT64 nFreeDiskSpace, nUsedDiskSpace; PRL_HANDLE hDiskStatistics; PrlStat_GetDiskStat(hServerStatistics, 0, &hDiskStatistics); PrlStatDisk_GetFreeDiskSpace(hDiskStatistics, &nFreeDiskSpace); PrlStatDisk_GetUsageDiskSpace(hDiskStatistics, &nUsedDiskSpace); nUsedDiskSpace /= (1024 * 1024); nFreeDiskSpace /= (1024 * 1024); printf("%7d %10lld %13lld %20lld %20lld\n", nCpuUsage, nUsedRam, nFreeRam, nUsedDiskSpace, nFreeDiskSpace); PrlHandle_Free(hDiskStatistics); PrlHandle_Free(hCpuStatistics); PrlHandle_Free(hServerStatistics); PrlHandle_Free(hEventParameters); } } PrlHandle_Free(handle); return PRL_ERR_SUCCESS; } // ------------------------------- // Program entry point. // ------------------------------- int main(int argc, char* argv[]) { PRL_HANDLE hServer; PRL_RESULT ret; // Use the correct dynamic library depending on the platform. #ifdef _WIN_ #define SDK_LIB_NAME "prl_sdk.dll" #elif defined(_LIN_) #define SDK_LIB_NAME "libprl_sdk.so" #elif defined(_MAC_) #define SDK_LIB_NAME "libprl_sdk.dylib" #endif if (PRL_FAILED(SdkWrap_Load(SDK_LIB_NAME)) && PRL_FAILED(SdkWrap_Load("./" SDK_LIB_NAME))) { fprintf(stderr, "Failed to load " SDK_LIB_NAME "\n"); return -1; } // Initialize the Parallels API. ret = PrlApi_Init(PARALLELS_API_VER); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlApi_Init returned with error: %s.\n", PRL_RESULT_TO_STRING(ret)); PrlApi_Deinit(); SdkWrap_Unload(); return ret; } // Create a server handle. ret = PrlSrv_Create(&hServer); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlSvr_Create failed, error: %s", PRL_RESULT_TO_STRING(ret)); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } // Log in (PrlSrv is asynchronous). PRL_HANDLE hJob = PrlSrv_Login( hServer, // PRL_HANDLE of type PHT_SERVER. szServer, // Server hostname or IP address. szUsername, // Username. szPassword, // Password. 0, // Deprecated - UUID of previous session. 0, // Optional - port number (0 for default). 0, // Optional - timeout value (0 for default). PSL_LOW_SECURITY); // Security level ret = PrlJob_Wait(hJob, 1000); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlJob_Wait for PrlSrv_Login returned with error: %s\n", PRL_RESULT_TO_STRING(ret)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } // Analyze the result of PrlSrv_Login. PRL_RESULT nJobResult; ret = PrlJob_GetRetCode(hJob, &nJobResult); if (PRL_FAILED(nJobResult)) { printf("Login job returned with error: %s\n", PRL_RESULT_TO_STRING(nJobResult)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } else printf("Login was successful.\n"); // ---------------------------------------------------------------------------- // 1. Register our event handler (OurCallback function). // 2. Subscribe to host machine statistics events. // 3. Keep receiving events until user presses <enter> key. // 4. Unsubscribe from statistics events. // 5. Un-register out event handler. // ---------------------------------------------------------------------------- PrlSrv_RegEventHandler(hServer, OurCallback, NULL); PrlSrv_SubscribeToHostStatistics(hServer); char c; scanf(&c, 1); PrlSrv_UnsubscribeFromHostStatistics(hServer); PrlSrv_UnregEventHandler(hServer, OurCallback, NULL); // ---------------------------------------------------------------------------- // Log off. hJob = PrlSrv_Logoff(hServer); ret = PrlJob_Wait(hJob, 1000); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlJob_Wait for PrlSrv_Logoff returned error: %s\n", PRL_RESULT_TO_STRING(ret)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } ret = PrlJob_GetRetCode(hJob, &nJobResult); if (PRL_FAILED(ret)) { fprintf(stderr, "PrlJob_GetRetCode failed for PrlSrv_Logoff with error: %s\n", PRL_RESULT_TO_STRING(ret)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } // Report success or failure of PrlSrv_Logoff. if (PRL_FAILED(nJobResult)) { fprintf(stderr, "PrlSrv_Logoff failed with error: %s\n", PRL_RESULT_TO_STRING(nJobResult)); PrlHandle_Free(hJob); PrlHandle_Free(hServer); PrlApi_Deinit(); SdkWrap_Unload(); return -1; } else printf("Logoff was successful.\n"); // Free handles that are no longer required. PrlHandle_Free(hJob); PrlHandle_Free(hServer); // De-initialize the Parallels API, and unload the SDK. PrlApi_Deinit(); SdkWrap_Unload(); return 0; }