2017-07-03 9 views
1

私はユーザーからのキー押下回数を追跡しようとしていますが、私はそれがクライアントかゲームかにかかわらずSteamと何かを実現するようになりましたそれを介して起動、それは動作を停止します。 の代わりにGetKeyStateを使用すると、ctrl、shift、tab、backspace、enterなどのキーボードの端にあるビットを拾うことができます。私はまた、Task ManagerやDiscordのような少数の他のプログラムでも同じ動作を見つけました。Steamや他のいくつかのプログラムからキーストロークを受け取ることができません

GetKeyStateGetAsyncKeyStateを使用して、私は​​とpywin32の両方で試してみました。

また、IInspectableが低レベルのキーボードフックを見ると、2つの異なるバージョンを試してみると、まったく同じ問題が発生しています。あなたはたとえば、「c」を押した場合、あなたはすべての4を示しており、[('C', 1), ('C', 2), ('C', 3), ('C', 4)]になるだろう、コンピュータ上のどこからでも

import ctypes 
try: 
    import win32api 
except ImportError: 
    win32api = None 

def get_key_press1(key): 
    return win32api.GetAsyncKeyState(key) 

def get_key_press2(key): 
    return win32api.GetKeyState(key) < 0 

def get_key_press3(key): 
    return ctypes.windll.user32.GetKeyState(key) > 1 

def get_key_press4(key): 
    return ctypes.windll.user32.GetAsyncKeyState(key) 

KEYS = { 
    'BACK': 8, 
    'TAB': 9, 
    'CLEAR': 12, 
    'RETURN': 13, 
    'PAUSE': 19, 
    'CAPSLOCK': 20, 
    'ESC': 27, 
    'SPACE': 32, 
    'PGUP': 33, 
    'PGDOWN': 34, 
    'END': 35, 
    'HOME': 36, 
    'LEFT': 37, 
    'UP': 38, 
    'RIGHT': 39, 
    'DOWN': 40, 
    'INSERT': 45, 
    'DELETE': 46, 
    'LWIN': 91, 
    'RWIN': 92, 
    'MENU': 93, 
    'NUM0': 96, 
    'NUM1': 97, 
    'NUM2': 98, 
    'NUM3': 99, 
    'NUM4': 100, 
    'NUM5': 101, 
    'NUM6': 102, 
    'NUM7': 103, 
    'NUM8': 104, 
    'NUM9': 105, 
    'MULTIPLY': 106, 
    'ADD': 107, 
    'SUBTRACT': 109, 
    'DECIMAL': 110, 
    'DIVIDE': 111, 
    'F1': 112, 
    'F2': 113, 
    'F3': 114, 
    'F4': 115, 
    'F5': 116, 
    'F6': 117, 
    'F7': 118, 
    'F8': 119, 
    'F9': 120, 
    'F10': 121, 
    'F11': 122, 
    'F12': 123, 
    'F13': 124, 
    'F14': 125, 
    'F15': 126, 
    'F16': 127, 
    'F17': 128, 
    'F18': 129, 
    'F19': 130, 
    'F20': 131, 
    'F21': 132, 
    'F22': 133, 
    'F23': 134, 
    'F24': 135, 
    'NUMLOCK': 144, 
    'SCROLLLOCK': 145, 
    'LSHIFT': 160, 
    'RSHIFT': 161, 
    'LCTRL': 162, 
    'RCTRL': 163, 
    'LALT': 164, 
    'RALT': 165, 
    'COLON': 186, 
    'EQUALS': 187, 
    'COMMA': 188, 
    'UNDERSCORE': 189, 
    'PERIOD': 190, 
    'FORWARDSLASH': 191, 
    'AT': 192, 
    'LBRACKET': 219, 
    'BACKSLASH': 220, 
    'RBRACKET': 221, 
    'HASH': 222, 
    'TILDE': 223 
} 
for c in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'): 
    KEYS[c] = ord(c) 


while True: 
    all_pressed = [] 
    for k in KEYS: 
     if win32api: 
      if get_key_press1(KEYS[k]): 
       all_pressed.append((k, 1)) 
      if get_key_press2(KEYS[k]): 
       all_pressed.append((k, 2)) 
     if get_key_press3(KEYS[k]): 
      all_pressed.append((k, 3)) 
     if get_key_press4(KEYS[k]): 
      all_pressed.append((k, 4)) 
    if all_pressed: 
     print all_pressed 

を:ここで

は、すべての機能に問題があることを実証するためのいくつかのコードです関数がそれを取得しています。 Steamに関連するものに焦点を当てて何も表示されていないときは、それを押してください。しかし、作業ボタンの1つを押すと [('LCTRL', 2), ('LCTRL', 3)]となり、 GetKeyStateの機能だけがそれを取り上げています。

私は過去数ヶ月間におよそ30試合でスクリプトをテストしましたが、スチームはキーボードトラッキングを有効にしていない唯一のものです。私は、Steamバージョンと比較するためにFactorioのスタンドアロン版をダウンロードしただけでも、完璧に機能しました。

明らかに何か不足していますか、またはキープレスを取得するためのよりよい方法がありますか?それはスクリプトの中で最もシンプルな部分でなければならないので少し迷惑ですが、それは修正不可能な部分です。

明確にするために、キーがその時点で押されているかどうかによって、True/Falseを返す関数を使用するのが理想的です。

+0

あなたがキーボード入力を監視したい場合は、キーボード入力を監視します。仕事のための適切なツールは、低レベルのキーボードフックです。 – IInspectable

+0

Googleに回答し、[this](https://stackoverflow.com/a/16430918/2403000)の回答と[this](https://gist.github.com/ethanhs/80f0a7cc5c7881f5921f)の例を試しましたが、同じ問題。私はまた、タスクマネージャーとDiscordが同じ問題を抱えていることを発見したので、Steamに関連するものではないので、質問を更新します。 – Peter

+0

低レベルのキーボードフックが入力を監視できない場合は、アプリケーションがそれを積極的に禁止しているためです。ドキュメンテーションでは、その方法を説明しています。その時点で、それはユーザーモードからのかなりのゲームオーバーです。 – IInspectable

答えて

0

フィジックスを見つけようと3ヵ月もの間に何度も試みたところ、私は問題を見つけました。それは管理者として実行されていませんでした。

他の誰かがこの問題を抱えている場合は、ここで私が結んだコードを示します。スクリプトの最初にelevate()を実行しますが、それを使用している場合はfreeze_supportの後にあることを確認してください。

pywin32:

def elevate(console=True): 
    arg = 'forced_elevate' 
    if sys.argv[-1] != arg and not win32com.shell.shell.IsUserAnAdmin(): 
     script = os.path.abspath(sys.argv[0]) 
     params = ' '.join([script] + sys.argv[1:] + [arg]) 
     try: 
      win32com.shell.shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params, nShow=5 if console else 0) 
     except pywintypes.error: 
      pass 
     else: 
      sys.exit(0) 

のctypes:

def elevate(console=True): 
    arg = 'forced_elevate' 
    if sys.argv[-1] != arg and not ctypes.windll.shell32.IsUserAnAdmin(): 
     script = os.path.abspath(sys.argv[0]) 
     params = u' '.join([script] + sys.argv[1:] + [arg]) 
     ret = ctypes.windll.shell32.ShellExecuteW(None, u'runas', unicode(sys.executable), params, None, 5 if console else 0) 
     if int(ret) > 32: 
      sys.exit(0) 
関連する問題