Как узнать, когда Windows неактивна - PullRequest
9 голосов
/ 15 октября 2008

Различные программы могут делать вещи, только если вы некоторое время не пользовались компьютером (например, заставка, индексирование Google Desktop и т. Д.).

Как они узнают, когда он был неактивен? Есть ли в Windows какая-то функция, которая сообщает вам, как долго она была неактивна, или вам нужно использовать какую-нибудь клавиатуру / мышь для отслеживания активности?

Я использую C #, но меня интересует любой метод определения бездействия.

Ответы [ 3 ]

11 голосов
/ 15 октября 2008

РЕДАКТИРОВАТЬ: изменил ответ, предоставив текст и детали за ответом Ши (что должно быть и было принято). Не стесняйтесь объединять и удалять это.

GetLastInputInfo Функция Функция GetLastInputInfo извлекает время последнего входного события.

Вставлено сюда из P / Invoke

Эта функция извлекает время с момента последнего пользовательского ввода

[DllImport("user32.dll")]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

static int GetLastInputTime()
{
    int idleTime = 0;
    LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
    lastInputInfo.cbSize = Marshal.SizeOf( lastInputInfo );
    lastInputInfo.dwTime = 0;

    int envTicks = Environment.TickCount;

    if( GetLastInputInfo( ref lastInputInfo ) )
    {
    int lastInputTick = lastInputInfo.dwTime;

    idleTime = envTicks - lastInputTick;
    }

    return (( idleTime > 0 ) ? ( idleTime / 1000 ) : idleTime );
}

[StructLayout( LayoutKind.Sequential )]
struct LASTINPUTINFO
{
    public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));

    [MarshalAs(UnmanagedType.U4)]
    public int cbSize;    
    [MarshalAs(UnmanagedType.U4)]
    public UInt32 dwTime;
}

FWIW: В AnAppADay я реализовал глобальный хук клавиатуры и мыши. Посмотрите это приложение для источника - это довольно близко к тому, что вы хотите. Классы, которые вам нужны, находятся в пространстве имен AnAppADay.Utils. [поцарапано из-за linkrot]

5 голосов
/ 15 октября 2008

Google твой друг

В основном использует this.
не забудьте полностью подготовить документацию перед использованием.

0 голосов
/ 15 октября 2008

Крючки для клавиатуры и мыши - это то, что я считаю наиболее ценным. Класс ниже можно вставить, и вам просто нужно выяснить, что вы хотите делать с информацией об обновлениях клавиш и мыши.

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace Example {

    public class Hook {

        delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

        [FlagsAttribute]
            public enum WindowMessage {
            WM_KEYDOWN =        0x0000000000000100, // &H100
            WM_MOUSEMOVE =      0x0000000000000200, // &H200
            WM_LBUTTONDOWN =    0x0000000000000201, // &H201
            WM_RBUTTONDOWN =    0x0000000000000204,  // &H204
            WH_KEYBOARD = 2,
            WH_MOUSE = 7,
            HC_ACTION = 0
        }

        [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
        private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);

        [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

        //Declare MouseHookProcedure as a HookProc type.
        static HookProc MouseHookProcedure;
        static HookProc KeyboardHookProcedure;

        private static int  mhMouseHook = 0;
        private static int  mhKeyboardHook = 0;

        public Hook() {}

        public static void Init() {
            MouseHookProcedure = new HookProc( MouseHookProc );
            KeyboardHookProcedure = new HookProc( KeyboardHookProc );
            mhMouseHook = SetWindowsHookEx( (int)WindowMessage.WH_MOUSE, MouseHookProcedure, (IntPtr)0, AppDomain.GetCurrentThreadId() );
            mhKeyboardHook = SetWindowsHookEx( (int)WindowMessage.WH_KEYBOARD, KeyboardHookProcedure, (IntPtr)0, AppDomain.GetCurrentThreadId() );
        }

        public static void Terminate() {
            UnhookWindowsHookEx( mhMouseHook );
            UnhookWindowsHookEx( mhKeyboardHook );
        }

        private static int MouseHookProc( int nCode, IntPtr wParam, IntPtr lParam ) {
            if ( nCode >= 0 ) {
                //do something here to update the last activity point, i.e. a keystroke was detected so reset our idle timer.
            }
            return CallNextHookEx( mhMouseHook, nCode, wParam, lParam );
        }

        private static int KeyboardHookProc( int nCode, IntPtr wParam, IntPtr lParam ) {
            if ( nCode >= 0 ) {
                //do something here to update the last activity point, i.e. a mouse action was detected so reset our idle timer.
            }
            return CallNextHookEx( mhKeyboardHook, nCode, wParam, lParam );
        }

    }
}

Конечно, это работает только в приложении, которое вы подключаете. Если вам нужно отслеживать бездействие во всей системе, вам нужно создать DLL, которая может быть загружена в адресные пространства всех других окон. К сожалению, я не слышал ни о каком хаке, который позволил бы скомпилированному .net .dll, который будет работать в этом сценарии; у нас есть C ++ DLL, которая подключается для этой цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...