게임을 하다가 갑자기 키보드 입력이 끊기는 경우가 종종 발생하였다.
(예를 들어, 앞으로 움직이는 키를 계속 누르고 있는데 잠깐 멈췄다가 다시 앞으로 움직이는 현상)
Back Ground에서 실행되는 프로세스가 창을 생성하여 키보드 포커스를 뺐어가는 것으로 의심되어, window focus event를 수신하는 python script를 실행해서 추적해보았다.
"""
FileName : trackwindow.py
Log window focus and appearance.
Written to try to debug some window popping up and stealing focus from my
Spelunky game for a split second.
Developed with 32-bit python on Windows 7. Might work in other environments,
but some of these APIs might not exist before Vista.
Much credit to Eric Blade for this:
https://mail.python.org/pipermail/python-win32/2009-July/009381.html
and David Heffernan:
http://stackoverflow.com/a/15898768/9585
"""
# using pywin32 for constants and ctypes for everything else seems a little
# indecisive, but whatevs.
import win32con
import sys
import ctypes
import ctypes.wintypes
user32 = ctypes.windll.user32
ole32 = ctypes.windll.ole32
kernel32 = ctypes.windll.kernel32
WinEventProcType = ctypes.WINFUNCTYPE(
None,
ctypes.wintypes.HANDLE,
ctypes.wintypes.DWORD,
ctypes.wintypes.HWND,
ctypes.wintypes.LONG,
ctypes.wintypes.LONG,
ctypes.wintypes.DWORD,
ctypes.wintypes.DWORD
)
# The types of events we want to listen for, and the names we'll use for
# them in the log output. Pick from
# http://msdn.microsoft.com/en-us/library/windows/desktop/dd318066(v=vs.85).aspx
eventTypes = {
win32con.EVENT_SYSTEM_FOREGROUND: "Foreground",
win32con.EVENT_OBJECT_FOCUS: "Focus",
win32con.EVENT_OBJECT_SHOW: "Show",
win32con.EVENT_SYSTEM_DIALOGSTART: "Dialog",
win32con.EVENT_SYSTEM_CAPTURESTART: "Capture",
win32con.EVENT_SYSTEM_MINIMIZEEND: "UnMinimize"
}
# limited information would be sufficient, but our platform doesn't have it.
processFlag = getattr(win32con, 'PROCESS_QUERY_LIMITED_INFORMATION',
win32con.PROCESS_QUERY_INFORMATION)
threadFlag = getattr(win32con, 'THREAD_QUERY_LIMITED_INFORMATION',
win32con.THREAD_QUERY_INFORMATION)
# store last event time for displaying time between events
lastTime = 0
def log(msg):
print(msg)
def logError(msg):
sys.stdout.write(msg + '\n')
def getProcessID(dwEventThread, hwnd):
# It's possible to have a window we can get a PID out of when the thread
# isn't accessible, but it's also possible to get called with no window,
# so we have two approaches.
hThread = kernel32.OpenThread(threadFlag, 0, dwEventThread)
if hThread:
try:
processID = kernel32.GetProcessIdOfThread(hThread)
if not processID:
logError("Couldn't get process for thread %s: %s" %
(hThread, ctypes.WinError()))
finally:
kernel32.CloseHandle(hThread)
else:
errors = ["No thread handle for %s: %s" %
(dwEventThread, ctypes.WinError(),)]
if hwnd:
processID = ctypes.wintypes.DWORD()
threadID = user32.GetWindowThreadProcessId(
hwnd, ctypes.byref(processID))
if threadID != dwEventThread:
logError("Window thread != event thread? %s != %s" %
(threadID, dwEventThread))
if processID:
processID = processID.value
else:
errors.append(
"GetWindowThreadProcessID(%s) didn't work either: %s" % (
hwnd, ctypes.WinError()))
processID = None
else:
processID = None
if not processID:
for err in errors:
logError(err)
return processID
def getProcessFilename(processID):
hProcess = kernel32.OpenProcess(processFlag, 0, processID)
if not hProcess:
logError("OpenProcess(%s) failed: %s" % (processID, ctypes.WinError()))
return None
try:
filenameBufferSize = ctypes.wintypes.DWORD(4096)
filename = ctypes.create_unicode_buffer(filenameBufferSize.value)
kernel32.QueryFullProcessImageNameW(hProcess, 0, ctypes.byref(filename),
ctypes.byref(filenameBufferSize))
return filename.value
finally:
kernel32.CloseHandle(hProcess)
def callback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread,
dwmsEventTime):
global lastTime
length = user32.GetWindowTextLengthW(hwnd)
title = ctypes.create_unicode_buffer(length + 1)
user32.GetWindowTextW(hwnd, title, length + 1)
processID = getProcessID(dwEventThread, hwnd)
shortName = '?'
if processID:
filename = getProcessFilename(processID)
if filename:
shortName = '\\'.join(filename.rsplit('\\', 2)[-2:])
if hwnd:
hwnd = hex(hwnd)
elif idObject == win32con.OBJID_CURSOR:
hwnd = '<Cursor>'
log(u"%s:%04.2f\t%-10s\t"
u"W:%-8s\tP:%-8d\tT:%-8d\t"
u"%s\t%s" % (
dwmsEventTime, float(dwmsEventTime - lastTime)/1000, eventTypes.get(event, hex(event)),
hwnd, processID or -1, dwEventThread or -1,
shortName, title.value))
lastTime = dwmsEventTime
def setHook(WinEventProc, eventType):
return user32.SetWinEventHook(
eventType,
eventType,
0,
WinEventProc,
0,
0,
win32con.WINEVENT_OUTOFCONTEXT
)
def main():
ole32.CoInitialize(0)
WinEventProc = WinEventProcType(callback)
user32.SetWinEventHook.restype = ctypes.wintypes.HANDLE
hookIDs = [setHook(WinEventProc, et) for et in eventTypes.keys()]
if not any(hookIDs):
print('SetWinEventHook failed')
sys.exit(1)
msg = ctypes.wintypes.MSG()
while user32.GetMessageW(ctypes.byref(msg), 0, 0, 0) != 0:
user32.TranslateMessageW(msg)
user32.DispatchMessageW(msg)
for hookID in hookIDs:
user32.UnhookWinEvent(hookID)
ole32.CoUninitialize()
if __name__ == '__main__':
main()
명령어 프롬프트를 열어서 python script를 실행한다. (명령어 프롬프트를 관리자 권한으로 실행해야 한다.)
python .\trackwindow.py
실행 결과를 확인해 보니, TDepend 프로세스가 창을 짧은 시간동안 생성해서 Focus를 가져가는 것으로 확인하였다.
58179500:0.88 Foreground W:0xf0a9c P:22056 T:34236 SysWOW64\TDepend.exe TDependPsc32
58179500:0.00 Foreground W:0x170858 P:30788 T:30448 SysWOW64\TDepend64.exe TDependPsc64
58179500:0.00 Focus W:0xf0a9c P:22056 T:34236 SysWOW64\TDepend.exe TDependPsc32
58179515:0.01 Show W:0xf0a9c P:22056 T:34236 SysWOW64\TDepend.exe TDependPsc32
58179515:0.00 Focus W:0x170858 P:30788 T:30448 SysWOW64\TDepend64.exe TDependPsc64
58179515:0.00 Focus W:None P:22056 T:34236 SysWOW64\TDepend.exe
58179515:0.00 Show W:0x170858 P:30788 T:30448 SysWOW64\TDepend64.exe TDependPsc64
추가로 검색 해보니, Tcube라는 캡처 방지 프로그램(회사 재택근무 용)이 생성하는 프로세스 였다.
http://www.teruten.com/kr/solution/virtualization.php
테르텐 - 제품 - 화면 보안
안전한 보안 기술을 개발하는 보안 전문 회사 테르텐
www.teruten.com
Tcube 프로그램을 제거하니, 키보드 입력이 끊기는 현상이 없어졌다.
(재택근무 할때마다 Tcube를 재설치 해야한다.... ㅠㅠ)
출처
'Window Tool' 카테고리의 다른 글
| "화면 끄기" 바로가기 생성 (0) | 2025.10.11 |
|---|---|
| 윈도우10 로그인 화면 제거 (0) | 2025.05.25 |
| 윈도우 10 & 11 언어 설치 Error : 0x800F0954 (1) | 2024.02.05 |
| CSR 블루투스 동글 & 윈도우10 (0) | 2024.02.05 |
| [컴퓨터 관리] USB 저장장치 파일탐색기 인식 문제 (0) | 2024.02.05 |