Determining CPU and RAM usage in a Silverlight 4 WIndows Sidebar Gadget - c#

I'm trying to write a Silverlight 4 Windows Sidebar Gadget that, among other things, can monitor the usage of each CPU core (as a percentage) and the usage of RAM (in bytes) of the host computer. I've tried using System.Management, but Visual Studio won't let me add it, as it's not part of Silverlight.
In the end, I'm looking for some method that simply returns the usage of a specific CPU core. Automatically detecting the number of cores would be a bonus. The same goes for RAM.
Extensive searching has led me to believe that this is possible through COM+ automation, but I'm clueless as to how. Any direction would be very much appreciated.

You can use System.Windows.Analytics class to get systems stats..
It has a AverageProcessorLoad which you can use to get the current CPU usage(Value between 0 and 1)
.And its for Silverlight only.
You can simply use it like this:
float averageCPUUsage = System.Windows.Analytics.AverageProcessorLoad;
float myAppCPUUsage = System.Windows.Analytics.AverageProcessLoad;// Get cpu usage by your current app.
Update
But from Silverlight this is as far as we can go.. for RAM and Processor count you will need to have somthing installed on the client side itself to tell you.. from browser you can't.

You can also take a look at sample of System.Windows.Analytics usage on this article.
A little fragment of code from that article that shows usage of System.Windows.Analytics:
public partial class Page : UserControl
{
Analytics analytics;
public Page()
{
InitializeComponent();
CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
}
void CompositionTarget_Rendering(object sender, EventArgs e)
{
if (analytics == null)
analytics = new Analytics();
}
}

Related

Insufficient memory to continue the execution of the program when trying to initialize array of InkCanvas in UWP

Here is my code:
public sealed partial class MainPage : Page
{
InkCanvas[] arrInkCanvas = null;
public MainPage()
{
this.InitializeComponent();
int i = 0;
arrInkCanvas = new InkCanvas[1000];
try
{
for (i = 0; i < 1000; i++)
{
arrInkCanvas[i] = new InkCanvas();
}
}
catch (Exception ex)
{
}
}
}
When i run this code in WPF app there's no problem , but in UWP it throws exception : "Insufficient memory to continue the execution of the program."
Is it bugs or something can anyone tells me ?
Thanks.
Windows OS will balance the memory located to the application based on RAM and OS configuration. You can check your app's memory configuration by MemoryManager (just as cFrozenDeath said) in following way:
public MainPage()
{
this.InitializeComponent();
var AppUsageLevel = MemoryManager.AppMemoryUsageLevel;
var AppMemoryLimit = MemoryManager.AppMemoryUsageLimit;
}
From my test, your app does run out of memory. You can do a simple test: In the for loop each time you new InkCanvas(), you can call MemoryManager.AppMemoryUsage and compare it with the MemoryManager.AppMemoryUsageLimit.
Could you let me know if you have any specific reason for creating UIElment in such a way? Win10 1.586 does provide a new API, TrySetAppMemoryUsageLimit, to set the app's memory limitation. However, based on internal discussion, this API only works for very limited scenario right now, such as VOIP application on mobile device. And the sample code and document for this API are not quite ready.
Looking into it, there is another post which looks similar, which suggests the limit might be at 128... which could be a limitation "by design"
If that is consistent - I have not tried it - why not creating a InkCanvas pool and reusing the InkCanvas once they are not in use? Unless you need them concurrently...
Also that would add speed as you would avoid recreating the inkcanvas and just reuse them.
So far, the code could remain consistent and you can enlarge the pool when the issue/limitation is fixed..

determining the current link speed of WiFi in C#

I am writing a program that does one thing, it finds out the current link speed of the wifi connection and reports it to the user in real time. the problem I am having is that it does not seem to be able to find out the current link speed, only the max link speed of the device (300 Mbps). the reason I am writing this is that I have a problem where, periodically the link speed will drop drastically (down to 1-2 Mbps) and I want to be able to see when that happens. with this code it will simply give me the maximum speed that the adapter supports, not the current link speed of the connection.
private void update(object state)
{
System.Net.NetworkInformation.NetworkInterface[] nics = null;
nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
long speed = 0;
string adapter = "";
foreach (System.Net.NetworkInformation.NetworkInterface net in nics)
{
if (net.Name.Contains("Wireless") || net.Name.Contains("WiFi") || net.Name.Contains("802.11") || net.Name.Contains("Wi-Fi"))
{
speed = net.Speed;
adapter = net.Name;
break;
}
}
string temp;
if (speed == 0)
{
temp = "There is currently no Wi-Fi connection";
}
else
{
temp = "Current Wi-Fi Speed: " + (speed / 1000000) + "Mbps on " + adapter;
}
if (label1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(update);
label1.Invoke(d, new object[] { temp });
}
else
{
label1.Text = temp;
}
}
this run by calling
System.Threading.Timer ticker = new System.Threading.Timer(update, label1, 0, 1000);
in the main method.
Considering that it literally took me the whole entire day to find what the solution to this was, I figured I'd at least show StackOverflow for future reference what I came across and what did and did not work for this question.
tl;dr: Scroll to the The Code section
What I found
Good ol' control panel
If you are looking for the really easy way to do this you can simply go and open Contol Panel. Depending on what version of Windows you are on (in my case I'm on Windows 8), the path to the page is Control Panel >> Network and Internet >> Network and Sharing Center and then you can click on the link next to "Connections: " which will give you a window that looks like what is below.
The current link speed is highlighted in red which in my case is 36.0 Mbps. Though, of course, this might not satisfy your original question if you were intending to integrate some code with the actual value.
WMI
With a mix of Googling and whatnot, I thought I might have found something in Windows Management Instrumentation.
Long story short, AFAIK, WMI does not have what we're looking for.
WMI, in short, is a giant object database (that
can also be queried through SQL) that allows you to query information about a
Windows machine such as process, disks, etc. In WMI, everything is
represented by a class with a series of instances each with a set of
properties.
Anyhow, WMI Explorer allows you to view all of this on your machine.
I (supposedly) found two classes on MSDN that might have the info on link speed but from WMI Explorer, there was nothing useful.
The first class, MSFT_NetAdapter, did not even show up in WMI Explorer on my machine.
The second class, Win32_NetworkAdapter, showed up in WMI Explorer, but the Speed property was still incorrect. The same network adapter was showing a value of 168000000 or 168 Mbps which is not right. Though I find this strange because there was already a MaxSpeed but it was blank.
Scratch WMI off the list.
Win32 P/Invoke
Yes, of course, the solution to everything is always calling unmanaged Win32 APIs using P/Invoke magic.
This is the route used to solve the problem.
Luckily, the IP_ADAPTER_ADDRESSES structure solves the problem. If you look at the MSDN page, it's a fairly large structure but what is important here is TransmitLinkSpeed which actually works.
Calling the GetAdaptersAddresses() function will return the actual structure.
Now, the actual C# P/Invoke code. Luckily, pinvoke.net already had interop for this function which I've added. This is all that was necessary.
The Code
Finally, here is your code patched up with the new P/Invoke black magic. I've made it work as a console application for demo purposes:
Using Statements:
using System;
using System.Threading;
Code:
class Program
{
private static void Main(string[] args)
{
Timer ticker = new Timer(Update, null, 0, 1000);
// Keep the main thread from dying
while (true)
{
Thread.Sleep(1000);
}
}
private static void Update(object state)
{
ulong speed = 0;
string adapter = "";
string[] nameSearches = { "Wireless", "WiFi", "802.11", "Wi-Fi" };
// The enum value of `AF_INET` will select only IPv4 adapters.
// You can change this to `AF_INET6` for IPv6 likewise
// And `AF_UNSPEC` for either one
foreach (IPIntertop.IP_ADAPTER_ADDRESSES net in IPIntertop.GetIPAdapters(IPIntertop.FAMILY.AF_INET))
{
bool containsName = false;
foreach (string name in nameSearches)
{
if (net.FriendlyName.Contains(name))
{
containsName = true;
}
}
if (!containsName) continue;
speed = net.TrasmitLinkSpeed;
adapter = net.FriendlyName;
break;
}
string temp;
if (speed == 0)
{
temp = "There is currently no Wi-Fi connection";
}
else
{
temp = string.Format("Current Wi-Fi Speed: {0} Mbps on {1}", (speed / 1000000.0), adapter);
}
Console.WriteLine(temp);
}
}
You are then going to be looking for the actual IPIntertop class that I updated. Since it's pretty big you can find it updated at pinvoke.net or on this PasteBin in case something goes down.
Bottom Line
Windows has a lot of APIs which are somewhat broken (WMI), can have a few "leaky abstractions" (.Net), or can be a pain to work with (Win32).
Sigh, that is a lot and I hope it helps.
I come accross the same issue, and need to get windows wifi link speed which is current negotiated.
and thanks to #Jaxrtech's WMI approach, that really works.
the correct class is CIM_NetworkAdapter(i'm using windows7), and query the speed column to get the current speed.
while wifi current negotiated speed is changing, this speed is changing too. i tested it, this matched ok.
select Description , DeviceID, Speed from CIM_NetworkAdapter
get:
D-Link DWA-140 RangeBooster N USB Adapter 17 285000000
Since no-one here mentioned it yet: why not use https://learn.microsoft.com/en-us/dotnet/api/system.net.networkinformation.networkinterface.speed?view=net-5.0#System_Net_NetworkInformation_NetworkInterface_Speed
This is, if the table on this site is correct included since .NET Framework 2.0 and seem to included in all other versions of .net including .net core.

How to get the battery usage of some apps in Windows phone 8?

I'm practicing on windows phone 8 samples. I've done finding the remaining battery percentage and remaining time by using the following codes,
using Windows.Phone.Devices.Power;
// Constructor
public MainPage()
{
InitializeComponent();
_battery = Battery.GetDefault();
_battery.RemainingChargePercentChanged += OnRemainingChargePercentChanged;
UpdateUI();
}
private void UpdateUI()
{
txtContent1.Text = string.Format("{0} %", _battery.RemainingChargePercent);
txtContent2.Text = string.Format("{0} hours", _battery.RemainingDischargeTime.TotalHours);
}
private void OnRemainingChargePercentChanged(object sender, object e)
{
UpdateUI();
}
But I don't know how to find the battery usage of an app or remaining time of application usage for example,
I don't know how to find the battery usage of Wifi or remaining time for using the Wifi.
or some other apps.
if somebody knows means please say!
There is no way you can do that on a physical device for many reasons.
Think of it - just because you are using WiFi, doesn't mean you will be only keeping the network on for background updates. You will most likely use it to download a music file, or a picture, or keep streaming online radio. Or you might as well launch a game.
The estimate that is given to you for the battery is based on the default metrics. It would be hard to restrict it to a very generic subset without exposing your app to many other indicators.

How Can I Hook a Youtube Video (Flash Player?) To Slow Down Playback?

The only good software I know which can decelerate and accelerate the playback of a YouTube video in any browser without first downloading it (because that would be cumbersome), is Enounce MySpeed.
Unfortunately, this software is not free, and my trial version ran out. I was playing around with its registry settings and noticed a few keys:
ProgramsToHook: iexplore.exe;firefox.exe;plugin-container.exe;chrome.exe;safari.exe;opera.exe;maxthon.exe;feeddemon.exe;realplay.exe;flvplayer.exe;flv player.exe;flock.exe;adobe media player.exe
UseFlashAdapter: 1
LLModules: ole32.dll;nspr4.dll;chrome.exe;realplay.exe;objb3201.dll;oleaut32.dll;rpflashplayer.dll
ModulesToIntercept: flash10*;flash9*;npswf32.dll;gcswf32.dll;fldbg10*;flashplayer.3.1.1k.ocx;adobe media player.exe
Based on the names and values of these registry keys, I'm guessing the MySpeed software hooks some function(s) in the listed modules (but modules are or aren't the same as DLLs?..) and does so for each process listed in ProgramsToHook. This is what I don't understand. What is the concept of the MySpeed software. Obviously it's hooking something, but I'm not too familiar with the intricacies of Windows hooks so I came to ask you experts. I'm thinking if I can understand how this hook process works, I can make my own version of the software using EasyHook, which is a fantastic .NET library to perform user-mode and kernel-mode hooks.
I thought that Windows user-mode hooking goes something like this. You choose one function in one DLL, and you intercept that function (a.k.a hook) in one process you want. If you want to hook the DLL in multiple processes, you just have to repeat the procedure for each process.
And then kernel-mode hooking is just choosing one function in one DLL and intercepting that function in every process that calls it (hence kernel-mode). But surely there are tons of ways to hook; I'm not too sure on whats the difference between these two hooks and DLL injection either.
So the point is, I'd like to know how MySpeed works. What is their hooking concept? If I can know this then I can make such a software in .NET!
Thanks in advance.
I can't provide you with an accurate explanation as I don't know the API calls or capabilites, but it goes something like this:
You app looks for iexplore.exe where it intercepts calls to certain modules. The module is mainly flash player. Flash has support for playing the video slower so you modify the call from iexplore.exe (JavaScript play button on webpage) or make an additional call to set playback speed.
What you need to do:
Use this tool to check what is actually happening: http://www.nektra.com/products/deviare-api-hook-windows/
Learn how to ask Flash Player to slow down a video (probably in Flash API docs). One Simple approach could be to see what MySpeed is actually doing using the Deviare API hook tool.
Write a program that replicates this procedure. It involves intercepting messages sent from one handle (iexplore.exe) to another (flash .dll). This can't be done externally, it has to be done internally, so this may be of help: http://www.codeproject.com/KB/threads/winspy.aspx
On hooks: http://msdn.microsoft.com/en-gb/library/ms644960.aspx
I don't think many people has done this in C#, so it could offer a challenge. I would though be interested in the progress (obstacles) if you have a blog or something to share the gory details on. :)
EDIT: The Deviare API Hook software seems not only to spy on calls, but also allow you to intercept them. So its a all-in-one package for your needs. :)
EDIT2: Relevant question: How do I intercept messages being sent to a window?
The key to speeding up or slowing down a video is to convince multimedia players that your computer is slower or faster than it really is. This can be accomplished hooking timeGetTime().
This is an extremely easy C# code to accomplish it:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Nektra.Deviare2;
namespace DeviareTest
{
public partial class Form1 : Form
{
private int nSpeed;
private uint nTime;
private NktSpyMgr _spyMgr;
public Form1()
{
InitializeComponent();
_spyMgr = new NktSpyMgr();
_spyMgr.Initialize();
_spyMgr.OnFunctionCalled += new DNktSpyMgrEvents_OnFunctionCalledEventHandler(OnFunctionCalled);
}
private void Form1_Load(object sender, EventArgs e)
{
NktHook hook = _spyMgr.CreateHook("WINMM.dll!timeGetTime", (int)(eNktHookFlags.flgOnlyPostCall));
hook.Hook(true);
bool bProcessFound = false;
NktProcessesEnum enumProcess = _spyMgr.Processes();
NktProcess tempProcess = enumProcess.First();
while (tempProcess != null)
{
if (tempProcess.Name.Equals("iexplore.exe", StringComparison.InvariantCultureIgnoreCase) && tempProcess.PlatformBits == 32)
{
hook.Attach(tempProcess, true);
bProcessFound = true;
}
tempProcess = enumProcess.Next();
}
if(!bProcessFound)
{
MessageBox.Show("Please run \"iexplore.exe\" before!", "Error");
Environment.Exit(0);
}
}
private void OnFunctionCalled(NktHook hook, NktProcess process, NktHookCallInfo hookCallInfo)
{
nTime++;
if (nSpeed==-2)
hookCallInfo.Result().LongVal = hookCallInfo.Result().LongVal - (int)(nTime * 0.2);
else if(nSpeed==2)
hookCallInfo.Result().LongVal = hookCallInfo.Result().LongVal + (int)(nTime * 3);
}
private void SlowButton_CheckedChanged(object sender, EventArgs e)
{
nSpeed = -2;
}
private void FastButton_CheckedChanged(object sender, EventArgs e)
{
nSpeed = 2;
}
}
}
I just published an article with a code example showing how to do this with the Deviare hooking engine. The sample code only works with the video part (not audio) and it is available here.
Youtube now has an html5 player with playback speed controls.
All you have to do is enable html5 here http://www.youtube.com/html5
Only some of the videos support the html5 player yet, though.
Hope this helps.
The key to speeding up or slowing down a video is to convince multimedia players that your computer is slower or faster than it really is
manipulating the system time will be a VERY dangerous and idiotic thing to do - not only will you break user-mode threadslices and hence have a serious impact on system-performance but you also will break many logging-functionalities and even user-mode reflectors which control KM-drivers ... this could both crash and physically harm (!) your system because modern hardware is programmable, given the correct (& proprietary, of course) set of func-calls and such. I would highly advise to NOT do reproduce this, even a few AV-apps will intercept this because of its dangerous nature.
But you're somewhat lucky : the kernel uses its own time, synced to hardware so windows itself COULD remain stable for a limited amount of time.
I think you should get back to the drawing-board, manipulating essential structures of your operating-system certainly is not the right way to accomplish your goal.

Process Memory Size - Different Counters

I'm trying to find out how much memory my own .Net server process is using (for monitoring and logging purposes).
I'm using:
Process.GetCurrentProcess().PrivateMemorySize64
However, the Process object has several different properties that let me read the memory space used:
Paged, NonPaged, PagedSystem, NonPagedSystem, Private, Virtual, WorkingSet
and then the "peaks": which i'm guessing just store the maximum values these last ones ever took.
Reading through the MSDN definition of each property hasn't proved too helpful for me. I have to admit my knowledge regarding how memory is managed (as far as paging and virtual goes) is very limited.
So my question is obviously "which one should I use?", and I know the answer is "it depends".
This process will basically hold a bunch of lists in memory of things that are going on, while other processes communicate with it and query it for stuff. I'm expecting the server where this will run on to require lots of RAM, and so i'm querying this data over time to be able to estimate RAM requirements when compared to the sizes of the lists it keeps inside.
So... Which one should I use and why?
If you want to know how much the GC uses try:
GC.GetTotalMemory(true)
If you want to know what your process uses from Windows (VM Size column in TaskManager) try:
Process.GetCurrentProcess().PrivateMemorySize64
If you want to know what your process has in RAM (as opposed to in the pagefile) (Mem Usage column in TaskManager) try:
Process.GetCurrentProcess().WorkingSet64
See here for more explanation on the different sorts of memory.
OK, I found through Google the same page that Lars mentioned, and I believe it's a great explanation for people that don't quite know how memory works (like me).
http://shsc.info/WindowsMemoryManagement
My short conclusion was:
Private Bytes = The Memory my process has requested to store data. Some of it may be paged to disk or not. This is the information I was looking for.
Virtual Bytes = The Private Bytes, plus the space shared with other processes for loaded DLLs, etc.
Working Set = The portion of ALL the memory of my process that has not been paged to disk. So the amount paged to disk should be (Virtual - Working Set).
Thanks all for your help!
If you want to use the "Memory (Private Working Set)" as shown in Windows Vista task manager, which is the equivalent of Process Explorer "WS Private Bytes", here is the code. Probably best to throw this infinite loop in a thread/background task for real-time stats.
using System.Threading;
using System.Diagnostics;
//namespace...class...method
Process thisProc = Process.GetCurrentProcess();
PerformanceCounter PC = new PerformanceCounter();
PC.CategoryName = "Process";
PC.CounterName = "Working Set - Private";
PC.InstanceName = thisProc.ProcessName;
while (true)
{
String privMemory = (PC.NextValue()/1000).ToString()+"KB (Private Bytes)";
//Do something with string privMemory
Thread.Sleep(1000);
}
To get the value that Task Manager gives, my hat's off to Mike Regan's solution above. However, one change: it is not: perfCounter.NextValue()/1000; but perfCounter.NextValue()/1024; (i.e. a real kilobyte). This gives the exact value you see in Task Manager.
Following is a full solution for displaying the 'memory usage' (Task manager's, as given) in a simple way in your WPF or WinForms app (in this case, simply in the title). Just call this method within the new Window constructor:
private void DisplayMemoryUsageInTitleAsync()
{
origWindowTitle = this.Title; // set WinForms or WPF Window Title to field
BackgroundWorker wrkr = new BackgroundWorker();
wrkr.WorkerReportsProgress = true;
wrkr.DoWork += (object sender, DoWorkEventArgs e) => {
Process currProcess = Process.GetCurrentProcess();
PerformanceCounter perfCntr = new PerformanceCounter();
perfCntr.CategoryName = "Process";
perfCntr.CounterName = "Working Set - Private";
perfCntr.InstanceName = currProcess.ProcessName;
while (true)
{
int value = (int)perfCntr.NextValue() / 1024;
string privateMemoryStr = value.ToString("n0") + "KB [Private Bytes]";
wrkr.ReportProgress(0, privateMemoryStr);
Thread.Sleep(1000);
}
};
wrkr.ProgressChanged += (object sender, ProgressChangedEventArgs e) => {
string val = e.UserState as string;
if (!string.IsNullOrEmpty(val))
this.Title = string.Format(#"{0} ({1})", origWindowTitle, val);
};
wrkr.RunWorkerAsync();
}`
Is this a fair description? I'd like to share this with my team so please let me know if it is incorrect (or incomplete):
There are several ways in C# to ask how much memory my process is using.
Allocated memory can be managed (by the CLR) or unmanaged.
Allocated memory can be virtual (stored on disk) or loaded (into RAM pages)
Allocated memory can be private (used only by the process) or shared (e.g. belonging to a DLL that other processes are referencing).
Given the above, here are some ways to measure memory usage in C#:
1) Process.VirtualMemorySize64(): returns all the memory used by a process - managed or unmanaged, virtual or loaded, private or shared.
2) Process.PrivateMemorySize64(): returns all the private memory used by a process - managed or unmanaged, virtual or loaded.
3) Process.WorkingSet64(): returns all the private, loaded memory used by a process - managed or unmanaged
4) GC.GetTotalMemory(): returns the amount of managed memory being watched by the garbage collector.
Working set isn't a good property to use. From what I gather, it includes everything the process can touch, even libraries shared by several processes, so you're seeing double-counted bytes in that counter. Private memory is a much better counter to look at.
I'd suggest to also monitor how often pagefaults happen. A pagefault happens when you try to access some data that have been moved from physical memory to swap file and system has to read page from disk before you can access this data.

Categories

Resources