如何将一个正在运行的文件删除它自己?(100分)

  • 主题发起人 主题发起人 海风
  • 开始时间 开始时间

海风

Unregistered / Unconfirmed
GUEST, unregistred user!
如何将一个正在运行的文件删除它自己?就象uninst.exe一样
 
看看cAkk以前的解答吧,我测试有一些问题,也不知道哪里不对?<br>&nbsp; &nbsp; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>&nbsp; &nbsp; var <br>&nbsp; &nbsp; &nbsp; f:textfile;<br>&nbsp; &nbsp; begin &nbsp;<br>&nbsp; &nbsp; &nbsp; assignfile(f,'./delself.bat');<br>&nbsp; &nbsp; &nbsp; rewrite(f);<br>&nbsp; &nbsp; &nbsp; writeln(f,'@echo off');<br>&nbsp; &nbsp; &nbsp; writeln(f,':loop');<br>&nbsp; &nbsp; &nbsp; writeln(f,'del "'+application.ExeName+'"');<br>&nbsp; &nbsp; &nbsp; writeln(f,'if exists "'+application.exename+'" goto loop');<br>&nbsp; &nbsp; &nbsp; writeln(f,'del ./delself.bat');<br>&nbsp; &nbsp; &nbsp; closefile(f);<br>&nbsp; &nbsp; &nbsp; winexec(pchar('./deself.bat'), SW_HIDE);<br>&nbsp; &nbsp; &nbsp; close;<br>&nbsp; &nbsp; end;<br>
 
Application.ExeName是一个带路径的文件名,如果这个路径或者文件名不符合DOS的命名<br>规则,在WIN 9X下就会报告错误,最好在程序里加上处理的代码,把规范的文件名或者目<br>录名改成DOS的83法则。
 
用批处理
 
有个关键啊,如果这个批处理要删除WINDOWS目录的文件要加东西的。
 
以下代码可以实现删除自己的功能,已经测试过:<br>procedure TForm1.Button1Click(Sender: TObject);<br>var <br>&nbsp; f: Textfile; <br>begin <br>&nbsp; assignfile(f,changefileext(paramstr(0),'.bat')); <br>&nbsp; rewrite(f); <br>&nbsp; writeln(f,':1');<br>&nbsp; writeln(f,format('Erase "%s"',[paramstr(0)])); <br>&nbsp; writeln(f,format('If exist "%s" Goto 1',[paramstr(0)])); <br>&nbsp; writeln(f,format('Erase "%s"',[changefileext(paramstr(0),'.bat')])); <br>&nbsp; closefile(f); <br>&nbsp; winexec(PChar(changefileext(paramstr(0),'.bat')),sw_hide); <br>&nbsp; halt;<br>end;
 
用api函数删除行不行?
 
API!?<br>想知道。
 
事呀,用api函数行不行?
 
&nbsp;用api肯定不行,只能用Dos的方式删除。Windows是不允许删除正在它的环境<br>下运行的东西的
 
以下代码用win api函数将自己删除<br>vc++ 6控制台模式编译测试成功<br>#include &lt;Windows.h&gt;<br><br>int main(int argc, char *argv[]) <br>{ <br>&nbsp; &nbsp; HMODULE module = GetModuleHandle(0);<br>&nbsp; &nbsp; CHAR buf[MAX_PATH];<br>&nbsp; &nbsp; GetModuleFileName(module, buf, sizeof(buf));<br>&nbsp; &nbsp; MessageBox(0,"Del Me","Test",MB_OK);<br>&nbsp; &nbsp; CloseHandle((HANDLE)4);<br> __asm {<br>&nbsp; &nbsp; &nbsp; &nbsp; lea &nbsp; &nbsp;eax, buf<br>&nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;0<br>&nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;0<br>&nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;eax<br>&nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;ExitProcess<br>&nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;module<br>&nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;DeleteFile<br>&nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;UnmapViewOfFile<br>&nbsp; &nbsp; &nbsp; &nbsp; ret<br>&nbsp; &nbsp; }<br>&nbsp; &nbsp; return 0; <br>}
 
call test.bat.<br>// test.bat<br>del test.exe // to delete the file test<br>del %
 
unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure DeleteMe;<br>var<br>&nbsp; BatchFile: TextFile;<br>&nbsp; BatchFileName: string;<br>&nbsp; ProcessInfo: TProcessInformation;<br>&nbsp; StartUpInfo: TStartupInfo;<br>begin<br>&nbsp; BatchFileName := ExtractFilePath(ParamStr(0)) + '_deleteme.bat';<br><br>&nbsp; AssignFile(BatchFile, BatchFileName);<br>&nbsp; Rewrite(BatchFile);<br><br>&nbsp; Writeln(BatchFile, ':try');<br>&nbsp; Writeln(BatchFile, 'del "' + ParamStr(0) + '"');<br>&nbsp; Writeln(BatchFile,<br>&nbsp; &nbsp; 'if exist "' + ParamStr(0) + '"' + ' goto try');<br>&nbsp; Writeln(BatchFile, 'del %0');<br>&nbsp; CloseFile(BatchFile);<br><br>&nbsp; FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);<br>&nbsp; StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;<br>&nbsp; StartUpInfo.wShowWindow := SW_HIDE;<br><br>&nbsp; if CreateProcess(nil, PChar(BatchFileName), nil, nil,<br>&nbsp; &nbsp; False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo,<br>&nbsp; &nbsp; ProcessInfo) then<br>&nbsp; begin<br>&nbsp; &nbsp; CloseHandle(ProcessInfo.hThread);<br>&nbsp; &nbsp; CloseHandle(ProcessInfo.hProcess);<br>&nbsp; end;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; DeleteMe;<br>&nbsp; close;<br>end;<br><br>end.
 
procedure DeleteMe; <br>var <br>&nbsp; BatchFile: TextFile; <br>&nbsp; BatchFileName: string; <br>&nbsp; ProcessInfo: TProcessInformation; <br>&nbsp; StartUpInfo: TStartupInfo; <br>begin <br>&nbsp; { create a batchfile in the applications directory } <br>&nbsp; BatchFileName := ExtractFilePath(ParamStr(0)) + '$$336699.bat'; <br>&nbsp; { open and write the file } <br>&nbsp; AssignFile(BatchFile, BatchFileName); <br>&nbsp; Rewrite(BatchFile); <br>&nbsp; Writeln(BatchFile, ':try'); <br>&nbsp; Writeln(BatchFile, 'del "' + ParamStr(0) + '"'); <br>&nbsp; Writeln(BatchFile, &nbsp;'if exist "' + ParamStr(0) + '"' + ' goto try'); <br>&nbsp; Writeln(BatchFile, 'del "' + BatchFileName + '"'); <br>&nbsp; CloseFile(BatchFile); <br>&nbsp; FillChar(StartUpInfo, SizeOf(StartUpInfo), $00); <br>&nbsp; StartUpInfo.dwFlags := STARTF_USESHOWWINDOW; <br>&nbsp; StartUpInfo.wShowWindow := SW_HIDE; <br>&nbsp; if CreateProcess(nil, PChar(BatchFileName), nil, nil, <br>&nbsp; &nbsp; &nbsp;False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo, <br>&nbsp; &nbsp; &nbsp;ProcessInfo) then <br>&nbsp; begin <br>&nbsp; &nbsp; CloseHandle(ProcessInfo.hThread); <br>&nbsp; &nbsp; CloseHandle(ProcessInfo.hProcess); <br>&nbsp; end; <br>end;<br>(以上代码在D5下成功使用。)<br>
 
问题结束
 
多人接受答案了。
 
后退
顶部