客户遇到问题,员工打开显示敏感信息的程序,并在不关闭的情况下离开。他们要求我监控应用程序何时打开,并在一定程度的不活动后关闭它。
我所做的是创建了一个新程序,它启动原始程序,但另一个表单就在它之上。如果我的表单是透明的,我可以毫无问题地点击表单,并操纵底层程序。如果我的表单(略微)不透明,点击将注册我的程序,但不会通过。
我需要的是一种方法,让我的表单注册发生了点击,重置其计时器,并将点击传递给底层应用程序。我可以重置计时器,或者我可以通过点击,但不能同时通过。
这是我正在尝试的代码。第一部分将我的表单定义为透明,并将其保存在另一个应用程序之上。
private void Form1_Load(object sender, EventArgs e)
{
this.Opacity = 0.40;
this.TopMost = true;
}
我认为这会让我监视点击,重置计时器,然后通过它,但它不起作用,所以我必须遗漏一些东西。编辑:WT_NCHITTEST = 0x84,HTTRANSPARENT = -1,如下所示:https://msdn.microsoft.com/en-us/library/windows/desktop/ms645618%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_NCHITTEST) // m.Msg 0x84 means that Windows is asking our form whether it is "transparent" or not.
{
timeToClose = 10;
m.Result = new IntPtr(HTTRANSPARENT); // tell Windows yes, to pass everything through.
}
base.WndProc(ref m);
}
答案 0 :(得分:2)
这是过度设计,我使用System.Timers.Timer和PInvoke GetLastInputInfo实现不活动检查。运行第二个应用程序,监视工作站不活动状态,并在违反阈值时关闭敏感应用程序。
以一定间隔初始化定时器并将其设置为自动重置,然后在每次定时器过去时检查是否不活动。如果不活动时间大于阈值,请将其关闭。
以下是GetLastInputInfo的代码。
public static class Tracker
{
/// <summary>
/// Reference to the GetLastInputInfo in the user32.dll file.
/// </summary>
/// <param name="plii">LASTINPUTINFO struct</param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
/// <summary>
/// Polls the system for the milliseconds elapsed since last user input.
/// </summary>
/// <returns>Milliseconds since last user input.</returns>
public static uint GetIdleTime()
{
LASTINPUTINFO lastInput = new LASTINPUTINFO();
lastInput.cbSize = (uint)Marshal.SizeOf(lastInput);
GetLastInputInfo(ref lastInput);
return ((uint)Environment.TickCount - lastInput.dwTime);
}
}
/// <summary>
/// Struct required and populated by the user32.dll GetLastInputInfo method.
/// </summary>
internal struct LASTINPUTINFO
{
public uint cbSize; //Size of the struct.
public uint dwTime; //TickCount at last input.
}
我的不活动计时器实现如下所示:
public void InitializeTimer()
{
ActivityTimer = new System.Timers.Timer(Configuration.TimeoutSettings["IntervalMilliseconds"]);
ActivityTimer.AutoReset = true;
ActivityTimer.Elapsed += OnElapsedPollForActivity;
ActivityTimer.Start();
}
/// <summary>
/// Method is called in ValidationForm_FormClosing, unsubscribes handler from event and stops the clock.
/// </summary>
public void TerminateTimer()
{
ActivityTimer.Elapsed -= OnElapsedPollForActivity;
ActivityTimer.Stop();
}
/// <summary>
/// Fires on ActivityTimer.Elapsed, polls workstation for time since last user input.
/// </summary>
private void OnElapsedPollForActivity(object sender, System.Timers.ElapsedEventArgs e)
{
if (Tracker.GetIdleTime() > Configuration.TimeoutSettings["TriggerMilliseconds"])
{
Logger.LogException(CurrentSession.SessionID, DateTime.Now, new InactivityException("Detected extended period of workstation inactivity."));
Application.Exit();
}
}