在Windows c不活动x分钟后退出Windows窗体应用程序

时间:2016-09-12 07:55:25

标签: c# winforms exit

我希望我的应用程序在Windows不活动x分钟后关闭,而不是基于我自己的应用程序的不活动。
我知道我应该看键盘和鼠标事件。但我不知道怎么做。我应该使用Import dll吗?
我的问题并不独特,而且在这里被问到:1,但我并不相信。 任何答案将不胜感激。

修改:
我希望我的应用程序在没有机构正在使用计算机时关闭,例如2分钟内。 我使用Timer解决了我的问题。

每当用户更改mouse位置或点击基本表单上keyboard中的某个键时,计时器都会重新启动。
    并在Timer elasped event我关闭了我的应用。

Timer t = new Timer(2*60*1000);
t.Start();
t.elapsed += closeAppFunction;

然后在鼠标移动中重新启动计时器。

1 个答案:

答案 0 :(得分:1)

您可以像这样包装Windows API:

public sealed class UserActivityMonitor
{
    /// <summary>Determines the time of the last user activity (any mouse activity or key press).</summary>
    /// <returns>The time of the last user activity.</returns>

    public DateTime LastActivity => DateTime.Now - this.InactivityPeriod;

    /// <summary>The amount of time for which the user has been inactive (no mouse activity or key press).</summary>

    public TimeSpan InactivityPeriod
    {
        get
        {
            var lastInputInfo = new LastInputInfo();
            lastInputInfo.CbSize = Marshal.SizeOf(lastInputInfo);
            GetLastInputInfo(ref lastInputInfo);
            uint elapsedMilliseconds = (uint) Environment.TickCount - lastInputInfo.DwTime;
            elapsedMilliseconds = Math.Min(elapsedMilliseconds, int.MaxValue);
            return TimeSpan.FromMilliseconds(elapsedMilliseconds);
        }
    }

    public async Task WaitForInactivity(TimeSpan inactivityThreshold, TimeSpan checkInterval, CancellationToken cancel)
    {
        while (true)
        {
            await Task.Delay(checkInterval, cancel);

            if (InactivityPeriod > inactivityThreshold)
                return;
        }
    }

    // ReSharper disable UnaccessedField.Local
    /// <summary>Struct used by Windows API function GetLastInputInfo()</summary>

    struct LastInputInfo
    {
        #pragma warning disable 649
        public int  CbSize;
        public uint DwTime;
        #pragma warning restore 649
    }

    // ReSharper restore UnaccessedField.Local

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetLastInputInfo(ref LastInputInfo plii);
}

然后,你可以通过在表单覆盖OnLoad()中执行类似的操作来实现在一段时间不活动后关闭表单的内容(此示例每隔5秒检查一次不活动,如果用户处于非活动状态则关闭表单超过10分钟):

readonly UserActivityMonitor _monitor = new UserActivityMonitor();

protected override async void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    await _monitor.WaitForInactivity(TimeSpan.FromMinutes(10), TimeSpan.FromSeconds(5), CancellationToken.None);
    this.Close();
}