import subprocess, os, sys, asyncio BASE = r'C:\Users\whdwo\OneDrive\바탕 화면\stockbot_v3' pid_file = os.path.join(BASE, 'logs', 'bot.pid') # 1-a) PID 파일로 종료 if os.path.exists(pid_file): try: pid = int(open(pid_file).read().strip()) result = subprocess.run(["taskkill", "/PID", str(pid), "/F"], capture_output=True, text=True) print(f"PID 파일 종료: {pid} -> returncode={result.returncode}") except Exception as e: print(f"PID 파일 종료 실패: {e}") os.remove(pid_file) else: print("PID 파일 없음") # 1-b) 잔존 프로세스 스캔 r = subprocess.run( ["powershell", "-Command", "Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like '*app/main.py*' -or $_.CommandLine -like '*app\\\\main.py*' } | Select-Object -ExpandProperty ProcessId"], capture_output=True, text=True ) pids = [p.strip() for p in r.stdout.strip().splitlines() if p.strip().isdigit()] for pid in pids: result = subprocess.run(["taskkill", "/PID", pid, "/F"], capture_output=True, text=True) print(f"잔존 프로세스 종료: {pid} -> returncode={result.returncode}") if not pids: print("실행 중인 봇 없음 — 새로 시작합니다") # 2. 봇 시작 + PID 저장 os.chdir(BASE) log_path = os.path.join(BASE, "logs", "bot_stderr.log") env = os.environ.copy() env["PYTHONUNBUFFERED"] = "1" proc = subprocess.Popen( [sys.executable, "-u", "app/main.py"], creationflags=subprocess.DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP, stdout=open(log_path, "a", encoding="utf-8"), stderr=subprocess.STDOUT, close_fds=True, env=env, ) with open(pid_file, "w") as f: f.write(str(proc.pid)) print(f"봇 시작 완료 PID={proc.pid}") # 3. Discord 알림 sys.path.insert(0, BASE) from app.main import load_env load_env() from app.monitor.notifier import send mode = os.getenv("KIS_MOCK", "true") dry = os.getenv("DRY_RUN", "true") label = "[모의투자]" if mode == "true" else "[실거래]" asyncio.run(send(f"{label} 자동매매 봇 시작 (DRY_RUN={dry})")) print("Discord 알림 전송 완료")