⚠️ 바로가기 `.lnk` 한글 경로 때문에 6번 디버깅한 썰 (feat. Base64)

송연지·2025년 6월 11일
0

트러블슈팅

목록 보기
28/32

🧠 시작은 단순했다: “바로가기(l .lnk)도 처리해야겠네?”

보안 기능을 만들면서 실행 파일 감지를 하는데,

생각보다 이런 경로가 많이 튀어나왔다:


C:\ProgramData\Microsoft\Windows\Start Menu\Programs\한셀 2024.lnk

“어? EXE가 아니고 LNK네?”

맞다. 대부분의 사용자는 프로그램을 직접 실행하는 게 아니라 시작메뉴 / 바탕화면 바로가기를 클릭한다.

결국 .lnk 파일을 열어서 실제 실행 대상(EXE 경로)을 뽑아야 한다는 결론에 도달했다.


🔎 LNK 구조 분석 & PowerShell 구현

Windows .lnk 파일은 단순 텍스트가 아니다.

WScript.Shell COM 객체를 통해 접근해야 한다.

PowerShell 스크립트는 간단했다:

powershell
복사편집
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut("C:\경로\한셀 2024.lnk")
$shortcut.TargetPath

이걸 Electron에서 Node.js child_process.spawn()으로 실행하면 끝이다.

그럴 줄 알았다.


💣 문제: “PowerShell에선 되는데 Electron에선 안 된다”

PowerShell 콘솔에선 잘 되는데,

Electron에서 실행하면 결과가 무조건 '' (빈 문자열).

ts
복사편집
// Electron
const result = await execPowerShell('한셀 2024.lnk');
console.log(result); // ''

내가 시도했던 디버깅 1~6단계

순번시도결과
1파일 경로 확인존재함
2경로 하드코딩해보기여전히 빈 문자열
3UTF-8로 파일 저장안 됨
4-Encoding UTF8 옵션 추가무효
5PowerShell 내부에 echo 찍기출력됨 → 경로만 깨짐
6console.log(filePath) 확인한글 잘 찍힘 → 파워셸로 넘어가는 중 깨짐

🧬 원인 분석

Electron → PowerShell 호출 시, 인자로 전달되는 경로가 한글이면 깨진다.

왜냐면:

  • Electron(Node.js)은 기본적으로 UTF-8
  • PowerShell은 윈도우 로케일 영향으로 CP949를 쓸 수도 있음
  • 그래서 CLI 인자 전달 시 한글이 깨짐 (CreateShortcut('��� 2024.lnk') ← 이렇게 변형됨)

🤦 “UTF-8로 저장하면 되겠지”는 착각이었다

처음엔 이렇게 생각했다:

“스크립트 파일 자체를 UTF-8 BOM으로 저장하면 되겠지?”

❌ 결과: 안 됨

왜냐하면 깨지는 시점이 스크립트 실행이 아니라, 경로 인자 전달 시점이기 때문이다.


🧠 Base64라는 진짜 해결책

결국 알게 됐다:

Electron → PowerShell 전달 경로를 Base64로 인코딩해서 넘기면 된다.

Base64는 ASCII 문자만으로 구성되어

OS, 로케일, 인코딩 충돌 없이 항상 안전하게 전송된다.

👇 그래서 이렇게 바꿨다:

🔁 Electron:


const encoded = Buffer.from(filePath, 'utf8').toString('base64');
spawn('powershell.exe', ['-File', 'script.ps1', encoded]

🔁 PowerShell:


param($encoded)
$decoded = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($encoded))
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($decoded)
$shortcut.TargetPath

Boom! 이제 한글 경로도 완벽하게 처리된다.


🧪 왜 Base64만이 해결책인가?

항목UTF-8Base64
한글 포함 문자열 처리깨질 수 있음절대 안 깨짐
CLI 인자 안전성❌ OS에 따라 다름✅ 항상 안전
PowerShell 환경 일관성❌ 인코딩 로케일 영향 받음✅ ASCII 문자만 사용
사용 목적저장, 출력용데이터 전송, 인자 전달용

핵심:

UTF-8은 문자열 인코딩이고, Base64는 전송 인코딩이다.

CLI 인자, 파일 경로, JSON 내 인자처럼 전송이 필요한 곳엔 Base64가 정답이다.


✅ 최종 구현 흐름

  1. LNK 경로 Base64 인코딩
  2. PowerShell에 전달
  3. Base64 디코딩 후 CreateShortcut으로 대상 추출
  4. 대상 EXE가 존재하면 해당 경로의 파일 메타데이터도 추출

이제 아래처럼 JSON으로 묶어서 반환된다:


{
  "lnk": {
    "filePath": "C:\\...\\한셀 2024.lnk",
    "targetPath": "C:\\Program Files\\HCell.exe",
    "description": "한글 스프레드시트"
  },
  "exe": {
    "progNm": "한셀 2024",
    "prdNm": "HCell",
    "signValid": true}
}

🧠 마무리 회고

처음엔 단순히 “바로가기도 처리해야겠다”는 생각이었는데,

그 끝엔 인코딩 지옥, CLI 디버깅, PowerShell 삽질이 기다리고 있었다.

그나마 다행인 건,

이제는 한글 포함된 모든 바로가기를 완벽하게 처리할 수 있게 됐다는 점이다.

💡 개발자를 위한 TIP: CLI(Command-Line Interface)란?

CLI란?

Command-Line Interface의 줄임말로,

GUI(그래픽 사용자 인터페이스) 없이 명령어를 텍스트로 입력해서 컴퓨터를 조작하는 방식이다.

  • 대표 예시:
    • Windows의 cmd.exe, powershell.exe
    • macOS, Linux의 bash, zsh, terminal

# 예시: 파일 경로를 인자로 받아 처리하는 명령
powershell.exe -File myscript.ps1 "C:\Users\연지\문서\바로가기.lnk"

왜 CLI에서 문제가 발생했을까?

  • CLI는 텍스트 기반이라 '한글' → byte → 다시 문자열로 변환되는 과정에서 인코딩 오류가 생기기 쉬움
  • 특히 PowerShell은 시스템 로케일(예: CP949)을 따라가는 반면, Electron(Node.js)은 UTF-8을 기본으로 사용함
  • 이 차이로 인해 CLI 인자로 한글을 넘길 때 깨지는 현상이 발생했다

👉 그래서 해결책은?

Base64 인코딩으로 경로를 감싼 다음 넘기면, CLI 내부에서 무조건 안전하게 처리 가능

CLI에서는 데이터를 다룰 때 문자 그대로 전달되는 게 아니라 바이트 수준의 처리가 되기 때문에,

ASCII만 사용하는 Base64가 매우 안정적인 해결책이 된다.

👇 개발자 여러분, 이건 꼭 기억하세요:

PowerShell에서 잘 된다고 Electron에서도 잘 되리라는 법은 없다.

CLI 인자엔 무조건 Base64를 써라.

아니면 3시간 날릴 수 있다 😇

profile
프론트엔드 개발쟈!!

0개의 댓글