1、介绍
最近在做一个系统,要求在安装程序在完成安装之后删除自身。遇到这样的问题,当然要祭起”Google大法”。果不其然,与我想同问题的朋友还是不少。网上给出的方案里面大致有这么几种。
2、方法
(1)利用批处理文件,删除自身
using System.Runtime.InteropServices;
//****************************************添加引用
[DllImport("kernel32.dll")]
public static extern uint WinExec(string lpCmdLine, uint uCmdShow);
private void button1_Click(object sender, EventArgs e)
{
string vBatFile = Path.GetDirectoryName(Application.ExecutablePath) + "//Zswang.bat";
using (StreamWriter vStreamWriter =new StreamWriter(vBatFile, false, Encoding.Default))
{
vStreamWriter.Write(string.Format(
":del/r/n" +
" del /"{0}/"/r/n" +
"if exist /"{0}/" goto del/r/n" + //此处已修改
"del %0/r/n", Application.ExecutablePath));
}
//************ 执行批处理
WinExec(vBatFile, 0);
//************ 结束退出
Close();
}
(2)利用压栈和出栈方式(汇编方法)
#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;
}
(3)DELETE_ON_CLOSE方法
先复制(CLONE)一个自己,用复制品起动另一个进程,然后自己结束运行,则原来的EXE文件不被系统保护.这时由新进程作为杀手删除原来的EXE文件,并且继续完成程序其他的功能。利用FILE_FLAG_DELETE_ON_CLOSE标志告诉操作系统,当和这个文件相关的所有句柄都被关闭之后(包括上面这个CREATEFILE创建的句炳),就把这个文件删除。
代码见
http://amxiaomao.blog.bokee.net/bloggermodule/blog_viewblog.do?id=165370
(4)利用cmd命令
这种方法,在网上并不多见。因此,本文重点介绍这种方法。这是在外国网站上偶尔看到的方法。原文提供了两种不同的命令语句格式。
代码非常简单。
在button1的click事件处理程序添加如下代码:
Process.Start("cmd.exe", "/C choice /C Y /N /D Y /T 3 & Del " + Application.ExecutablePath);
Application.Exit();
下面解释下命令的意思:
Cmd /c 调用命令窗口执行dos指令
Choice /C Y /N /D Y /T 3 这个命令有点怪,等待3分钟之后执行一个默认为y的选择命令
& 连接下一个命令(用于一行执行多个命令)
Del <Application. ExecutablePath> 删除可执行文件
可惜这种方法由于xp不支持Choice命令,没有测试成功。
基于这种思路,该文章还提出一种命令格式
Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " +
Application.ExecutablePath);
Application.Exit();
利用 ping命令的 –w 参数指定延时执行。经测试成功删除自身。
3、总结
方式2、3,我没有测试,但是根据文章内容来看要想在c#中实相对来说比较困难一些。(4)方式,利用某些dos命令的延时效果,在程序退出之后自动删除程序自身思路非常巧妙。也避免了bat方式,循环删除的问题。当然4方法从本质上应该和1方法差不多,但是书写来简洁的多了,:)。