关于程序升级的问题,程序运行时候不能复制自身 ( 积分: 50 )

  • 主题发起人 主题发起人 xgwzw
  • 开始时间 开始时间
X

xgwzw

Unregistered / Unconfirmed
GUEST, unregistred user!
我的程序为A.exe 在下载新版本的时候我命名为B。exe,下载的代码如下,可是每次都是弹出 ShowMessage('start A.exe Error!');这个对话框,为什么程序不能自动复制呢?

注:B。exe是新版本的A。exe
if LowerCase(ExtractFileName(ParamStr(0)))='A.exe' then
begin
Application.Terminate;
WinExec(PChar(ExtractFilePath(ParamStr(0))+'B.exe'),SW_HIDE);
end
else begin
//ShowMessage('B');
if not CopyFile(PChar(ParamStr(0)),PChar(ExtractFilePath(ParamStr(0))+'A.exe'),False) then
ShowMessage('start A.exe Error!');
Application.Terminate;
WinExec(PChar(ExtractFilePath(ParamStr(0))+'A.exe'),SW_SHOW);

end;
 
建projecta和projectb分别加入unita和unitb编译再看调用效果
unit unita;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ProcessInfo: TProcessInformation;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
StartupInfo: TStartUpInfo;

begin
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_HIDE;
CreateProcess(nil, PChar('b.exe'), nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo);

end;

procedure TForm1.Button2Click(Sender: TObject);
var
H: THandle;
P: DWORD;

begin
H := FindWindow(nil, 'b');
if H <> 0 then
begin
GetWindowThreadProcessId(H, @P);
if P <> 0 then
if TerminateProcess(OpenProcess(PROCESS_TERMINATE, False, P), $FFFFFFFF) then
showmessage('terminated B')
else
showmessage('can not terminate B');

end;
end;

end.


unit unitb;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ProcessInfo: TProcessInformation;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
StartupInfo: TStartUpInfo;

begin
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_HIDE;
CreateProcess(nil, PChar('a.exe'), nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo);

end;

procedure TForm1.Button2Click(Sender: TObject);
var
H: THandle;
P: DWORD;
begin
H := FindWindow(nil, 'a');
if H <> 0 then
begin
GetWindowThreadProcessId(H, @P);
if P <> 0 then
if TerminateProcess(OpenProcess(PROCESS_TERMINATE, False, P), $FFFFFFFF) then
showmessage('terminated A')
else
showmessage('can not terminate A');
end;
end;

end.
 
to newsmile
我的想法是用一个程序便于维护,用2个程序的话,就比较好实现了!
 
请您看下我的代码,才几行,我想讨论一下这种方案为什么不可以!怎么改进!谢谢!
 
我这里的a和b不就相当于您的“B。exe是新版本的A。exe”吗我自己就是这样更新的
 
做更新时,要适当延时,让A程序完全退出

以下是我以前写的部份。。。可参照使用

Function EnumWindowsProc(AHWnd: Hwnd; LPARAM: LPARAM): Boolean; Stdcall;
Var
WndCaption: Array[0..256] Of char;
Str: String;
Begin
GetWindowText(AHWnd, @WndCaption, 256);
Str := StrPas(WndCaption);
If (Str <> '') And (IntToStr(AHWnd) = ParamStr(2)) Then
TStringList(LPARAM).Add(StrPas(WndCaption));
Result := true;
End;

Procedure AppUpdate; Stdcall;
Label
_Retry;
Var
Hwd, H: THandle;
MS: TStrings;
i, RunMode: Integer;
Pid: Dword;
S: String;
Begin
//检测参数是否正确方可运行,此函数不对外公开
//然后初始化
//ShowMessage(ParamStr(4));

If Not FileExists(ParamStr(4)) Then {检测主程序是否存在}
Paths[0] := ExtractFilePath(GetModuleFileName) {取本DLL所在目录}
Else Paths[0] := ExtractFilePath(ParamStr(4));

Try
RunMode := StrToInt(ParamStr(3)); {运行模式}
Hwd := StrToInt(ParamStr(2)); {检测主程序句柄是否正确}
Except
Exit;
End;
Application.Handle := Hwd;

{延时以适应主程序完全退出}
i := 999999;
While i <> 0 Do
Begin
Dec(i);
Application.ProcessMessages;
End;

_Retry:
MS := TStringList.Create;
EnumWindows(@EnumWindowsProc, LPARAM(MS));
i := MS.Count;
If i > 0 Then S := Replace(MS.Text, #13#10, '');
FreeAndNil(MS);
If i > 0 Then
Begin
i := MsgBoxEx(S + #13#10 + ParamStr(4) + #13#10#13#10 + '还在运行', '提示', mtInformation, [mbCancel, mbAbort, mbRetry, mbIgnore], true, clBlack, 0, '', poScreenCenter, -1, -1);
If i = mrCancel Then {取消}
Exit
Else If i = mrIgnore Then {忽略}
MessageBox(Application.Handle, PChar('忽略 ' + S + ' 运行,可能会造成更新失败!'), '警告', MB_ICONWARNING)
Else If i = mrRetry Then {重试}
Goto _Retry
Else If i = mrAbort Then {终止}
Begin
GetWindowThreadProcessId(StrToInt(ParamStr(2)), Pid);
H := OpenProcess(PROCESS_ALL_ACCESS, False, Pid);
If H <> 0 Then
Begin
If Not TerminateProcess(H, $FFFFFFFF) Then Exit;
CloseHandle(H);
End;
End;
End;
end;
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
597
import
I
后退
顶部