2009-06-08 2 views
5

많은 것들이 시도되었지만 내 작업 표시 줄이 숨겨져 있고 내 데스크톱 UI에 다른 초자연적 인 효과가있는 가운데 계속 작동하도록 할 수는 없습니다.윈도우를 추가/활성화하는 방법을 알려주는 "windows hook"시스템을 추가하는 방법은 무엇입니까?

열기 라이브러리 http://mwinapi.sourceforge.net/을 먼저 사용해보십시오. 그것은 창문과 물건을 열거하기위한 객체 지향 레이어로 잘 작동했지만. 걸이를 제대로 할 수 없었습니다

다음 정류장은 Dino E.'s post on Windows Hooks in the .Net framework입니다. 나는 텍스트를 이해하고 이것을 작동 시키려고 노력하면서 내 자신의 타입을 쓰는 것을 끝내었다.

내 의도는이 응용 프로그램을 실행하고을 실행하는 동안 생성 된 모든 창을 기록 할 수있게하는 것입니다. 모두의 시선을 호출 ...

업데이트 : 분명히 당신 can't write global windows hooks in .Net이/

그래서 내가 C++로 전환 (일부 낮은 수준의 마우스 또는 키보드 후크 제외) 코드를 관리하기 때문에을 냈다. 여전히 모든 WinAPI 호출은 유효한 핸들을 반환하지만 호출되는 필터 함수가 표시되지 않습니다. 알림을받지 못하는 것 같습니다. 아직도 작동하지 않습니다 ... 누군가 실수를 발견 할 수 있습니까?

void CWinHookFacade::Hook() 
{ 
    HMODULE hCurrentDll = LoadLibrary(_T("[Path to my hook dll]")); 
    m_HookHandle = SetWindowsHookEx(WH_CBT, 
     FilterFunctionForHook, 
     hCurrentDll, 
     0); 
    if (m_HookHandle == NULL) 
    { 
     throw new std::exception("Unable to hook"); 
    } 

} 
void CWinHookFacade::Unhook() 
{ 
    if (!UnhookWindowsHookEx(m_HookHandle)) 
    { 
     throw new std::exception("Unhook failed!"); 
    } 
    m_HookHandle = NULL; 
} 

LRESULT CWinHookFacade::FilterFunctionForHook(int code, WPARAM wParam, LPARAM lParam) 
{ 
    if (code >= 0) 
    { 
     switch(code) 
     { 
     case HCBT_CREATEWND: 
      wprintf(_T("Created Window")); 
      break; 
     case HCBT_ACTIVATE: 
      wprintf(_T("Activated Window")); 
      break; 
     case HCBT_DESTROYWND: 
      wprintf(_T("Destroy Window")); 
      break; 
     } 
    } 

    return CallNextHookEx(m_HookHandle, code, wParam, lParam); 
} 

클라이언트 EXE 난 당신이 C#에서 후크 기능을 구현하기 위해 노력하고 있기 때문에 당신이 발생하는 문제를 생각이

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CWinHookFacade::Hook(); 
    getchar(); 
    CWinHookFacade::Unhook(); 
} 
+0

- SetWindowsHookEx는 매번 유효한 핸들을 반환합니다. 또한 누군가가 이것을 시험해보고 싶어하는 경우 위의 코드는 다른 의존성을 가지지 않는다. 빈 프로젝트에서 .cs 파일에 붙여넣고 실행하십시오. – Gishu

답변

5

처럼 Hook_DLL를 호출합니다. pinvoke.net's documentation (SetWindowsHookEx())을 기반으로,이 작업을 수행 할 수 없다고 말합니다. 후크 프로 시저는 관리되지 않는 DLL에 있어야합니다. 그렇지 않으면 메시지 루프가있는 실행중인 모든 프로세스에 DLL이로드되어 각 프로세스에서 CLR이로드되고 시작됩니다. 이 작업은 오랜 시간이 걸릴뿐만 아니라 모든 프로세스에 CLR을 주입하는 것이 가장 좋은 방법은 아닙니다. 또한 프로세스에 이미 DLL이 빌드 된 것과 다른 실행 CLR이있는 경우 어떻게됩니까?

최상의 방법은이 코드를 관리되지 않는 C++ DLL로 옮기고 어떤 종류의 프로세스 간 통신을 사용하여 후크 절차에 의해 가로 챈 데이터를 응용 프로그램에 다시 보냅니다.

업데이트

먼저 왜 당신이 당신의 DLL의 HINSTANCE를 얻을 수 LoadLibrary()을 요구하고, (이것은 당신의 문제를 일으키는 아마되지 않습니다)? DLL이 이미로드되었으므로 GetModuleHandle()에 전화하는 것이 좋습니다.

후크 프로 시저가 호출되지 않는 이유는 무엇입니까? 어떻게 확인 했습니까? 시스템의 모든 GUI 스레드를 연결하고 있기 때문에 DLL을 모든 GUI 프로세스에로드해야합니다. wprintf()을 호출 한 결과를 볼 수 없을 가능성이 있습니다. 다른 프로세스에는 출력을 표시 할 콘솔 창이 없기 때문입니다.

DLL이 제대로로드되었는지 확인하려면 프로세스에 의해로드 된 DLL을 나열하는 프로그램을 사용하십시오 (Process Explorer). 찾기 | DLL의 이름을 검색하려면 핸들 또는 DLL 메뉴 항목 찾기 - 메시지 루프가있는 모든 프로세스에 표시되어야합니다.

DLL이로드되었는지 확인한 후 훅이 호출되는지 확인하려면 디버거를 다른 프로세스 (예 : 메모장)에 연결 한 다음 훅 기능에 중단 점을 설정할 수 있습니다. CBT 후크에 메시지가 전송 될 때마다 그 메시지는 사라집니다. 디버거를 사용하지 않으려면 wprintf()OutputDebugString()으로 변경하고 DebugView과 같은 유틸리티를 실행하여 결과를 모니터링 할 수 있습니다.

마지막으로 후크 함수가 다른 프로세스의 컨텍스트에서 호출 되었기 때문에 m_HookHandle 변수가 유효하지 않습니다. shared data segment에 저장하여 DLL의로드 된 모든 인스턴스가 동일한 값을 갖도록해야합니다.

+0

나는 주입 부분에 대해 알고 있었다. DLL에 내 코드가있다. 그러나 C#에서는 불가능하다는 것을 알지 못했습니다. 내일 CPP에서 이것을 시도하고 그것이 어떻게 진행되는지 게시 할 것입니다 ... 저는 pinvoke 페이지의 notes 섹션을 제 위험에 빠뜨리는 일을 놓쳤습니다. (ManagedThreadID도 어려운 방법으로 작동하지 않는다는 것을 알게되었습니다.) – Gishu

+0

또 다른 문제는 http://mwinapi.sourceforge.net/에서 가져온 Hook 클래스에 ctor 매개 변수 -bGlobal이 있으며 완전히 관리된다는 것입니다. 이상한 ... – Gishu

+0

너무 비 관리로 전환 - 여전히 작동하지 않습니다. 업데이트 된 원래 질문 ... – Gishu

3

마지막으로이 사람을 찍었습니다. 누군가가 이것을 필요로하는 경우에 대비하여 blog post으로 썼습니다.

관련 문제