4

現時点ではSystem.Diagnostics.Process.GetProcesses()、単純なLINQクエリを使用して実行しているメインウィンドウで実行中のプロセスのリストを取得できます。

次に、関数をインポートuser32.dllして、SetWindowPos他のプロセスのウィンドウパラメータを操作できます。

わかりました、動作します。次に、プロセスのウィンドウ、たとえばcalc.exeをクリックして選択します。つまり、ウィンドウをクリックしたときにプロセス名をキャッチするフックを備えたProcessオブジェクト(およびMainWindowHandle)を取得したいと思います。

どうすればこれを達成できますか?

4

2 に答える 2

5

これが C# でどのように行われるかはわかりませんが、この質問に WinAPI というタグを付けてくださったので、お手伝いできます。WinAPI では、次のように実行できます。

#include <stdio.h>
#include <Windows.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")

int main(void)
{
  /* Hacky loop for proof of concept */
  while(TRUE) {
    Sleep(100);

    if(GetAsyncKeyState(VK_F12)) {
      break;
    }

    if(GetAsyncKeyState(VK_LBUTTON)) {
      HWND  hwndPt;
      POINT pt;

      if(!GetCursorPos(&pt)) {
        wprintf(L"GetCursorPos failed with %d\n", GetLastError());
        break;
      }

      if((hwndPt = WindowFromPoint(pt)) != NULL) {
        DWORD  dwPID;
        HANDLE hProcess;

        GetWindowThreadProcessId(hwndPt, &dwPID);

        hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPID);

        if(hProcess == NULL) {
          wprintf(L"OpenProcess failed with error: %d\n", GetLastError());
        } else {
          wchar_t lpFileName[MAX_PATH];
          DWORD   dwSize = _countof(lpFileName);

          QueryFullProcessImageName(hProcess, 0, lpFileName, &dwSize);
          wprintf(L"%s\n", lpFileName);

          CloseHandle(hProcess);
        }
      }
    }
  }

  return EXIT_SUCCESS;
}

結果の例:

結果

この場合、マウス クリックを取得するために単純にポーリングしています。より適切な方法は、ある種の Windows フックを使用することです。

于 2012-04-25T15:23:43.347 に答える
1

マイク・クワンが言ったように、どちらのアプローチにも独自の欠点がありますが、フックを作成する方が良いでしょうが、bjarneds はすでにこれについて良い仕事をしています。@ DotNET Object Spyをご覧ください。これは C# で記述されており、ニーズなどに対応します。

また、フックの使用は日ごとに冗長になっていることにも注意してください。やりたいことによっては、他の winapis のようなものGetForegroundWindowがより適切に機能する可能性があります。

于 2012-04-25T20:07:15.857 に答える