- install_autostart.py를 진짜 설치기로 재작성: 최신 companion.py를 서버에서 직접 받아 %LOCALAPPDATA%\PythonCompanion에 설치(다운로드 폴더 정리돼도 안전), 재실행 시 최신 버전으로 갱신. 네트워크 실패 시 옆 폴더의 companion.py로 폴백 - claude-app/code 에디터의 companion 상태 옆에 companion.py(⬇)/ install_autostart.py(⚙) 다운로드 링크 추가 - /companion.py, /install_autostart.py를 인증 미들웨어에서 예외 처리 — 독립 실행되는 install_autostart.py는 로그인 세션 쿠키가 없어, 예외가 없으면 로그인 페이지 HTML을 companion.py인 척 받아버림 - 코드 에디터 ☁️서버 터미널 탭의 기본 작업 폴더를 ~/homeclaw로 고정 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
93 lines
3.3 KiB
Python
93 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Python Companion 설치 + Windows 자동시작 등록
|
|
실행: python install_autostart.py
|
|
|
|
companion.py를 고정 위치(%LOCALAPPDATA%\\PythonCompanion)에 내려받아 설치하고
|
|
Windows 로그인 시 자동 실행되도록 등록합니다. 다운로드 폴더처럼 정리될 수
|
|
있는 임시 위치가 아니라 별도 설치 폴더를 쓰므로, 원본 다운로드 파일을
|
|
지워도 계속 동작합니다. 다시 실행하면 최신 버전으로 재설치/업데이트됩니다.
|
|
"""
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import urllib.request
|
|
|
|
COMPANION_URL = 'https://ai.applecherry.net/companion.py'
|
|
|
|
|
|
def main():
|
|
if sys.platform != 'win32':
|
|
print('이 스크립트는 Windows 전용입니다.')
|
|
input()
|
|
return
|
|
|
|
install_dir = os.path.join(os.environ['LOCALAPPDATA'], 'PythonCompanion')
|
|
os.makedirs(install_dir, exist_ok=True)
|
|
companion_path = os.path.join(install_dir, 'companion.py')
|
|
|
|
startup_dir = os.path.join(
|
|
os.environ['APPDATA'],
|
|
'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup'
|
|
)
|
|
vbs_path = os.path.join(startup_dir, 'python_companion.vbs')
|
|
|
|
# pythonw.exe 경로 (콘솔 창 없이 실행)
|
|
pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
|
|
if not os.path.exists(pythonw):
|
|
pythonw = sys.executable # fallback
|
|
|
|
already = os.path.exists(vbs_path)
|
|
|
|
print('=' * 50)
|
|
print(f'Python Companion {"업데이트" if already else "설치"}')
|
|
print('=' * 50)
|
|
print(f'설치 위치 : {companion_path}')
|
|
print(f'pythonw : {pythonw}')
|
|
print(f'시작프로그램 : {vbs_path}')
|
|
print()
|
|
|
|
print('companion.py 최신 버전 다운로드 중...')
|
|
try:
|
|
urllib.request.urlretrieve(COMPANION_URL, companion_path)
|
|
print(f'[완료] {companion_path}')
|
|
except Exception as e:
|
|
# 네트워크 문제로 다운로드에 실패하면, 이 스크립트와 같은 폴더에 있는
|
|
# companion.py가 있는지 확인해서 그걸로 대신 설치한다.
|
|
local_fallback = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'companion.py')
|
|
if os.path.exists(local_fallback):
|
|
print(f'[경고] 다운로드 실패({e}) — 같은 폴더의 companion.py를 대신 사용합니다.')
|
|
shutil.copy(local_fallback, companion_path)
|
|
else:
|
|
print(f'[오류] companion.py를 받을 수 없습니다: {e}')
|
|
input('\n[Enter] 종료...')
|
|
return
|
|
print()
|
|
|
|
vbs_content = (
|
|
'Set WS = CreateObject("Wscript.Shell")\n'
|
|
f'WS.Run "{pythonw} ""{companion_path}""", 0, False\n'
|
|
)
|
|
with open(vbs_path, 'w', encoding='utf-8') as f:
|
|
f.write(vbs_content)
|
|
|
|
print(f'[{"업데이트" if already else "완료"}] 자동시작 등록됨')
|
|
print('다음 Windows 로그인 시 자동으로 실행됩니다.')
|
|
print()
|
|
print('제거하려면 아래 둘 다 삭제하세요:')
|
|
print(f' {vbs_path}')
|
|
print(f' {install_dir} (설치 폴더 전체)')
|
|
print()
|
|
|
|
choice = input('지금 바로 실행하시겠습니까? (y/n): ').strip().lower()
|
|
if choice == 'y':
|
|
import subprocess
|
|
subprocess.Popen([pythonw, companion_path])
|
|
print('실행됨 (트레이 아이콘 확인)')
|
|
|
|
input('\n[Enter] 종료...')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|