어떤 프로세스가 글로벌 핫키를 등록했는지 알아보세요? (Windows API)


114

내가 알 수있는 한, Windows는 (RegisterHotkey를 통해) 전역 단축키를 등록한 응용 프로그램을 알려주는 API 기능을 제공하지 않습니다. RegisterHotkey가 false를 반환하는 경우에만 핫키가 등록되었음을 알 수 있지만 누가 핫키를 "소유"하는지 알 수 없습니다.

직접 API가없는 경우 원형 교차로가있을 수 있습니까? Windows는 등록 된 각 핫키와 관련된 핸들을 유지합니다.이 정보를 얻을 수있는 방법이 없어야한다는 것은 다소 놀랍습니다.

작동하지 않을 가능성이있는 예 : 등록 된 핫키를 전송 (시뮬레이션) 한 다음 Windows가이를 등록한 프로세스로 보낼 핫키 메시지를 가로 채십시오. 첫째, 메시지를 가로 채면 대상 창 핸들이 드러나지 않는다고 생각합니다. 둘째, 가능하더라도 핫키를 보내는 것은 다양한 프로그램에서 잠재적으로 원치 않는 모든 종류의 활동을 유발하기 때문에 나쁜 일입니다.

중요한 것은 아니지만 이러한 기능에 대한 요청을 자주 보았으며 UI 또는 문서의 어느 곳에서도 핫키를 공개하지 않고 단축키를 등록하는 애플리케이션의 희생양이되었습니다.

(Delphi에서 일하고 WinAPI의 견습생 이상은 친절하십시오.)

답변:


20

귀하의 질문이 내 관심을 불러 일으켰 기 때문에 나는 약간의 파고를했으며 불행히도 적절한 대답이 없지만 내가 가진 것을 공유 할 것이라고 생각했습니다.

1998 년에 작성된 키보드 후크 (Delphi에서)를 만드는예제를 찾았 지만 Delphi 2007에서 몇 가지 조정을 통해 컴파일 할 수 있습니다.

다음을 호출하는 DLL입니다. SetWindowsHookEx콜백 함수를 통해 전달 키 입력을 가로 챌 수 있습니다.이 경우 재미를 위해 조작하고 왼쪽 커서를 오른쪽으로 변경하는 등의 작업을 수행합니다. 그런 다음 간단한 앱이 DLL을 호출하고 다시보고합니다. TTimer 이벤트를 기반으로 한 결과. 관심이 있으시면 Delphi 2007 기반 코드를 게시 할 수 있습니다.

잘 문서화되고 주석이 달렸으며 잠재적으로 키 누름이 진행되는 위치를 파악하는 기초로 사용할 수 있습니다. 키 입력을 보낸 응용 프로그램의 핸들을 가져올 수 있다면 그 방법으로 추적 할 수 있습니다. 이 핸들을 사용하면 필요한 정보를 아주 쉽게 얻을 수 있습니다.

다른 앱은 단축키의 또 다른 용어 인 단축키를 포함 할 수 있기 때문에 단축키를 통해 단축키를 결정하려고 시도했습니다. 그러나 대부분의 응용 프로그램은이 속성을 설정하지 않으므로 많이 반환하지 않을 수 있습니다. 해당 경로에 관심이 있다면 Delphi는 IShellLink바로 가기를로드하고 핫키를 가져 오는 데 사용할 수있는 COM 인터페이스에 액세스 할 수 있습니다.

uses ShlObj, ComObj, ShellAPI, ActiveX, CommCtrl;

procedure GetShellLinkHotKey;
var
  LinkFile : WideString;
  SL: IShellLink;
  PF: IPersistFile;

  HotKey : Word;
  HotKeyMod: Byte;
  HotKeyText : string;
begin
  LinkFile := 'C:\Temp\Temp.lnk';

  OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, SL));

  // The IShellLink implementer must also support the IPersistFile
  // interface. Get an interface pointer to it.
  PF := SL as IPersistFile;

  // Load file into IPersistFile object
  OleCheck(PF.Load(PWideChar(LinkFile), STGM_READ));

  // Resolve the link by calling the Resolve interface function.
  OleCheck(SL.Resolve(0, SLR_ANY_MATCH or SLR_NO_UI));

  // Get hotkey info
  OleCheck(SL.GetHotKey(HotKey));

  // Extract the HotKey and Modifier properties.
  HotKeyText := '';
  HotKeyMod := Hi(HotKey);

  if (HotKeyMod and HOTKEYF_ALT) = HOTKEYF_ALT then
    HotKeyText := 'ALT+';
  if (HotKeyMod and HOTKEYF_CONTROL) = HOTKEYF_CONTROL then
    HotKeyText := HotKeyText + 'CTRL+';
  if (HotKeyMod and HOTKEYF_SHIFT) = HOTKEYF_SHIFT then
    HotKeyText := HotKeyText + 'SHIFT+';
  if (HotKeyMod and HOTKEYF_EXT) = HOTKEYF_EXT then
    HotKeyText := HotKeyText + 'Extended+';

  HotKeyText := HotKeyText + Char(Lo(HotKey));

  if (HotKeyText = '') or (HotKeyText = #0) then
    HotKeyText := 'None';

  ShowMessage('Shortcut Key - ' + HotKeyText);
end;

당신에 대한 액세스 권한을 가지고있는 경우에 사파리 온라인 하는이 바로 가기 / 쉘 링크 사용에 대한 좋은 부분 스티브 텍사스와 사비 파 체코에 의해 볼랜드 델파이 6 개발자 안내서는. 위의 예는 거기 와이 사이트 에서 도살 된 버전입니다 .

도움이 되었기를 바랍니다.


59

한 가지 가능한 방법은 Visual Studio 도구 인 Spy ++ 를 사용하는 것 입니다.

이것을 시도하십시오 :

  1. 도구 실행 (저에게는 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\spyxx_amd64.exe)
  2. 메뉴 바에서 선택 스파이 -> 로그 메시지 ... (또는 히트 Ctrl+ M)
  3. 확인 시스템에 모든 창을추가 윈도우 프레임
  4. 메시지 탭으로 전환
  5. 모두 지우기 버튼을 클릭 합니다
  6. WM_HOTKEY목록 상자에서 선택 하거나 메시지 그룹 에서 키보드 를 선택하십시오 . (잠재적 인 소음에 문제가없는 경우).
  7. 확인 버튼을 클릭하십시오
  8. 문제의 단축키 ( 예 : Win+ R)를 누릅니다.
  9. 메시지 (모든 창)WM_HOTKEY에서 줄을 선택하고 마우스 오른쪽 버튼을 클릭 한 다음 상황에 맞는 메뉴에서 속성 ... 을 선택 합니다.
  10. 에서 메시지 등록 정보 대화 상자에서 클릭 창 핸들의 링크를 (이 메시지를받은 윈도우의 핸들이 될 것입니다)
  11. 창 속성 대화 상자 에서 동기화 버튼을 클릭합니다 . 그러면 주 Spy ++ 창 트리보기에 창이 표시됩니다.
  12. 창 속성 대화 상자에서 선택 프로세스 탭을
  13. 프로세스 ID 링크를 클릭하십시오 . 이것은 (내 당신에게 그 과정을 보여줍니다 Win+의 R경우 : EXPLORER)

6
좋은 대답입니다! 것을 그냥 참고 64 비트 응용 프로그램에 대한 메시지 만 스파이 ++ 어획량의 64 비트 버전은 당신이 표시되지 않는 경우, 그래서 WM_HOTKEY의 메시지 메시지 로그를 핫키를 누른 후, 당신은 스파이의 32 비트 버전을 실행해야 할 수도 있습니다 ++ .
David Ferenczy Rogožan

정말 고맙습니다!!! 나는 이것을 찾을 때까지 기본적으로 몇 가지 단축키 사용을 포기했습니다.
thewindev

3
8 단계에서는 핫키를 요청하지 않고 핫키를 누른 후에도 메시지 창이 계속 비어 있습니다. github.com/westoncampbell/SpyPlusPlus(Windows 10)에서 32 비트 및 64 비트 버전을 사용 했습니다 .
CoolMind

9

몇 가지 조사 후 MS가 핫키를 저장하는 데 사용하는 내부 구조에 액세스해야하는 것으로 보입니다. ReactOS에는 GetHotKey내부 목록을 반복 하고 호출에 매개 변수와 일치하는 핫키를 추출하여 호출 을 구현하는 클린 룸 구현이 있습니다.

ReactOS의 구현이 MS 구현과 얼마나 가까운 지에 따라 구조를 찾기 위해 메모리를 둘러 볼 수 있지만 그것은 내 머리 위에 있습니다 ...

BOOL FASTCALL
GetHotKey (UINT fsModifiers,
           UINT vk,
           struct _ETHREAD **Thread,
           HWND *hWnd,
           int *id)
{
   PHOT_KEY_ITEM HotKeyItem;

   LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
   {
      if (HotKeyItem->fsModifiers == fsModifiers &&
            HotKeyItem->vk == vk)
      {
         if (Thread != NULL)
            *Thread = HotKeyItem->Thread;

         if (hWnd != NULL)
            *hWnd = HotKeyItem->hWnd;

         if (id != NULL)
            *id = HotKeyItem->id;

         return TRUE;
      }
   }

   return FALSE;
}

나는 이 질문과 관련된 누군가가 sysinternals대한이 스레드를 요청했다고 생각하지만 어쨌든 두 가지를 함께 유지하기 위해 링크 할 것이라고 생각했습니다. 스레드는 매우 흥미로워 보이지만 MS 내부에 액세스하지 않고 이것을 알아 내려면 심층 분석이 필요하다고 생각합니다.


3

내 머리 꼭대기에서 EnumWindows를 사용하여 모든 창을 열거 한 다음 콜백에서 WM_GETHOTKEY를 각 창에 보냅니다.

편집 : 갑자기 나는 그것에 대해 틀렸다. MSDN 에는 자세한 정보가 있습니다.

WM_HOTKEY는 WM_GETHOTKEY 및 WM_SETHOTKEY 바로 가기 키와 관련이 없습니다. WM_HOTKEY 메시지는 일반 바로 가기 키에 대해 전송되는 반면 WM_SETHOTKEY 및 WM_GETHOTKEY 메시지는 창 활성화 바로 가기 키와 관련됩니다.

참고 : 다음 은 사용자가 찾고있는 기능을 가지고 있다고 주장하는 프로그램입니다. 디 컴파일을 시도 할 수 있습니다.


3
이제 프로그램에 대한 링크가 완전히 끊어졌습니다. 그게 무슨 프로그램 이었어? 갑자기 더 이상 작동하지 않거나 성가신 새로운 작업을 수행하기 때문에 어떤 프로그램이 내 단축키를 등록했는지 알아 내고 싶습니다.
James Oltmans 2011-08-23

(종종 웹 페이지가 사라진 경우 Wayback Machine이 도움이 될 수 있지만 여기서는 404 Not Found : http://web.archive.org/web/*/tds.diamondcs.com.au/dse/ 만 미러링했습니다 . 탐지 / hotkeys.php )
아론 토마스

2

이것은 당신에게 많은 것을 알려주는 것 같습니다 : http://hkcmdr.anymania.com/help.html


1
그렇습니까? 드라이버로 위장한 DLL? 두 개의 후크를 설정 하는 hoo데 사용 되는 DLL 함수 ( SetWindowHookEx하나 WH_KEYBOARD_LL와 하나) WH_GETMESSAGE... 나머지는 MSDN에 문서화되어 있어야합니다.
0xC0000022L 2011 년

Windows 8 또는 10에서이 앱을 사용하지 마십시오.
Jeff Lange


0

나는 당신이 자신의 프로세스 내에서 어떤 창에서든 메시지의 흐름을 가로 챌 수 있다는 것을 안다. 우리가 VB6에서 서브 클래 싱이라고 부르던 것. (내가 그 함수를 기억하지는 못하지만, 아마도 SetWindowLong?) 자신의 프로세스 외부에있는 창에 대해이 작업을 수행 할 수 있는지 확실하지 않습니다. 그러나이 게시물을 위해 그렇게하는 방법을 찾도록 가정하겠습니다. 그런 다음 모든 최상위 창에 대한 메시지를 간단히 가로 채고 WM_HOTKEY 메시지를 모니터링 할 수 있습니다. 방망이에서 바로 모든 키를 알 수는 없지만 키를 누르면 어떤 응용 프로그램이 키를 사용하고 있는지 쉽게 파악할 수 있습니다. 결과를 디스크에 저장하고 모니터 응용 프로그램이 실행될 때마다 다시로드하면 시간이 지남에 따라 응용 프로그램의 성능을 높일 수 있습니다.


-1

이것은 Windows API에 관한 질문의 일부에 정확히 대답하는 것은 아니지만 전역 단축키 목록과이를 "소유"하는 응용 프로그램에 대한 질문의 일부에 대답합니다.

http://hkcmdr.anymania.com/ 의 무료 핫키 탐색기 는 모든 글로벌 핫키 목록과이를 소유 한 응용 프로그램을 보여줍니다. 이것은 응용 프로그램 별 바로 가기 키가 작동을 멈춘 이유와이를 수정하는 방법 (등록 된 앱에 등록 된 전역 핫키를 재구성하여)을 몇 초 내에 파악하는 데 도움이되었습니다.


4
그것을 설치하고 그것은 나쁜 농담처럼 적어도 쇼핑몰 의도가있는 프로그램은 바이러스처럼 행동했습니다. 모든 종류의 창 열기, 음성
내레이터

3
@Flion : superuser.com/a/191090/3617에서 토론을 참조하십시오 . 기본적으로 일부 핫키 유틸리티는 가능한 모든 키 조합을 조사하여 작동합니다. Windows 8 이상에서 (Windows 7에서는 더 적지 만)이 프로빙 기술 은 단순히 쿼리하는 것이 아니라 모든 키 조합을 트리거 합니다.
Brian

@Flion FWIW, Win7에서 성공적으로 사용했습니다. 그러나 Brian을 올바르게 이해하면 이후 버전에서는 잘 작동하지 않을 수 있으며, 정의 된 사용자 지정 단축키에 따라 작동 방식이 달라질 수 있습니다.
Gerhard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.