🧑‍💻 개발 지식

홈 › 개발 지식

윈도우 11에서 wmic가 사라져 예약 작업이 조용히 멈춘 이야기 (파이썬 대체 코드)

작성 2026-10-20

매일 자정에 도는 파이썬 작업이 있었습니다. 새 데이터를 모으고, 정적 사이트를 다시 만들어 배포하고, 다른 PC로 넘길 요약 파일을 만드는 작업입니다. 어느 날 보니 사이트가 하루 동안 갱신되지 않았고, 로그에는 이 한 줄만 있었습니다.

FileNotFoundError: [WinError 2] 지정된 파일을 찾을 수 없습니다

오류가 났는데도 작업은 죽지 않았고, 마지막 요약 단계만 어제 데이터로 정상 완료된 것처럼 끝났습니다. 원인과 해결을 정리합니다.

원인: wmic가 없다

각 단계 시작 전에 "같은 스크립트가 이미 돌고 있는지" 확인하는 코드가 있었습니다. 매시간 도는 빌드와 겹치지 않게 하려는 것입니다.

r = subprocess.run(
    ["wmic", "process", "where", "name like 'python%'", "get", "commandline"],
    capture_output=True, text=True)
return script_name in r.stdout

WMIC는 오래전에 지원 중단(deprecated)이 예고됐고, 최신 윈도우 11 빌드에는 기본으로 설치되어 있지 않습니다. 그래서 subprocess.run이 실행 파일을 찾지 못하고 FileNotFoundError를 냅니다. 저는 단계마다 try/except로 감싸고 오류를 로그에만 남겼기 때문에, 작업이 죽지 않고 해당 단계만 조용히 건너뛰었습니다.

대체 1: PowerShell CIM (추가 설치 없음)

Get-CimInstance Win32_Process가 WMIC와 같은 정보를 줍니다.

import subprocess

NO_WINDOW = 0x08000000  # 예약 작업에서 콘솔 창이 뜨지 않게

def is_running(script_name: str) -> bool:
    ps = ("(Get-CimInstance Win32_Process "
          "-Filter \"Name like 'python%'\").CommandLine")
    r = subprocess.run(["powershell", "-NoProfile", "-Command", ps],
                       capture_output=True, text=True, errors="ignore",
                       creationflags=NO_WINDOW)
    if r.returncode != 0:
        raise RuntimeError(f"프로세스 확인 실패: {r.stderr[-200:]}")
    return script_name in r.stdout

대체 2: psutil (패키지를 추가해도 된다면)

import psutil

def is_running(script_name: str) -> bool:
    for p in psutil.process_iter(["name", "cmdline"]):
        name = (p.info["name"] or "").lower()
        if name.startswith("python") and any(script_name in a for a in (p.info["cmdline"] or [])):
            return True
    return False

더 빠르고 운영체제에 상관없이 동작합니다. 일부 프로세스는 cmdline 접근이 거부되는데, process_iter에 속성 목록을 주면 예외 대신 None이 들어오므로 or []로 처리합니다.

진짜 수정: 점검이 실패하면 멈추게 한다

더 큰 문제는 호출하는 쪽이었습니다.

# 수정 전: 점검 실패도 "기다릴 게 없음"으로 취급됨
try:
    wait_until_free("build.py")
    run_build()
except Exception as e:
    log("build 실패", e)
# 수정 후: 대기에 제한 시간이 있고, 점검 자체가 깨지면 작업을 멈춘다
for _ in range(60):               # 최대 30분
    if not is_running("build.py"):
        break
    time.sleep(30)
else:
    raise RuntimeError("build.py가 30분 뒤에도 실행 중")
run_build()

그리고 마지막 요약 단계는 앞 단계가 성공했을 때만 요약을 만들게 바꿨습니다. 실패한 밤이 평온한 밤처럼 보이지 않게 하려는 것입니다.

윈도우 자동화 점검 목록

저는 정보 사이트를 AI 코딩 에이전트와 함께 운영하며 이런 자동화를 매일 돌리고 있습니다. 그 사이트는 루리의 줍줍이고, 자동화·개발 기록은 개발 지식에 쌓고 있습니다.

관련: 개발 지식 전체

이 글에 대해 묻고 싶으면 ❓ 개발 FAQ에 남겨 주세요.

📤 공유