반응형

🎯 이 글에서 배우는 것: 디버깅 기법, 에러 처리, 성능 최적화, 고급 팁
🐛 디버깅이란?
디버깅(Debugging)은 코드의 버그(오류)를 찾아 고치는 과정입니다. 스크립트가 예상대로 동작하지 않을 때 필수적인 기술이죠!
🔍 기본 디버깅 기법
1. MsgBox 디버깅 (가장 간단!)
#Requires AutoHotkey v2.0
ProcessData(data) {
MsgBox("1. 함수 시작, data = " data) ; 체크포인트 1
result := data * 2
MsgBox("2. 계산 완료, result = " result) ; 체크포인트 2
if (result > 100) {
MsgBox("3. 조건문 진입") ; 체크포인트 3
result := 100
}
MsgBox("4. 함수 종료, 반환값 = " result) ; 체크포인트 4
return result
}
2. ToolTip 디버깅 (비침습적)
MsgBox는 실행을 멈추지만, ToolTip은 계속 진행하면서 정보 표시:
^j::{
Loop 10 {
ToolTip("현재 반복: " A_Index "`n값: " A_Index * 2)
Sleep(500)
}
ToolTip() ; 툴팁 제거
}
3. 파일 로깅
실행 기록을 파일로 저장:
#Requires AutoHotkey v2.0
LogFile := A_ScriptDir "\debug.log"
Log(message) {
timestamp := FormatTime(, "yyyy-MM-dd HH:mm:ss")
FileAppend(timestamp " - " message "`n", LogFile)
}
; 사용 예시
^j::{
Log("핫키 ^j 실행됨")
try {
result := SomeFunction()
Log("결과: " result)
} catch as e {
Log("에러 발생: " e.Message)
}
}
4. OutputDebug + DebugView
Windows Sysinternals의 DebugView와 함께 사용:
OutputDebug("변수 x의 값: " x)
OutputDebug("함수 진입: ProcessData()")
⚠️ 에러 처리 (Try-Catch)
기본 구조
try {
; 에러가 발생할 수 있는 코드
result := FileRead("없는파일.txt")
} catch as e {
; 에러 처리
MsgBox("에러 발생!`n" e.Message)
}
에러 객체 속성
try {
result := 10 / 0 ; 0으로 나누기
} catch as e {
MsgBox(
"에러 타입: " Type(e) "`n"
"메시지: " e.Message "`n"
"발생 위치: " e.File " (Line " e.Line ")`n"
"추가 정보: " e.Extra
)
}
Finally 블록
에러 발생 여부와 관계없이 항상 실행:
file := FileOpen("test.txt", "w")
try {
file.WriteLine("테스트")
; ... 작업 수행
} catch as e {
MsgBox("에러: " e.Message)
} finally {
file.Close() ; 항상 파일 닫기
}
사용자 정의 에러 던지기
ValidateAge(age) {
if (age < 0)
throw ValueError("나이는 음수일 수 없습니다", -1, age)
if (age > 150)
throw ValueError("나이가 너무 큽니다", -1, age)
return true
}
try {
ValidateAge(-5)
} catch as e {
MsgBox(e.Message)
}
🚀 성능 최적화
1. SetBatchLines 대신 Critical
v2에서는 SetBatchLines가 제거됨. 대신 Critical 사용:
^j::{
Critical ; 인터럽트 방지, 성능 향상
Loop 10000 {
; 빠른 처리가 필요한 작업
}
Critical("Off") ; 다시 일반 모드
}
2. 변수 캐싱
반복적인 함수 호출 피하기:
; 나쁜 예 - 매번 함수 호출
Loop 1000 {
if (StrLen(myString) > 10) ; 매번 길이 계산
; ...
}
; 좋은 예 - 한 번만 계산
len := StrLen(myString)
Loop 1000 {
if (len > 10)
; ...
}
3. 문자열 연결 최적화
; 나쁜 예 - 매번 새 문자열 생성
result := ""
Loop 1000 {
result := result . A_Index . "`n" ; 느림
}
; 좋은 예 - 배열 사용 후 한 번에 결합
parts := []
Loop 1000 {
parts.Push(A_Index)
}
result := ""
for item in parts
result .= item "`n"
4. Sleep 적절히 사용
; CPU 과부하 방지
Loop {
; 작업 수행
Sleep(10) ; 적절한 대기
}
5. 핫키 범위 제한 (#HotIf)
; 전역 핫키 - 항상 메모리 사용
^j::MsgBox("어디서든")
; 조건부 핫키 - 필요할 때만 활성화
#HotIf WinActive("ahk_exe notepad.exe")
^j::MsgBox("메모장에서만")
#HotIf
🔧 자주 발생하는 문제와 해결
문제 1: 핫키가 작동하지 않음
원인과 해결:
; 1. 스크립트가 실행 중인지 확인
; → 트레이 아이콘 확인
; 2. 관리자 권한 필요할 수 있음
; → 우클릭 → 관리자 권한으로 실행
; 3. 다른 프로그램이 핫키 사용 중
; → 다른 키 조합 시도
; 4. 핫키 문법 확인
^j::MsgBox("OK") ; 올바름
Ctrl+j::MsgBox() ; 잘못됨!
문제 2: Send가 제대로 입력 안 됨
; 1. 대상 프로그램이 특수한 경우
Send("Hello") ; 일반
SendInput("Hello") ; 더 빠름, 보통 권장
SendEvent("Hello") ; 호환성 좋음
SendPlay("Hello") ; 게임용 (관리자 권한 필요)
; 2. 타이밍 문제
Send("^c")
Sleep(100) ; 클립보드 복사 대기
Send("^v")
; 3. 특수문자 문제
Send("{Enter}") ; 올바름
Send("Enter") ; "Enter" 문자가 입력됨!
; 4. 텍스트 그대로 입력
SendText("^!#") ; 특수 키로 해석 안 함
문제 3: 창을 찾지 못함
; Window Spy로 정확한 제목/클래스 확인!
; 부분 일치
SetTitleMatchMode(2) ; 제목에 포함되면 OK
WinActivate("메모장")
; 정규식 사용
SetTitleMatchMode("RegEx")
WinActivate(".*메모장.*")
; 클래스로 찾기 (더 정확)
WinActivate("ahk_class Notepad")
; 실행 파일로 찾기
WinActivate("ahk_exe notepad.exe")
문제 4: 한글 입력 문제
; SendText로 해결
SendText("안녕하세요") ; Send 대신 SendText
; 또는 클립보드 이용
A_Clipboard := "안녕하세요"
Send("^v")
문제 5: 무한 루프
; 탈출 키 항상 준비!
Esc::ExitApp
; 또는 안전장치
count := 0
Loop {
count++
if (count > 1000) {
MsgBox("무한 루프 방지!")
break
}
; 작업
}
💡 고급 팁과 트릭
1. 조건부 컴파일
#Requires AutoHotkey v2.0
DEBUG := true ; false로 바꾸면 디버그 출력 비활성화
DebugLog(msg) {
if DEBUG
ToolTip(msg)
}
^j::{
DebugLog("핫키 실행됨")
; 실제 작업
}
2. 설정 파일 사용 (INI)
settingsFile := A_ScriptDir "\settings.ini"
; 설정 저장
IniWrite("value1", settingsFile, "Section", "Key1")
IniWrite("value2", settingsFile, "Section", "Key2")
; 설정 읽기
val1 := IniRead(settingsFile, "Section", "Key1", "default")
val2 := IniRead(settingsFile, "Section", "Key2", "default")
3. 스크립트 자동 시작
; 시작프로그램에 바로가기 생성
startupFolder := A_Startup
shortcutPath := startupFolder "\MyScript.lnk"
if !FileExist(shortcutPath) {
FileCreateShortcut(A_ScriptFullPath, shortcutPath)
MsgBox("시작프로그램에 등록됨!")
}
4. 트레이 메뉴 커스터마이징
; 기본 메뉴 제거하고 커스텀 메뉴 생성
A_TrayMenu.Delete()
A_TrayMenu.Add("설정", ShowSettings)
A_TrayMenu.Add("도움말", ShowHelp)
A_TrayMenu.Add() ; 구분선
A_TrayMenu.Add("새로고침", (*) => Reload())
A_TrayMenu.Add("종료", (*) => ExitApp())
ShowSettings(*) {
MsgBox("설정 화면")
}
ShowHelp(*) {
Run("https://www.autohotkey.com/docs/v2/")
}
5. 핫키 동적 생성/해제
; 핫키 동적 생성
Hotkey("^j", MyFunc)
MyFunc(*) {
MsgBox("동적 핫키!")
}
; 핫키 비활성화
Hotkey("^j", "Off")
; 핫키 다시 활성화
Hotkey("^j", "On")
; 핫키 재할당
Hotkey("^j", AnotherFunc)
6. 타이머 활용
; 5초마다 실행
SetTimer(MyTimer, 5000)
MyTimer() {
ToolTip("5초 경과!")
SetTimer(() => ToolTip(), -1000) ; 1초 후 툴팁 제거
}
; 타이머 중지
; SetTimer(MyTimer, 0)
📝 체크리스트: 스크립트 배포 전 확인사항
□ #Requires AutoHotkey v2.0 선언됨
□ #SingleInstance Force 추가됨
□ 모든 경로가 절대경로 또는 A_ScriptDir 기준
□ 에러 처리 (try-catch) 추가됨
□ 디버그용 MsgBox 제거됨
□ 탈출 키 (Esc::ExitApp 등) 설정됨
□ 주석으로 코드 설명 추가됨
□ 다른 PC에서 테스트됨
🛠️ 유용한 도구들
| 도구 | 용도 |
|---|---|
| Window Spy | 창 제목, 클래스, 좌표 확인 (AHK 설치 시 포함) |
| VS Code + AHK v2 확장 | 코드 편집, 문법 강조, 자동완성 |
| SciTE4AutoHotkey | AHK 전용 에디터 |
| DebugView | OutputDebug 메시지 확인 |
| AHK v2 공식 문서 | 함수 레퍼런스 |
🎓 더 배우려면
공식 리소스
추천 학습 순서
- 공식 튜토리얼 완독
- 포럼의 Scripts and Functions 섹션 탐색
- 다른 사람 스크립트 분석
- 자신만의 프로젝트 시작
🏁 시리즈를 마치며
15회에 걸쳐 AutoHotkey v2의 기초부터 실전까지 함께했습니다!
우리가 배운 것들
| 회차 | 주제 |
|---|---|
| 1-2 | 설치, 첫 스크립트 |
| 3-4 | 핫키, 핫스트링 |
| 5-6 | Send/Click, Run/창 관리 |
| 7-8 | 변수/데이터타입, 제어문 |
| 9-10 | 함수, 키 리매핑 |
| 11-12 | GUI, 파일 다루기 |
| 13-14 | 문자열 처리, 실전 예제 |
| 15 | 디버깅과 팁 |
앞으로의 여정
이제 기초는 끝났습니다. 진짜 실력은 직접 만들어보면서 늡니다!
- 불편한 것을 발견하면 → "이거 자동화할 수 있을까?" 생각하기
- 작은 스크립트부터 시작
- 조금씩 기능 추가
- 다른 사람 코드 참고
- 포럼에서 질문하고 답변하기
💬 마지막 팁
"완벽한 스크립트는 없습니다. 작동하는 스크립트가 최고입니다!"
처음엔 지저분해도 괜찮습니다. 일단 돌아가게 만들고, 나중에 다듬으세요.
AutoHotkey와 함께 더 효율적인 컴퓨터 생활을 즐기시길 바랍니다! 🎉
📚 전체 시리즈 목록
- AutoHotkey v2 소개 및 설치
- 첫 스크립트 작성하기
- 핫키(Hotkey) 기초
- 핫스트링(Hotstring)
- 키보드/마우스 입력 보내기
- 프로그램 실행과 창 관리
- 변수와 데이터 타입
- 제어문
- 함수 기초
- 키 리매핑
- GUI 기초
- 파일 다루기
- 문자열 처리
- 실전 예제 모음
- 디버깅과 팁 ← 현재 글
이전 글: [#14 실전 예제 모음]
시리즈 완결! 🎊
반응형
'🔬 과학·테크 > 🔥 AutoHotkey v2 입문 가이드' 카테고리의 다른 글
| AutoHotkey v2 입문 가이드 #14: 실전 예제 모음 - 바로 쓰는 스크립트 10선 (0) | 2025.12.17 |
|---|---|
| AutoHotkey v2 입문 가이드 #13: 문자열 처리 - 텍스트 다루기의 기술 (0) | 2025.12.16 |
| AutoHotkey v2 입문 가이드 #12: 파일 다루기 - 읽고, 쓰고, 관리하기 (0) | 2025.12.15 |
| AutoHotkey v2 입문 가이드 #11: GUI 기초 - 나만의 창 만들기 (0) | 2025.12.14 |
| AutoHotkey v2 입문 가이드 #10: 키 리매핑 - 키보드 재창조하기 (0) | 2025.12.13 |