I once used an LCD TV as a monitor for my PC. The TV did not have a standby state like a display monitor, and was designed to automatically turn off when the video signal stopped for 10 minutes. You can turn off this power-saving feature and leave it on all the time, but that's a waste of electricity. After it turns off automatically, you can turn it on with a remote control signal, but the power control is an on-off toggle operation, so if you send it when the power is off, it will turn on, but it will be sent when it is on. and the TV turns off. In other words, the remote control signal should only be sent when the TV has auto-off after the PC screen has turned off.
There are two ways. One method is to check the state of the display and determine whether it is off. Another method is to measure the time when there is no user input (idle time) to find the timing when the video signal stops, and then use the elapsed time to guess that the TV has turned off automatically. The former was a rather troublesome method, so I decided to use the method of measuring idle time.
You can check the amount of time before the screen turns off in the Windows Settings app or in the Power Options control panel. If there is a possibility of changing it frequently, it is necessary to check it every time with a program, but it is quite a troublesome process such as requiring administrator privileges. In my experience, I hard-coded the fixed value into the program because it rarely changed on desktop machines.
To get the idle time measured by Windows, use the Win32 API "GetLastInputInfo". API information can be found below.
・GetLastInputInfo function (English) https://docs.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-getlastinputinfo
This API will tell you when there was last user input (keyboard or mouse action). However, the time expression is commonly called "Windows time". Windows time is a 32-bit integer value that represents the elapsed time in milliseconds since Windows restarted. However, this value is created by software processing that is added at the system timer interrupt time interval (approximately 10 to 16 milliseconds). Therefore, it should be noted that the error is not very noticeable in time units of seconds or longer, but large errors and variations appear when measured in milliseconds.
This time I used Windows PowerShell in a lazy way. Windows PowerShell is generally not very popular, but it does most things. PowerShell has the ability to compile and call C# code, but execution is done in an interpreter. This method does not require a compiler or a development environment like Visual Studio. On the other hand, if you write full-fledged code in C#, debugging it is quite difficult. The program this time was relatively easy to make because it only had to define Win32API calls, initialize structures, and extract members from structures.
To create C# code like this, search for PINVOKE.NET, a collection of information about Win32 calls to .NET.
・pinvoke.net: GetLastInputInfo (user32)https://pinvoke.net/default.aspx/user32/GetLastInputInfo.html・LASTINPUTINFO (Structures)https://pinvoke.net/default.aspx/Structures/LASTINPUTINFO. html
Listing 01 is a program that detects idle time. The here string in the first half (Here-String, the part enclosed by @) is C# code, and Windows PowerShell compiles and executes this at runtime. The second half is the function definition that calls the C# code written in PowerShell and the sample execution at startup (the last two lines). Put this in a text file with the extension ".ps1". Start PowerShell and read this file to measure 3 seconds of idle time with progress display as an example (Photo 01).
There are two PowerShell functions defined. One is the WaitIdle function, which detects the idle time specified in milliseconds. If you add the “-Verbose” option, the progress will be displayed. When the specified idle time is detected, the function exits, so you can do something there. This function will not exit unless the idle time is greater than or equal to the specified time. You can detect the screen off timing by specifying the time when the screen of the PC turns off in this function. The other is the IdleTime function, which returns the current idle time in milliseconds (1 second = 1000 milliseconds). Note that if you want to use Japanese characters in Windows PowerShell, the file must be Unicode encoded (UTF-16LE).
■ List 01
$du=Add-Type -ErrorAction Ignore @'using System;using System.Diagnostics;using System.Runtime.InteropServices;namespace shioda.asb01 { public static class UserInput {[DllImport("user32.dll" , SetLastError=false)]private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);[StructLayout(LayoutKind.Sequential)]private struct LASTINPUTINFO {public uint cbSize;public int dwTime;}public static int LastInputTime {get { LASTINPUTINFO myLastInputInfo = new LASTINPUTINFO (); myLastInputInfo.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO)); GetLastInputInfo(ref myLastInputInfo); return myLastInputInfo.dwTime;}} }}'@function global:IdleTime() { return [System.Environment] ::TickCount - [shioda.asb01.UserInput]::LastInputTime;}function global:WaitIdle() { param ( [int32] $wt, [switch] $Verbose ) ; while (($t = IdleTime) -lt $wt ) {$w = $wt - $t;if($Verbose) {Write-Host ("Idle : {0,8:d} [ms] Wait : {1,8:d} [ms]" -f $ t,$w ) }Start-Sleep -Milliseconds $w}}WaitIdle -verbose 3000; Write-host "You can excute anything here." class can be treated as an object as it is. In this program, the C# part is a class called "UserInput", and a property called "LastInputTime" is defined.Windows PowerShell is great for small experiments, like calling Win32 APIs. Since the C# code can be specified as it is, you can find the code that can be used as a reference by searching the Internet for information on Win32API for C#.
Navigation Lists
Checking the idle timeCategory
Related Articles
Hot Articles