작업 스케줄러 파이썬 검은 창, pythonw 인데도 CMD 창이 뜰 때

요약

예약 작업이 돌 때마다 검은 콘솔 창이 튀어나오고, pythonw 로 띄운 프로그램도 ssh 나 ffmpeg 를 부를 때마다 CMD 창이 깜빡입니다. 스케줄러에 python.exe 를 그대로 등록했고, 창 없는 부모가 콘솔 프로그램을 부르면 윈도우가 자식마다 새 창을 만듭니다. 스케줄러에는 wscript.exe 와 VBS 래퍼로 등록하고, 자식 프로세스는 CREATE_NO_WINDOW 로 띄웁니다.

배경에서 도는 작업은 눈에 띄지 않아야 합니다. 그런데 윈도우에서 파이썬을 예약 실행하면 창이 생각보다 자주 튀어나옵니다. 원인은 두 갈래였고, 고치는 자리도 달랐습니다.

하루 96번 튀어나오는 검은 창

15분마다 도는 예약 작업이 실행될 때마다 검은 콘솔 창을 화면 맨 앞으로 띄웠습니다. 하루로 치면 96번입니다. 문서를 쓰는 중에 창이 포커스를 빼앗아 가서 타이핑이 그쪽으로 들어가고 오타가 났습니다.

또 다른 경우는 일부러 pythonw.exe 로 띄운 백그라운드 파이썬이었습니다. 자기 창은 없는데도 주기마다 ssh 로 서버에 접속하거나 ffmpeg 를 부를 때 CMD 창이 잠깐 떴다 사라졌습니다.

부모의 창과 자식의 창은 따로다

상황 창이 뜨는 이유 고칠 자리
스케줄러에 python.exe 등록 콘솔 프로그램이라 실행마다 콘솔 창이 할당되고 보임 스케줄러 등록 방식
pythonw 가 ssh, ffmpeg 호출 창 없는 부모가 콘솔 프로그램을 부르면 자식마다 새 콘솔이 생김 자식을 띄우는 코드
자식 파이썬이 다시 ffmpeg 호출 손자도 새 콘솔을 만듦 자식을 python.exe 와 숨김 옵션으로

pythonw 가 숨겨 주는 것은 자기 창뿐입니다. 자식 프로세스는 따로 창을 받습니다. 같은 일을 하던 노드 프로그램은 windowsHide: true 를 붙여 두어서 창이 뜨지 않았습니다.

그렇다고 스케줄러에 pythonw 를 등록하는 것도 함정입니다. pythonw 에서는 sys.stdout 이 None 이라 스크립트에 print() 가 있으면 죽습니다.

등록 방식과 자식 호출을 각각 고친다

1. 스케줄러에는 VBS 래퍼로 등록

스케줄러에는 wscript.exe 로 VBS 파일을 등록하고, VBS 안에서 창 숨김 옵션 0 으로 python.exe 를 부릅니다. 콘솔은 할당되지만 숨겨지므로 print 도 정상으로 동작합니다.

' run_hidden.vbs (UTF-16LE 로 저장)
Set sh = CreateObject("WScript.Shell")
sh.Run "cmd /c C:\Python\python.exe C:\jobs\autosave.py >> C:\jobs\autosave.log 2>&1", 0, False

화면 출력만 하는 스크립트는 위처럼 cmd /c 로 감싸 로그 파일에 남깁니다. VBS 파일은 한글 경로가 깨지지 않게 UTF-16LE 로 저장합니다. 등록은 아래처럼 합니다.

$a = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "C:\jobs\run_hidden.vbs"
$t = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 15)
Register-ScheduledTask -TaskName "AutoSave" -Action $a -Trigger $t

2. 창 없는 부모가 부르는 자식은 숨김 옵션으로

파이썬에서는 creationflags=0x08000000(CREATE_NO_WINDOW)을 줍니다. 한곳에 모아 두면 빠뜨리지 않습니다.

import subprocess
CREATE_NO_WINDOW = 0x08000000

def popen_nowin(args, **kw):
    return subprocess.Popen(args, creationflags=CREATE_NO_WINDOW, **kw)

popen_nowin(["ssh", "-o", "BatchMode=yes", "[email protected]", "uptime"])

자식 파이썬이 다시 ffmpeg 를 부르는 구조라면 자식을 pythonw 가 아니라 python.exe 와 CREATE_NO_WINDOW 로 띄웁니다. 그래야 손자도 숨은 콘솔을 물려받습니다. 노드라면 child_process 옵션에 windowsHide: true 를 붙입니다.

고쳐졌는지 확인하는 법

Start-ScheduledTask -TaskName "AutoSave"
(Get-ScheduledTaskInfo -TaskName "AutoSave").LastTaskResult

만든 뒤에는 한 번 직접 돌려서 결과 코드가 0 인지, 그리고 그동안 화면에 창이 하나도 안 뜨는지 눈으로 봅니다. 자식 프로세스 쪽은 ssh 나 ffmpeg 가 실제로 불리는 주기를 한 번 지켜봐야 확인됩니다.

참고로 편집기나 도구가 띄우는 훅처럼 이미 다른 프로세스의 자식으로 도는 것은 창을 띄우지 않았습니다. 창이 계속 뜬다면 작업 스케줄러 쪽 등록이나 창 없는 부모의 자식 호출부터 보면 됩니다.

테스트한 환경

항목 내용
운영체제 윈도우 PC
실행 방식 작업 스케줄러, pythonw 로 도는 백그라운드 파이썬, 노드 프로그램
창을 띄운 자식 ssh, ffmpeg, python.exe -m 으로 부른 모듈

함께 보면 좋은 글

이 글의 내용은 2026년 10월 5일에 마지막으로 확인했습니다. 틀린 곳을 발견하시면 연락처로 알려 주세요.