Active window (program) unexpectedly loses focus in Windows 7
As and31415 advised me, I took a careful look at what is in my Startup
tab of msconfig
program, but found nothing unusual.
It is now clear that this is 99% caused by some external program (though not noticed before and though I haven't installed anything new recently), not by Windows. This is the most important point for me here.
I googled a little bit more and got some ideas / advice, namely that I should try to press Alt+F4 immediately after I notice a steal of a focus. This should exit process that could cause this focus stealth. Then, I may try to use Process Monitor
from Sysinternals
package to trace the process that has just exited.
This may give me some idea of what is causing this problem.
I programmed a C# program to monitor fluctuating processes. Here is the code if someone needs to find out what process is causing this problem.
using System;
using System.Diagnostics;
using System.Linq;
namespace ProcessMonitor
{
class Program
{
static void Main(string[] args)
{
var lastPros = Process.GetProcesses().Select((x) => x.Id).ToList();
var oldProcessList = Process.GetProcesses();
while (true)
{
var processlist = Process.GetProcesses();
var currentPros = processlist.Select(x => x.Id).ToList();
var diff = lastPros.Except(currentPros).ToList();
Console.ForegroundColor = ConsoleColor.Red;
var pro = oldProcessList.Where(x => diff.Contains(x.Id)).ToList();
if (diff.Count == 0)
{
pro = processlist.Where((x) => diff.Contains(x.Id)).ToList();
diff = currentPros.Except(lastPros).ToList();
Console.ForegroundColor = ConsoleColor.Green;
pro = processlist.Where((x) => diff.Contains(x.Id)).ToList();
}
foreach (var oldPid in diff)
{
Console.Write("PID {0}", oldPid);
try
{
Console.WriteLine(" name {0}", pro.Where((x) => x.Id == oldPid).ToList()[0].ProcessName);
}
catch (Exception e)
{
Console.WriteLine($" Hit exception {e}");
}
}
if (diff.Count > 0)
{
lastPros = currentPros;
oldProcessList = processlist;
}
System.Threading.Thread.Sleep(100);
}
}
}
}
Output sample showing process starting (green) and terminating (red)
The focus is probably stolen by a buggy background task. It opens a window, which steals focus, and it is very quickly closed, but the focus does not return. Lately, Microsoft Office had such a bug.
To discover such processes, you can use tools like Window Focus Logger (mirror) or a custom C# program similar to Process Monitor:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ProcessMonitor
{
class Program
{
const int pollDelay = 100;
static void Main(string[] args)
{
var lastProcesses = GetDescriptions();
while (true)
{
System.Threading.Thread.Sleep(pollDelay);
var now = DateTime.Now;
var processes = GetDescriptions();
var started = processes.Except(lastProcesses);
var stopped = lastProcesses.Except(processes);
foreach (var p in started)
{
Print(now, p, ConsoleColor.Green);
}
foreach (var p in stopped)
{
Print(now, p, ConsoleColor.Red);
}
lastProcesses = processes;
}
}
static void Print(DateTime dateTime, ProcessDescription process,
ConsoleColor color)
{
Console.ForegroundColor = color;
Console.WriteLine("{0:hh\\:mm\\:ss\\.ff}\tPID {1}\t{2}",
dateTime.TimeOfDay, process.Id, process.Description);
Console.ResetColor();
}
static List<ProcessDescription> GetDescriptions()
{
return Process.GetProcesses().Select(x => GetDescription(x)).ToList();
}
static ProcessDescription GetDescription(Process p)
{
int pid = -1;
string description;
try
{
pid = p.Id;
description = p.ProcessName;
}
catch (Exception e)
{
description = "Hit exception " + e;
}
return new ProcessDescription { Id = pid, Description = description };
}
struct ProcessDescription
{
public int Id;
public string Description;
public override bool Equals(object obj)
{
return obj != null && Id == ((ProcessDescription)obj).Id;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
}
}
Polished and bugfixed version of the code provided by Omar Alshaker. Also does not require C# 6. Requires .NET 3.5 or newer.
You can compile it using the C# compiler (csc.exe
) that comes with your .NET Framework installation and run the resulting executable to get a real-time log of processes that start (green) or end (red). Use Ctrl + C to terminate it.
To find the compiler, run where /R %windir%\Microsoft.NET csc.exe
. Pick the one from the latest .NET version installed, no matter whether 32b or 64b. Save the C# code in Program.cs
and compile it to Program.exe
:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe Program.cs