2012-04-01 1 views
1

GetForegroundWindow() C#에서 P/Invoke를 사용하여 새로 시작한 응용 프로그램을 캡처하려고합니다. 그러나, 내가 얻은 것은 explorer.exe 윈도우 핸들 실제 프로세스 창 핸들 (예 : notepad.exe 또는 wordpad.exe)이 시작되었습니다. (여러 메모장 인스턴스가 열려있는 경우) 사용자가있는 사용자는 내가 "메모장"인스턴스의 실제 핸들을 얻으려면 같은 시간에 "메모장"을 열 때 GetForeGroundWindow()를 사용하여 C#에서 새로 시작한 응용 프로그램 창 핸들을 얻는 방법?

사실 난 로그 사용자가 입력 한 텍스트에 노력하고 있습니다 뭔가 쓰려고하는 중이다.

즉, Windows 7 Ultimate x64의 시작 메뉴에서 notepad.exe를 실행하고 C# .Net 기반 응용 프로그램을 눌러 키를 실행합니다. 내 응용 프로그램에서 응용 프로그램 키 후크를 설정하여 텍스트가 변경된 이벤트에서 응용 프로그램이 전경 윈도우를 가져 오려고 시도합니다. 문제는 : notepad.exe 대신 explorer.exe를 얻는 것입니다.

코드는 이미 열려있는 창에 대해 완벽하게 작동하지만 크롬, 메모장, 워드 패드 또는 기타와 같은 모든 응용 프로그램의 새로 시작한 인스턴스에는 작동하지 않습니다. 올바른 응용 프로그램에 대해 텍스트를 로깅하는 대신 explorer.exe에 대한 텍스트를 로깅합니다. 여기 내 코드는 다음 GetForegroundWindow()가 전경 창으로 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 반환 올바른 응용 프로그램 즉 notepad.exe를 대신 explorer.exe에. 기존의 열린 응용 프로그램을 입력하고 응용 프로그램의 새 인스턴스를 시작하지 않을 때 동일한 코드가 올바른 응용 프로그램 창을 읽습니다.

나는 약간의 경쟁 조건 문제가 있음을 읽을 수 있습니다. 이 경우, 어떻게 해결할 수 있습니까?

도와주세요. 나는 이걸 아주 오래 붙어있다.

감사합니다.

+0

물론 탐색기는 전경 창입니다. 새로운 프로세스를 시작하기 위해 키 누르기를 처리합니다. 그것을 해결하는 방법에 관해서는 당신이 성취하고자하는 것을 정말로 이해할 수 없기 때문에 나는 말하기를 좋아하지 않을 것입니다. 그러나 키보드 입력을 연결하는 경우 키보드 훅 내부에서 GetForegroundWindow를 호출 할 수 없으며 키보드 입력이 끝나는 위치를 알려줍니다. –

+0

메모장이 열려 있고 메모장 창에 "메모장"을 입력하면 텍스트가 이벤트를 변경하고 해당 텍스트를 기록한 다음 나중에 기록 된 텍스트를 볼 수 있습니다. 완벽한 것을 만들기 위해서, 나는이 메소드를 호출하여 텍스트 변경 이벤트에서 "현재 Foregound 윈도우"를 업데이트합니다. 이 이벤트는 현재 포 그라운드 윈도우를 가져와야합니다. 즉 "입력하는 메모장"응용 프로그램입니다. 어떤 아이디어 ??? –

답변

1

확인. 얘들 아. 문제는 GetForegroundWindow()가 아닙니다. 어쩌면 그건 내가 왜 그 대답을 얻지 못했을까요. 문제를 자세히 디버그하여 문제를 찾아 냈습니다. 대답은 수정 된 코드로 여기에서 찾을 수 있습니다.

Solution with Code

관련 문제