我正在尝试实现自动更新功能,因此我以编程方式下载update_myprog.exe(使用Inno Setup创建),然后我想立即关闭程序并运行update_myprog.exe 。目前我使用subprocess.Popen()来运行它,但由于某些原因,当update_myprog.exe运行时,我收到一个错误:"安装程序无法自动关闭所有应用程序。建议您在继续之前使用需要由安装程序更新的文件关闭所有应用程序。"。当我自己运行update_myprog.exe时(不是通过原始程序),它运行正常。
所以,我想知道,我的Python,Inno Setup或其他什么问题?
以下是我的问题的简化版本,只提取相关代码。
这是我的python代码(autoupdate.py):
import wx
import subprocess
import win32process
import tempfile
class Main(wx.Frame):
def __init__(self,*args,**kwargs):
wx.Frame.__init__(self,*args,**kwargs)
self.SetTitle('MyProg v1')
self.updatebutton=wx.Button(self,label='Update')
self.updatebutton.Bind(wx.EVT_BUTTON,self.update)
def update(self,event):
canupdate=True
if(canupdate):
tempdir=tempfile.mkdtemp()
fname=os.path.join(tempdir,'update_myprog.exe')
proc = subprocess.Popen('"update_myprog.exe" /SP- /silent /noicons /nocancel /password="pw"', creationflags=win32process.DETACHED_PROCESS,shell=True)
self.Destroy()
sys.exit()
app = wx.App(False)
Main(parent=None).Show(True)
app.MainLoop()
然后我用:
编译它pyinstaller "autoupdate.py" --distpath="make\dist" --workpath="make\build"
然后我使用以下Inno安装脚本创建了安装程序(update_myprog.exe):
[Setup]
AppId={{7FBA93BE-7DC4-4114-91DF-DD524A078F63}
AppName=My Program
AppVersion=1
AppPublisher=My Company, Inc.
AppPublisherURL=http://www.example.com/
AppSupportURL=http://www.example.com/
AppUpdatesURL=http://www.example.com/
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
AllowNoIcons=yes
OutputDir=make/Installer
OutputBaseFilename=update_myprog
Password=pw
Compression=lzma
SolidCompression=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "C:\Python27\My Projects\Test Update\make\dist\autoupdate\autoupdate2.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Python27\My Projects\Test Update\make\dist\autoupdate\*"; DestDir: "{app}";
[Icons]
Name: "{group}\My Program"; Filename: "{app}\autoupdate.exe"
Name: "{commondesktop}\My Program"; Filename: "{app}\autoupdate.exe"; Tasks: desktopicon
[Run]
Filename: "{app}\autoupdate.exe"; Description: "{cm:LaunchProgram,My Program}"; Flags: nowait postinstall
然后我运行安装程序(工作正常),并将安装程序复制到它安装到的目录中。然后我运行我的程序,然后单击按钮,它给了我一个错误。为什么呢?
如果其他人可以在他们的计算机上执行上述步骤,它可能会有所帮助,如果他们遇到同样的问题,请告诉我。感谢所有帮助。
旧问题:
所以,我基本上和Spawning a non-child process in python有相同的问题,但对于Windows。
我正在尝试实现自动更新功能,因此我以编程方式下载update_myprog.exe(使用Inno Setup创建),然后我想立即关闭程序并运行update_myprog.exe 。目前我正在使用subprocess.Popen()来运行它,但它似乎仍然是原始程序的子程序,因此无法覆盖原始程序的exe文件来更新它。
os.system是我想要的,还是有其他解决方案?
答案 0 :(得分:0)
如果您想完全分离您可以使用的过程:
from win32process import DETACHED_PROCESS
from subprocess import Popen
Popen(["python","xyz.py"],creationflags=DETACHED_PROCESS,shell=True).pid
<强>更新强>
使用临时目录编译它可能导致它自己的小噩梦,但这是另一个问题,上帝知道wx在这里的表现如何。确保download
实际上正在完成并尝试execfile(filename)
而不是Popen。如果那里没有运气,请尝试以下方法:
from subprocess import Popen, CREATE_NEW_CONSOLE,CREATE_NEW_PROCESS_GROUP
Popen(["python", 'xyz.py'],shell = True | CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE)
如果不这样做,请重新发布问题并让别人看一看。对不起,我无法提供更多帮助。让我知道你最后是如何怀疑它的。
答案 1 :(得分:0)
一年多以前,我使用 Inno Setup 和 PyInstaller 实现了自动更新。
您需要在子流程之前调用 self.destroy()
。这是为了在你调用 Inno 之后,你可以立即退出。您还可以使用 /FORCECLOSEAPPLICATIONS
标志,以便 Inno-Setup 可以在 sys.exit()
速度不够快的情况下关闭您的程序。