我做了一个自动更新的程序:
原理是采用主程序和副程序:
    主程序一打开自动上网查找是否有更新文件,有则自动下载到一个临时目录,下载完后,则结束主进程,并调用副程序。副程序一打开则自动复制临时目录内文件到主程序目录,覆盖后并重新启动主程序,再结束自身进程。现在就问题是:主程序调用副程序后还没有关闭自己,还挂着自己在内存,使得副程序无法执行覆盖操作。求高手指点下:
   主程序的调用那段代码的应该怎样写?才能让主程序完全关闭,同时能启去副程序去执行覆盖操作?
代码:
主程序:
procedure TSS002_WebUpdate.BtnUpdateClick(Sender: TObject);
begin
//...检查更新,并下载
//主程序和副程序在同一目录 
   ...
  application.Terminate;
  ShellExecute(0,pchar('OPEN'),Pchar('副程序'), nil, nil, SW_SHOWNORMAL);  
end;副程序:
procedure TFrm_Main.FormShow(Sender: TObject);
begin
 //利用  ShFileOperation(v_SHFOS) 进行复制目录
 //复制完后启动主程序
 shellexecute(0, 'open', pchar('主程序'), nil, nil, sw_shownormal) ; 
 close;
end;

解决方案 »

  1.   

    主程序, 升级程序
    下载放到升级程序, 下载完,然后MoveFileEx, 将俩程序对换,然后主程序退出,启动主程序,就完成升级了 
      

  2.   

    movefileex只能做到重启后替换,最好的办法是升级程序下载到一个临时目录,然后结束主程序进程,复制进行文件替换,然后重新启动进程
      

  3.   

    谢谢倒两位老大。
    我没未用过movefileex,不过查了一下说明,貌似是将整个目录移动过去。这样做会有一个问题,原目录下不需要更新的文件同样会一命呜呼,不可取啊。例如自定义的INI文件gyk120说的方法和我的一样,只是我不知道,怎样完全结束主程序,并能启动副程序?因为我上面写的代码有问题,主程序还没有释放,所以副程序进行覆盖时,系统提示主程序正在被使用的错误,若有解决方法请解救下。
      

  4.   

    movefileex 参数是文件名 不是目录
      

  5.   

    dinoalex 说的应该可行!只是若不能上网时(或不需要更新时),在每次启动时都要先检测完再启动主程序,这样就需要用户花一些冤枉时间来等待,不太人性!!
    movefileex 这个不太会用,若要重启电脑就太大工程了。如下大富翁的某个例子:都是要启电脑的:
    MoveFileEx('C:\aa.exe, nil, MOVEFILE_REPLACE_EXISTING or MOVEFILE_DELAY_UNTIL_REBOOT)
      

  6.   

    即配置档里:update=1.0.2
    curver=1.0.2就不用更新,调用的很快就退出执行,启动主程序启动后,有线程来进行连网看是否有更新,当有时,下载完后就再配置,就成update=1.0.3
    curver=1.0.2...updatedir= 20100601
    ...一不同,下次启动就更新呗
      

  7.   

    我咋记得这个问题讨论过呢……我一直采用的方式跟大家分享下,首先说明我的程序启动会创建一个互斥变量。这里只说更新本身。1、下载新的程序到update目录;2、带参数(当前程序的句柄和路径)执行新的程序,若新程序发现互斥变量已经存在,且有特定参数,则将该参数转化为句柄,并等待该句柄的结束;3、执行了新的程序后,原程序执行关闭操作;4、新程序等到原程序关闭后,将自身拷贝至原程序路径下。5、至于自身是否需要删除,自己考虑。
      

  8.   

    这个问题,我记着以前测试过:1、运行的EXE 主程序,如果要替换这个主程序EXE,先把主程序改名字;运行的过程中是可以修改名字的;2、然后下载新的主程序,主程序升级完,关闭旧的主程序,新程序启动时检测是否有 旧版的,检测到删除即可
      

  9.   

    movefileex是重启计算机替换,不是重启程序
    简单一点就分两个文件
    你可以用TerminateProcess结束主程序进程,然后MoveFile直接替换
      

  10.   

    我的做法:服务器上有一个ini:
    最低可用版本=3.01
    最新版本=5.12程序xxx.exe每次运行先下载这个ini
    如果自己低于3.01的,则必须升级
    如果自己低于5.12的,则仅仅提示是否升级下载新版本,是一个独立的au.exe,接受程序xxx.exe的命令行参数来调用,程序xxx.exe自己随即退出
    au.exe去下载xxx.5.12,下载成功等n秒钟(也是命令行指定的),再把把xxx.exe改名为xxx.5.10(也是命令行指定的),把xxx.5.12改为xxx.exe
      

  11.   

    1、主程序检测到需要更新,则启动更新程序,关闭自身
    2、更新程序启动后下载更新,用定时器反复检查主程序是否已退出(可通过Windows的“互斥体对象(mutex object)”,搜索OpenMutex、ReleaseMutex、WaitForSingleObject)
    3、确定主程序关闭后,将主程序改名备份,再将下载后的文件放改为主程序名
      

  12.   

    ShellExecute会等待副程序执行完毕后再关闭主程序,
    用CreateProcess调用副程序就好了