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创建的句炳),就把这个文件删除。

(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方法差不多,但是书写来简洁的多了,:)。