Ok, so I thought it would be pretty easy to write a widget that monitored CPU load for more than one core. Most, if not all, of the CPU monitoring widgets I've seen use Konfabulator's system.whatever method to get the CPU activity percentage, which returns only one value.
I started out using Win32_Processor, because it has more of the raw CPU properties that I want, and its use is a lot simpler than the performance counter classes.
var wbemLocator = COM.createObject( "WbemScripting.SWbemLocator" );
var wbemService = wbemLocator.ConnectServer( ".", "root/cimv2" );
var cimProc = wbemService.Get( 'Win32_Processor="cpu0"' );
print( oProc.Properties_.Item("LoadPercentage").Value );
This works fine, but I realized that there is no mechanism for refreshing the Win32_Processor instance (at least I haven't found one yet). No problem, I figured I would just grab a new object whenever my timer fired. This worked, in that the percentage got updated in the UI, but the call takes awhile, and the thread is blocked, so my widget locked Konfabulator up hard.
Decided to try the performance counter objects, which work with a refresher. At least the WMI layer wouldn't have to make a new object everytime.
var wbemLocator = COM.createObject( "WbemScripting.SWbemLocator" );
var wbemRefresher = COM.createObject( "WbemScripting.SWbemRefresher" );
var wbemService = wbemLocator.ConnectServer( ".", "root/cimv2" );
var colProcs = wbemRefresher.AddEnum( wbemService, "Win32_PerfFormattedData_PerfOS_Processor" ).ObjectSet;
wbemRefresher.Refresh();
for ( proc in colProcs )
print( proc.Properties_.Item("PercentProcessorTime").Value;
This code works fine in VB, but when I execute it in Konfabulator AddEnum throws an exception. Since it works in VB I did not think the error was coming up from WMI, so I put a try/catch block around it, and tried to create WbemScripting.SWbemLastError, and it failed. That's the defined behavior when there is no error, so it is something in Konfabulator, I guess, or something I need to do to one of the parameters before I pass it. I pass other strings to WMI without incident though, so that seems unlikely.
To try and get around this tomorrow I am going to implement SWbemService.ExecQueryAsynch(), and call this from my timer event handler to get a new object. I'll need to use a semaphore to govern the event handler while it is waiting for the method to complete. But I think this will be less than optimal because ExecQueryAsynch has got to be the slowest way to create a WMI instance. If SWbemService.Get was taking too long, this is likely to be worse. The asynch call will keep the widget from locking up, but I don't think the update granularity will be very good. This is the exact situation that calls for a refresher.
Anyone have a clue as to what I might try to get the AddEnum call to work in jscript from Konfabulator?
I started out using Win32_Processor, because it has more of the raw CPU properties that I want, and its use is a lot simpler than the performance counter classes.
var wbemLocator = COM.createObject( "WbemScripting.SWbemLocator" );
var wbemService = wbemLocator.ConnectServer( ".", "root/cimv2" );
var cimProc = wbemService.Get( 'Win32_Processor="cpu0"' );
print( oProc.Properties_.Item("LoadPercentage").Value );
This works fine, but I realized that there is no mechanism for refreshing the Win32_Processor instance (at least I haven't found one yet). No problem, I figured I would just grab a new object whenever my timer fired. This worked, in that the percentage got updated in the UI, but the call takes awhile, and the thread is blocked, so my widget locked Konfabulator up hard.
Decided to try the performance counter objects, which work with a refresher. At least the WMI layer wouldn't have to make a new object everytime.
var wbemLocator = COM.createObject( "WbemScripting.SWbemLocator" );
var wbemRefresher = COM.createObject( "WbemScripting.SWbemRefresher" );
var wbemService = wbemLocator.ConnectServer( ".", "root/cimv2" );
var colProcs = wbemRefresher.AddEnum( wbemService, "Win32_PerfFormattedData_PerfOS_Processor" ).ObjectSet;
wbemRefresher.Refresh();
for ( proc in colProcs )
print( proc.Properties_.Item("PercentProcessorTime").Value;
This code works fine in VB, but when I execute it in Konfabulator AddEnum throws an exception. Since it works in VB I did not think the error was coming up from WMI, so I put a try/catch block around it, and tried to create WbemScripting.SWbemLastError, and it failed. That's the defined behavior when there is no error, so it is something in Konfabulator, I guess, or something I need to do to one of the parameters before I pass it. I pass other strings to WMI without incident though, so that seems unlikely.
To try and get around this tomorrow I am going to implement SWbemService.ExecQueryAsynch(), and call this from my timer event handler to get a new object. I'll need to use a semaphore to govern the event handler while it is waiting for the method to complete. But I think this will be less than optimal because ExecQueryAsynch has got to be the slowest way to create a WMI instance. If SWbemService.Get was taking too long, this is likely to be worse. The asynch call will keep the widget from locking up, but I don't think the update granularity will be very good. This is the exact situation that calls for a refresher.
Anyone have a clue as to what I might try to get the AddEnum call to work in jscript from Konfabulator?