从自身终止Python进程并在之后运行代码

问题描述 投票:0回答:1

当在一个脚本中我想使用一个 .pyd 库但通常我想使用同一 .pyd 的另一个版本时,我有这样的用例。

为了实现此目的,我在 python 脚本启动时切换 .pyd 文件,然后 import lib 导入正确的版本。

在 python 脚本的末尾(使用 atexit),我附加了可能会切换库的脚本。问题是,如果 .pyd 被某个进程(当前的 python 实例)使用并且无法卸载(我发现不可能在运行时卸载已加载的 .dll 或 .pyd),则无法更改 .pyd。所以我需要杀死 python.exe 然后运行我的脚本。

当我杀死 python.exe 时,它似乎终止了

os.system

 我一开始就尝试过,但它永远不会运行将执行库切换的 .bat 文件。我正在努力解决这个问题。

长话短说 - 我想终止 python 进程并运行一些代码。

示例代码如下 - 它永远不会将进程 ID 打印到

test_my_case.txt

。如果我删除 
&& timeout 3
 它工作得很好 - 所以我认为问题是 
subprocess.call
 进程被杀死,因为 python 进程被杀死,并且如果在回显之前有任何延迟,它就无法打印。

我尝试过的 -

os.startfile

os.system
subprocess.Popen
subprocess.call

import os import subprocess import atexit # never prints PID to the test_my_case.txt def switch_library(): command = f"taskkill /F /PID {os.getpid()} && timeout 3 && echo {os.getpid()} > test_my_case.txt" subprocess.run(command, shell=True) atexit.register(switch_library) exit()
    
python process system
1个回答
0
投票
嗯,这相当老套,但我找到了一种通过任务计划程序(在 Windows 上)来完成此操作的方法。首先,我尝试使用

[schtasks][1]

 来完成此操作,但当我希望脚本在计划后不久执行时,它不允许设置以秒为单位的启动时间,因此我转向 Powershell 脚本...

import os import sys import tempfile import subprocess import atexit from pathlib import Path @atexit.register def switch_library(): temp_folder = Path(tempfile.gettempdir()) pid = os.getpid() def write_to_file(filepath, string): with open(filepath, "w") as fi: fi.write(string) cmd_script = f"taskkill /F /PID {pid} & timeout 3 & echo {pid} > %~dp0./test_my_case.txt" batch_file = temp_folder / "terminator.bat" write_to_file(batch_file, cmd_script) ps_script = f"""Unregister-ScheduledTask -TaskName "library_switch" -Confirm:$false $taskTrigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds(1) $taskAction = New-ScheduledTaskAction -Execute "{batch_file.as_posix()}" Register-ScheduledTask 'library_switch' -Action $taskAction -Trigger $taskTrigger """ ps_script_file = temp_folder / "terminator.ps1" write_to_file(ps_script_file, ps_script) # requires: Set-ExecutionPolicy RemoteSigned show_ps_output = False stdout = sys.stdout if show_ps_output else subprocess.DEVNULL p = subprocess.Popen(["powershell.exe", ps_script], stdout=stdout) p.communicate()
    
© www.soinside.com 2019 - 2024. All rights reserved.