簡體   English   中英

python 生成 cmd 腳本並在它結束后關閉它

[英]python spawn cmd script and close it after it ends

我編寫了自動更新軟件(使用 pyinstaller 編譯為 exe 的 python)。 一切正常,但有一個問題我無法解決 - 在 cmd window 完成更新后,我無法關閉它。

假設軟件exe名稱是software.exe (這個軟件是單文件exe)。 啟動時,它會檢查更新,如果找到,它將下載為software.bundle ,並將在當前目錄中創建一個臨時腳本software-update.bat 此腳本注冊為在software.exe關閉時調用(使用atexit.register )。
此腳本將刪除software.exe並將software.bundle重命名為sofware.exe ,將啟動software.exe並自行刪除software-update.bat

所以更新正在運行。

問題是,為了刪除 .exe 我需要先完全關閉它,這意味着執行software-update.bat的命令需要與主 running.exe software.exe分開運行。

我只能使用它

os.system(f'start {script_update_name} /b')

(再次 - 此命令正在啟動software-update.bat ,然后software.exe '立即' 退出)

嘗試使用subprocess.run或任何替代方法在嘗試從更新腳本中刪除sofware.exe時導致“訪問被拒絕”(因為software.exe顯然仍在運行)。

所以最后我的問題,解決上述問題之一將解決我的問題:

  1. 是否有一個選項可以可靠地退出由於start...命令而聲明的 cmd window? 在腳本末尾添加exit (或我能找到的任何其他解決方案)不起作用。
  2. 有沒有“開始”的替代品? 知道將bat文件與主exe分開運行,但完成后退出?

如果有幫助,這里是更新腳本software-update.bat

with open(script_update_name, 'w') as f:
    s = dedent(f"""
          @echo off
          echo Updating...
          del {file.__str__()}
          rename {(file.parent / done_download_name).__str__()} {osPath.basename(file.__str__())}
          start {osPath.basename(file.__str__())}
          echo Done
          del {script_update_name}
          """).strip('\n')
    f.write(s)

我知道這聽起來很簡單,但老實說,我現在無法解決它。

任何幫助,將不勝感激!

我可以用@Mofi 的非常有用的評論來解決:

問題是時間問題 - 我需要在啟動 .bat 腳本之前完全終止 .exe 進程,因為 .bat 腳本正在積極嘗試刪除 .exe 文件。 為此,我在我的 python 代碼(即作為.exe 運行)中使用os.getpid() ) 來獲取 .exe 的當前進程 pid,並且 .bat 文件等待此 PID 進程退出,完整的腳本是:

with open(script_update_name, 'w') as f:
s = dedent(f"""
      @echo off
      
      REM wait for process to finish
      :loop
      tasklist | find " {os.getpid()} " >nul
      if not errorlevel 1 (
          timeout /t 1 /nobreak >nul 
          echo waiting for EasySchema to exit...
          goto :loop
      )
      
      echo Updating EasySchema...
      del {file.__str__()}
      rename {(file.parent / done_download_name).__str__()} {osPath.basename(file.__str__())}
      start {osPath.basename(file.__str__())}
      echo Done
      del {script_update_name}
      """).strip('\n')
f.write(s)

運行腳本的部分從 os.system() subprocess.Popen 更改為@Mofi 建議

def run_update_script():
  subprocess.Popen(['cmd', '/C', file.parent / script_update_name])

有了這個,我可以可靠地更新 my.exe 並在結束后關閉終端。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM