Обнаружение того, что пользователь находится вдали от ПК с .NET

У меня есть настольное приложение, в котором я хотел бы знать две вещи:

  1. Находится ли пользователь в настоящее время на ПК (точнее, вводит ли он какие-либо данные на ПК), поэтому я могу изменить его состояние на «отсутствует», если это необходимо; и
  2. Работает ли скринсейвер прямо сейчас, чтобы я мог выполнять более интенсивную работу процессора в это время.

Я использую С#/.NET. Как бы вы предложили решить эти две задачи?

ПРИМЕЧАНИЕ. Вызов WIN32 будет столь же хорош, как и любое решение с неуправляемым кодом.


person Eldad Mor    schedule 23.12.2010    source источник


Ответы (4)


http://dataerror.blogspot.com/2005/02/detect-windows-idle-time.html

^ Обнаружение времени простоя Windows. :)

Активатором этой функции является GetLastInputInfo() Win32 API и структура LASTINPUTINFO Win32. .

person Phill    schedule 23.12.2010
comment
Ссылки — это не ответы — ну, по крайней мере, больше. Ожидается, что ответы на SO будут автономными. Пожалуйста, рассмотрите этот мета-вопрос и добавьте в свой ответ достаточно подробностей, чтобы он не зависел полностью от внешней ссылки. Возможно, образец кода? (Этот ответ был помечен как не ответ.) - person Charles; 28.01.2014
comment
@Charles - я знаю, но я написал это еще в 2010 году. Думаю, я только что присоединился к SO в то время, и никто не указал мне на ссылки, а не информацию об ответах. :) - person Phill; 28.01.2014
comment
Да, и тогда стандарты не были такими строгими... однако этот ответ все еще был помечен, и его улучшение, вероятно, было бы хорошей идеей. - person Charles; 28.01.2014
comment
@Charles - я согласен, но не могу обновить его, пока я на работе. Нужно прочитать ссылку и вопрос, поэтому сегодня вечером обновлю ответ. В любом случае хорошая идея, если ссылка умрет, контент все равно будет доступен. :) - person Phill; 28.01.2014

Вот код, чтобы определить, работает ли экранная заставка. Дополнительные сведения см. в этом.

const int SPI_GETSCREENSAVERRUNNING = 114;

[DllImport( "user32.dll", CharSet = CharSet.Auto )]
private static extern bool SystemParametersInfo( 
   int uAction, int uParam, ref bool lpvParam, 
   int flags );


// Returns TRUE if the screen saver is actually running
public static bool GetScreenSaverRunning( )
{
   bool isRunning = false;

   SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0, 
      ref isRunning, 0 );
   return isRunning;
}
person Harvey Kwok    schedule 23.12.2010
comment
Я думал, что это не работает, но потом понял причину: это не работает, если вы просматриваете скринсейвер! Он должен запускаться автоматически. Итак, чтобы проверить это, установите заставку на 1 минуту и ​​подождите. :) - person Andrew; 29.12.2016

Вместо того, чтобы выяснять, когда выполнять более интенсивную работу... Подумайте о том, чтобы выполнять свою «интенсивную работу» как можно раньше, но с более низким приоритетом потока.

Я не думаю, что на ваши вопросы есть ответ на чистом С#, если вы не опрашиваете положение мыши и не наблюдаете за движениями... Или что-то в этом роде.

person Arafangion    schedule 23.12.2010

Вы можете использовать глобальную ловушку клавиатуры/мыши и просто сбросить свой «счетчик» на 0, когда вы получите событие от любого из них. Когда ваш счетчик достигнет нужного времени простоя, выполните фоновые действия.

Здесь есть некоторый код, который позволяет легко выполнять перехват в .NET: http://www.codeproject.com/KB/cs/globalhook.aspx

person Flipster    schedule 23.12.2010