作者:phpxiaofei | 来源:互联网 | 2023-06-03 19:36
最近我在程序中添加一个卸载功能。要求在把所有的文件删除后程序能自我删除。。。在网上查到了一些资料,比如把自我删除代码写入DLL,然后作为程序的资源。。。但由于我不懂汇编,只能照搬,结果死得很惨
最近我在程序中添加一个卸载功能。要求在把所有的文件删除后程序能自我删除。。。
在网上查到了一些资料,比如把自我删除代码写入DLL,然后作为程序的资源。。。
但由于我不懂汇编,只能照搬,结果死得很惨。。。
各位肯定有做过这方面经验的吧?能不能提示一下
要能给个可以在98以上系统都能使用的的源码(我猜源码应该不长),兄弟愿意再加100分
谢谢啦
25 个解决方案
我也没把握到底到哪好
那麻烦斑竹移到基础类去,谢谢
还有我的这个程序只能运行一个实例
一般使用到汇编!需要重新启动
还有我的这个程序只能运行一个实例
使用临界区互斥变量
还有我的这个程序只能运行一个实例
-----------------------------------
我的意思是说,由于我的程序只能运行一次
所以把这个程序拷到临时文件夹,再启动一个实例是行不通的
但如果实在没招,只能先这样
汇编,不会啊。重不重启倒不重要
程序自己删除自己?
这不可能吧
--------------------------------
确实,如果程序还在运行是绝对不可能删除的
除非修改系统底层
但能让程序结速后变着法删除。。。
__asm
{
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push DeleteFile
push UnmapViewOfFile
ret
}
漏了点
char buf[MAX_PATH];
HMODULE module;
module = GetModuleHandle(0);
GetModuleFileName(module, buf, MAX_PATH);
CloseHandle((HANDLE)4);
__asm
{
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push 0//DeleteFile
push UnmapViewOfFile
ret
}
晕,push 0//DeleteFile应该是push DeleteFile
个破csdn不允许编辑帖子,强烈抗议!
我可以很负责任的告诉你,必选借助MOVEFILEEX()将文件登记,并且重启,才能删除,否则执行过程中自身直接删除自身是不可实现的。
BOOL SelfDelete()
{
SHELLEXECUTEINFO sei;
TCHAR szModule [MAX_PATH],
szComspec[MAX_PATH],
szParams [MAX_PATH]; // get file path names:
if((GetModuleFileName(0,szModule,MAX_PATH)!=0) &&
(GetShortPathName(szModule,szModule,MAX_PATH)!=0) &&
(GetEnvironmentVariable(_T("COMSPEC"),szComspec,MAX_PATH)!=0))
{
// set command shell parameters
lstrcpy(szParams,_T("/c del "));
lstrcat(szParams, szModule);
lstrcat(szParams, _T(" > nul")); // set struct members
sei.cbSize = sizeof(sei);
sei.hwnd = 0;
sei.lpVerb = _T("Open");
sei.lpFile = szComspec;
sei.lpParameters = szParams;
sei.lpDirectory = 0;
sei.nShow = SW_HIDE;
sei.fMask = SEE_MASK_NOCLOSEPROCESS; // increase resource allocation to program
SetPriorityClass(GetCurrentProcess(),
REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_TIME_CRITICAL);
// invoke command shell
if(ShellExecuteEx(&sei))
{
// suppress command shell process until program exits
SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS);
SetProcessPriorityBoost(sei.hProcess,TRUE);
// notify explorer shell of deletion
SHChangeNotify(SHCNE_DELETE,SHCNF_PATH,szModule,0);
return TRUE;
}
else // if error, normalize allocation
{
SetPriorityClass(GetCurrentProcess(),
NORMAL_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_NORMAL);
}
}
return FALSE;
}
加上上面的代码后,重载DestroyWindow()函数,在里面添加一行:
SelfDelete();
再看看你的.exe文件还在不在^_^
LookSail给出的代码,我试过,确实可以删除,但好像只能在9X,NT,2000下有效
Snow_Ice11111(雪上加冰) 的代码我试试,看能不能在9X下运行(我的感觉好像不妙,呵呵)
bjskyhorse:我只是想在退出的时候删除,但那时还是在运行。。。你的方法,我没接触过啊:(~~~
LookSail:有没有可以通过判断平台(9X,NT,2000,XP)来进行相应操作的代码,我现在差XP下的。谢谢啦。。。。
DWORD dwVersion;
dwVersion=::GetVersion();
if (dwVersion >= 0x80000000) //Win9x
{
AfxMessageBox(_T("9X"));
return;
}
else
{
AfxMessageBox(_T("2K or NT")); //Win2K/WinXP
}
谢谢rageliu!
是这样判断平台。
可能我的意思没说清楚
我的意思是说,我如何根据不同的平台(9X,NT,2000,XP)来执行LookSail给出的代码?
比如,我已判断出是9X,那我得用FreeLibrary(),如果是NT,2000我用UnmapViewOfFile来取消映射等,那在XP下呢?
LookSail给出的代码,只能在98下吧?
^_^
Snow_Ice11111的方法不错。只是不能有100%的把握。谢谢
我在其他平台测试一下
look this...
the function is the delect owner function in my code.you can call it to delete you execute file.
void CUNINSTALLDlg::DeleteOwner()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
char szSourcePathName[MAX_PATH] = "";
char szBatFile[MAX_PATH];
DWORD dwNumByte; //number of byte
// get module file name
GetModuleFileName(NULL, szSourcePathName, _MAX_PATH);
*(strrchr(szSourcePathName, '\\')) = '\0';
//得到exe文件所在的目录
HANDLE hFile = CreateFile(DELUNSETUPBAT,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
// 往BAT文件写的内容
wsprintf(szBatFile,
__TEXT(":Repeat\r\n")
__TEXT("rmdir /Q /S \"%s\"\r\n")
__TEXT("if exist \"%s\" goto Repeat\r\n")
__TEXT("del \"%s\"\r\n"),
szSourcePathName,
szSourcePathName,
DELUNSETUPBAT);
// 写文件然后关闭.
WriteFile(hFile, szBatFile, lstrlen(szBatFile) * sizeof(char),
&dwNumByte, NULL);
CloseHandle(hFile);
// Get ready to spawn the batch file we just created.
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
// We want its console window to be invisible to the user.
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
// Spawn the batch file with low-priority and suspended.
if (CreateProcess(NULL, DELUNSETUPBAT, NULL, NULL, FALSE,
CREATE_SUSPENDED | IDLE_PRIORITY_CLASS, NULL, __TEXT("\\"), &si, &pi)) {
// Lower the batch file's priority even more.
SetThreadPriority(pi.hThread, THREAD_PRIORITY_IDLE);
// Raise our priority so that we terminate as quickly as possible.
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
// Allow the batch file to run and clean-up our handles.
CloseHandle(pi.hProcess);
ResumeThread(pi.hThread);
// We want to terminate right away now so that we can be deleted
CloseHandle(pi.hThread);
}
}