"Chun Yu Kong" <uniq...@hotmail.com> wrote in message
news:a03c01c1a044$8af33720$37ef2ecf@TKMSFTNGXA13...
> Is there a way to erase the executable file of a runing
> program? I need to do this in my project because I have
> to update the system whlie the program is running. I am
> using installshield for all the updates until now. If
> anyone knows how to do this, pleazzzzze tell me how.
> Thank you in advance.
> Chun Yu
The little code marvel below was posted by Gary Nebbet a year ago. It should
work on NT, 2000 and XP. It is a *complete* program which deletes its own
.exe file.
Of course, there's an approach that works on any OS:
1. From within the program that has to be deleted, spawn (in the background)
a 'deleter' program, passing it the name of the file(s) to delete in a
command line parameter
2. From within the 'deleter' program, try to delete the file(s) every N
seconds. Exit upon success.
Luc
#include <windows.h>
int main(int argc, char *argv[])
{
HMODULE module = GetModuleHandle(0);
CHAR buf[MAX_PATH];
GetModuleFileName(module, buf, sizeof buf);
CloseHandle(HANDLE(4));
__asm {
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push DeleteFile
push UnmapViewOfFile
ret
}
return 0;
}
When the delete the of executable file succeeds then the batch file can
delete itself (del %0).
This method work on Win9x and well as all NT incarnations.
--
Norman Black
Stony Brook Software
nospam => stonybrk
#define SOFTWARE_UPDATE_PROGRAM ((_TCHAR
*)("C:\\INETPUB\\FTPROOT\\SETUP.EXE -Q"))
When the running program gets the message to install a new version:
// Open and create registry key to run application on startup
status = ::RegOpenKey(HKEY_LOCAL_MACHINE,
_T("SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUNONCE"), &hKey);
status = ::RegSetValueEx(hKey, "Setup", NULL, REG_SZ, (_TUCHAR
*)SOFTWARE_UPDATE_PROGRAM,
(_tcslen(SOFTWARE_UPDATE_PROGRAM) + 1) * sizeof(TCHAR));
HANDLE hToken; // pointer handle to process token
TOKEN_PRIVILEGES tkp; // pointer to token structure
// Get the current process token handle so we can get shutdown
// privilege.
retval = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY, &hToken);
// Get the LUID for shutdown privilege.
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
&tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Get shutdown privilege for this process.
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES) NULL, 0);
// force the system to shutdown NOW
::ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0);
// Disable shutdown privilege.
tkp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES) NULL, 0);
"Chun Yu" <uniq...@hotmail.com> wrote in message
news:bf5e01c1a05f$06d82390$9ae62ecf@tkmsftngxa02...
Unfortunately, this does not work under Windows XP. The
kernel previously kept a handle reference to the section
object for the main image, but under Windows XP this was
changed to a pointer reference (which cannot easily be
released from user mode).
My current best solution is to package the final stage of
a deinstallation in a DLL callable from Rundll32 (i.e. a
DLL that exports function(s) with suitable
signatures). The kernel only keeps a reference to the main
image section object (and not to DLL section objects), so
the DLL can be deleted.
If the DLL was named deinstall.dll, it could be invoked by
the command:
Rundll32 deinstall,Cleanup arg1 arg2 arg3
Gary
#include <windows.h>
#pragma comment(linker, "-export:CleanupA=_CleanupA@16")
extern "C"
void CALLBACK CleanupA(HWND, HINSTANCE, PSTR, int)
{
static MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(&mbi, &mbi, sizeof mbi);
PVOID module = mbi.AllocationBase;
CHAR buf[MAX_PATH];
GetModuleFileName(HMODULE(module), buf, sizeof buf);
__asm {
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push DeleteFile
push FreeLibrary
ret
}
}