我想在Delphi中编写一个程序,它删除自己并复制另一个版本而不是它,另一个.exe文件来自另一个文件夹。我在测试项目上尝试了这个代码,但它确实有效。但是当我为我的大项目复制它时,它无法删除自己。 大项目的大小是68 413 KB(如果它与问题有任何关联..)
有什么建议吗?
AppName:= ExtractFileName(ParamStr(0));
myBatFile:= 'copy.bat';
AssignFile(myText, myBatFile);
Rewrite(myText);
Writeln(myText, 'del ' + AppName);
Writeln(myText, 'copy whateverPath\myProgram.exe whateverPath\destination\myProgram.exe');
Writeln(myText, 'del ' + myBatFile);
CloseFile(myText);
ShellExecute(Application.Handle,'open','copy.bat',nil,nil,SW_ShowNormal);
Halt;
答案 0 :(得分:3)
当您调用create view DemoView as select name=SUBSTRING(name,1,50)+'...' from tableName;
时,会创建一个新的命令解释程序进程,然后进程B.然后ShellExecute
返回,您的进程A继续执行。
你现在拥有所谓的种族。这两个过程都处于竞争中。进程B正在尝试删除用于创建进程A的可删除文件。因此进程A需要在进程B完成之前终止,以便成功完成。但是你没有做任何事情来实现这一目标。
实现这一目标的正确方法如下:
答案 1 :(得分:3)
您可以使用http://www.catch22.net/tuts/self-deleting-executables中的自删除批处理文件方法在退出后删除可执行文件,然后复制新的可执行文件并删除批处理文件。
procedure UpdateMeAfterClose(const NewFilename: string);
var
batch: TStrings;
appName, newApp, batchName: string;
begin
batch := TStringList.Create;
try
//** Get batch filename in temp
batchName := TPath.GetTempPath;
if GetTempFileName(PChar(batchName), 'bat', 0, PChar(batchName)) = 0 then
RaiseLastOSError;
batchName := ChangeFileExt(batchName, '.bat');
newApp := AnsiQuotedStr(NewFilename, '"');
appName := AnsiQuotedStr(Application.ExeName, '"');
batch.Add(':Repeat');
batch.Add('del ' + appName); // try to delete current exe
batch.Add('if exist ' + appName + ' goto Repeat');
batch.Add('copy ' + newApp + ' ' + appName); // copy new exe
batch.Add(appName); // start new app
batch.Add('del "' + batchName + '"'); // delete this batch file
batch.SaveToFile(batchName);
finally
batch.Free;
end;
ShellExecute(0, 'open', PChar(batchName), nil, nil, SW_HIDE);
end;
答案 2 :(得分:3)
您无法删除正在运行的进程的文件。但你可以重命名它! 所以你可以: