我正在尝试使用C#中的P / Invoke使用 GetForegroundWindow()捕获新启动的应用程序。但是,我得到的只是 explorer.exe窗口句柄,而不是已启动的实际进程窗口句柄(例如notepad.exe或wordpad.exe)。
实际上我正在尝试记录用户输入的文本当用户打开“记事本”的同时我想获得“记事本”实例的实际句柄(如果多个记事本实例打开)用户试图写一些内容。
即我在Windows 7 Ultimate x64的开始菜单中启动了notepad.exe,我的基于C#.Net的应用程序运行按下了按键。我在我的应用程序中设置了应用程序密钥挂钩,以便在文本更改事件时,应用程序尝试获取前台窗口。问题是:它获取explorer.exe而不是notepad.exe。
该代码适用于已经打开的窗口,但它不适用于任何应用程序的新启动实例,如chrome,记事本,wordpad或任何其他应用程序。它不是针对正确的应用程序记录文本,而是记录explorer.exe的文本。这是我的代码:
private string GetActiveWindowTitle()
{
const int nChars = 256;
IntPtr handle = IntPtr.Zero;
StringBuilder Buff = new StringBuilder(nChars);
handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
Process GetActiveProcess()
{
Process[] AllProcess = Process.GetProcesses();
String title = GetActiveWindowTitle();
foreach (Process pro in AllProcess)
{
if (title.Equals(pro.MainWindowTitle))
{
return pro;
}
}
return Process.GetCurrentProcess();
}
string GetActiveProcessFileName()
{
IntPtr hwnd = GetForegroundWindow();
SetForegroundWindow(hwnd);
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
Process p = Process.GetProcessById((int)pid);
//p.MainModule.FileName.Dump();
return p.ProcessName;
}
ProcessInfo GetActiveProcessInfo()
{
IntPtr hwnd = GetForegroundWindow();
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
Process p = Process.GetProcessById((int)pid);
ProcessInfo pi = new ProcessInfo();
if (GetWindowText(hwnd, Buff, nChars) > 0)
{
pi.ProcessTitle = Buff.ToString();
}
pi.ProcessName = p.ProcessName;
pi.ProcessHandle = (int)p.MainWindowHandle;
return pi;
}
GetActiveProcessInfo 返回explorer.exe而不是正确的应用程序,即notepad.exe,因为GetForegroundWindow()将explorer.exe作为前景窗口读取。当我输入现有的打开的应用程序并且不启动应用程序的新实例时,相同的代码会读取正确的应用程序窗口。
我在某处读到有一些竞争条件问题。如果是这种情况,我该如何解决这个问题?
请帮帮我。我真的被困在这很久了。
感谢。
答案 0 :(得分:1)
确定。伙计们。问题不在于GetForegroundWindow()。也许这就是为什么我没有得到任何答案。我详细调试了这个问题并找到了问题所在。答案可以在这里找到更正的代码。