Author: Jonas Bilinkevicius
I would like to run a program that finishes by deleting itself (similar to the DOS
TSR programs). Is this possible?
Answer:
Solve 1:
One technique is to use a batch file. It works on all versions of Windows. An
example:
1 { ... }
2 s := 'SelfDelete.bat';
3 s := ExtractFilePath(ParamStr(0)) + s;
4 assign(f, s);
5 rewrite(f);
6 writeln(f, ':f');
7 writeln(f, 'del "' + ParanStr(0));
8 writeln(f, 'if EXIST "' + ParamStr(0) + '" goto f');
9 writeln(f, 'del "' + s);
10 closefile(f);
11 WinExec(PChar(s), SW_HIDE)
Solve 2:
This simple method uses a Windows Registry entry, which in turn, makes Command.com
to do the job for us, whenever the next Windows restart occurs. Add the following
code to a procedure of your choice:
12 uses
13 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
14 StdCtrls,
15 Registry;
16
17 type
18 TForm1 = class(TForm)
19 Button1: TButton;
20 procedure Button1Click(Sender: TObject);
21 private
22 { Private declarations }
23 public
24 { Public declarations }
25 end;
26
27 var
28 Form1: TForm1;
29
30 implementation
31
32 {$R *.DFM}
33
34 procedure TForm1.Button1Click(Sender: TObject);
35 var
36 APath: array[0..255] of char;
37 begin
38 {Command.com does not support long paths, so convert to short}
39 if GetShortPathName(PChar(ParamStr(0)), APath, SizeOf(APath) - 1) <> 0 then
40 begin
41 {Work with TRegistry}
42 with TRegistry.Create do
43 try
44 {Set Root Key}
45 RootKey := HKEY_LOCAL_MACHINE;
46 {Open Key, creating key if it does not exist}
47 if OpenKey('\Software\Microsoft\Windows\CurrentVersion\RunOnce', True) then
48 begin
49 {Add our String Value to the Key}
50 WriteString('MyApp', 'command.com /c del ' + APath);
51 {Close the Key}
52 CloseKey;
53 end;
54 finally
55 {Free TRegistry}
56 free;
57 end;
58 end;
59 end;
This example makes use of ParamStr(0) to meet the expectations that the title of
this article has elicited: By pointing to the path + filename of the application
that executes this procedure, the program will in fact bring about the removal of
itself. Windows NT/2000 Note: Users running programs that utilize this code, must
have the right to modify the HKEY_LOCAL_MACHINE section of the Windows Registry.
Solve 3:
Try this (not tested under WinXP, but works under Win95, Win98, WinNT 4.0 and
Win2000):
60 procedure DeleteExeAndDir;
61 var
62 hModule: THandle;
63 szModuleName, szDirName: array[0..MAX_PATH] of Char;
64 hKrnl32: THandle;
65 pExitProcess, pDeleteFile, pFreeLibrary, pUnmapViewOfFile, pRemoveDir: pointer;
66 ExitCode: UINT;
67 var
68 r: integer;
69 begin
70 hModule := GetModuleHandle(nil);
71 GetModuleFileName(hModule, szModuleName, sizeof(szModuleName));
72 StrPCopy(szDirName, ExtractFileDir(szModuleName));
73 hKrnl32 := 'kernel32');
74 pExitProcess := GetProcAddress(hKrnl32, 'ExitProcess');
75 pDeleteFile := GetProcAddress(hKrnl32, 'DeleteFileA');
76 pFreeLibrary := GetProcAddress(hKrnl32, 'FreeLibrary');
77 pUnmapViewOfFile := GetProcAddress(hKrnl32, 'UnmapViewOfFile');
78 pRemoveDir := GetProcAddress(hKrnl32, 'RemoveDirectoryA');
79 ExitCode := system.ExitCode;
80 SetCurrentDirectory(pchar(ExtractFileDir(szDirName)));
81 if ($80000000 and GetVersion()) <> 0 then
82 {Win95, 98, Me}
83 asm
84 lea eax, szModuleName
85 lea ecx, szDirName
86 push ExitCode
87 push 0
88 push ecx
89 push pExitProcess
90 push eax
91 push pRemoveDir
92 push hModule
93 push pDeleteFile
94 push pFreeLibrary
95 ret
96 end
97 else
98 begin
99 for r := 1 to 100 do
100 begin
101 CloseHandle(r shl 2);
102 end;
103 {CloseHandle(THANDLE(4));}
104 asm
105 lea eax, szModuleName
106 lea ecx, szDirName
107 push ExitCode
108 push 0
109 push ecx
110 push pExitProcess
111 push eax
112 push pRemoveDir
113 push hModule
114 push pDeleteFile
115 push pUnmapViewOfFile
116 ret
117 end
118 end;
119 end;
Solve 4:
120 program delself;
121
122 uses
123 windows;
124
125 procedure DeleteSelf;
126 var
127 module: HMODULE;
128 buf: array[0..MAX_PATH - 1] of char;
129 p: ULONG;
130 hKrnl32: HMODULE;
131 pExitProcess, pDeleteFile, pFreeLibrary: pointer;
132 begin
133 module := GetModuleHandle(nil);
134 GetModuleFileName(module, buf, sizeof(buf));
135 CloseHandle(THandle(4));
136 p := ULONG(module) + 1;
137 hKrnl32 := GetModuleHandle('kernel32');
138 pExitProcess := GetProcAddress(hKrnl32, 'ExitProcess');
139 pDeleteFile := GetProcAddress(hKrnl32, 'DeleteFileA');
140 pFreeLibrary := GetProcAddress(hKrnl32, 'FreeLibrary');
141 asm
142 lea eax, buf
143 push 0
144 push 0
145 push eax
146 push pExitProcess
147 push p
148 push pDeleteFile
149 push pFreeLibrary
150 ret
151 end;
152 end;
153
154 begin
155 DeleteSelf;
156 end.
|