How to measure system idle time in C#, excluding when watching movies, etc?
I am looking for a program that me开发者_运维技巧asures system idle time on Windows. I have found many codes that do this. For example,
http://www.codeproject.com/KB/cs/GetIdleTimeWithCS.aspx
However, I also want to take into account user watching movies, videos, etc. That time no input is given, but still the system is not idle.
Is there anyway to do this?
This function detects if a process is running in fullscreen in forground, and returns name of the process if found so:
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
private static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern bool
GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
private struct POINTAPI
{
public int x;
public int y;
}
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
private struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public POINTAPI ptMinPosition;
public POINTAPI ptMaxPosition;
public RECT rcNormalPosition;
}
public string FullscreenProcess()
{
IntPtr foreWindow = GetForegroundWindow();
// get the placement
WINDOWPLACEMENT forePlacement = new WINDOWPLACEMENT();
forePlacement.length = Marshal.SizeOf(forePlacement);
GetWindowPlacement(foreWindow, ref forePlacement);
if (forePlacement.rcNormalPosition.top == 0 && forePlacement.rcNormalPosition.left == 0 && forePlacement.rcNormalPosition.right == Screen.PrimaryScreen.Bounds.Width && forePlacement.rcNormalPosition.bottom == Screen.PrimaryScreen.Bounds.Height)
{
uint processID;
GetWindowThreadProcessId(foreWindow, out processID);
Process proc = Process.GetProcessById((int)processID);
return proc.ProcessName;
}
return null;
}
After this, we just need to match the returned process name with a set of popular media players or other processes.
Limitation is that we have assumed user plays in fullscreen.
You can get the idle time for computer using this, however your problem is how to know weather a movie is playing, you can check the processes that is currently running on the computer System.Diagnostics.Process.GetProcesses()
, and then check if one of them is a known movie player. However I don't think this will achieve what you locking for either, because even if you find out that for example a Gom player is running, you still don't know if it running a video or audio or just opened without any thing actually playing...
In case you watch videos in fullscreen: You could use code like this do determine if there is an app running in fullscreen:
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
struct RECT
{
public int Left;
public int Top;
public int Width;
public int Height;
}
static bool IsBigWindowRunning()
{
foreach (Process proc in Process.GetProcesses())
{
RECT rect;
var success = GetWindowRect(proc.MainWindowHandle, out rect);
if(success && (r.Left + r.Width) >= Screen.PrimaryScreen.WorkingArea.Width)
{
return true;
}
}
return false;
}
I haven't tested it well and i would definetely play around with this line, add some limits:
if((r.Left + r.Width) >= Screen.PrimaryScreen.WorkingArea.Width)
Good luck!
精彩评论