Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to erase a running program's executable file?

127 views
Skip to first unread message

Mike M.

unread,
Jan 18, 2002, 2:19:53 PM1/18/02
to
You could put a setup file for the program onto the machine and then set the
runonce registry setting and reboot. The system will come up and run the
setup of your new version. I do this by sending the setup to another
machine using ftp. Of course this only works if you can reboot the machine
in question.

"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


Luc Kumps

unread,
Jan 18, 2002, 2:32:26 PM1/18/02
to

"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;
}


Norman Black

unread,
Jan 18, 2002, 3:27:58 PM1/18/02
to
In your executable write a batch file to disk. In this batch file have
it loop trying to delete the running executable. Execute the batch file
with low priority.

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

Chun Yu

unread,
Jan 18, 2002, 3:30:54 PM1/18/02
to
Dear Mike,
Thank you for your reply. It seems like your solution is
the simplest that I can go for. But I am a little
(uh..acutally quite a bit) shakey on what file should I
edit. From what I understand, I should put the setup file
(I assume Setup.exe from InstallShield would do?) in my
computer and I edit the runonce registry and then all I
have to do is to reboot the machine. But where should I
put my Setup.exe file? Currently I am putting all the
programs that runs automatically at c:\winnt\profiles\All
Users\Start Menu\programs\Startup\. So I assume I have to
finish updating before the process that I am trying to
update starts by itself? Or that runonce registry will do
the magic for me?
Thank you very much,
Chun Yu

Mike M.

unread,
Jan 18, 2002, 5:01:18 PM1/18/02
to
Whatever setup.exe you generated to install your program. You can put it
anywhere. I put it in my ftproot because I ftp it to the machine in
question. The server determines a client needs a new version, ftps the
program to the machine and sends a command (cia socket) to tell the client
to perform the code below.
Code snippet without error checking and such:

#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...

Gary Nebbett

unread,
Jan 19, 2002, 9:45:44 AM1/19/02
to
Hello Luc,

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
}
}

0 new messages