如何让我的C#app擦除自身(自毁)?以下是我认为可行的两种方式:
这两种方法效率都不高。我觉得有一些内置的标志或Windows中允许这样的东西。我该怎么办?另外,您能提供一些示例代码吗?
更新:感谢您的所有答案!我要去尝试一下,然后看看它在哪里。
首先,有些人问我为什么要我的应用程序这样做。这就是答案:几天前,我读了Joel Spolsky在他的博客上发布的Project Aardvark规范,并提到客户端应用程序会在远程会话后删除自己。我想知道它是如何工作的,以及如果我需要这样做,我可以完成这样的壮举。
以下是对建议内容的一点概述:
当然,这些都有其缺点,如评论中所述。
但是,下面概述的这种方法是否有效?
有两个可执行文件:Program.exe和Cleaner.exe。前者是程序本身,后者是删除Program.exe及其自身的应用程序(如果它被加载到内存中,我将要解释)。 Program.exe(具有依赖关系)是否可以加载所有Cleaner.exe,它没有任何依赖关系,到内存并运行它?
如果可以,可以将Cleaner.exe打包到Program.exe中,加载到内存中,然后运行吗?
答案 0 :(得分:19)
有MoveFileEx API,当给出MOVEFILE_DELAY_UNTIL_REBOOT
标志时,将在下次系统启动时删除指定的文件。
答案 1 :(得分:10)
关于这个主题有一个很棒的CodeProject Article。
编辑:基本上这是一个简单的cmd调用,会在几秒钟后删除指定的文件。
Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + Application.ExecutablePath);
Application.Exit();
答案 2 :(得分:7)
只要您需要在计算机上存在物理存在,您将永远无法保证这将起作用。例如:
如果您的应用程序需要此级别的安全性,请考虑将其托管在您控制的计算机上(例如,通过提供Web服务并让存根客户端以这种方式访问它)。
在一个有点相关的说明中,人们也倾向于推测某人的动机:(1)需要在某人的机器上存在物理存在;(2)想要删除该应用程序存在的证据。
答案 3 :(得分:4)
对@Bobby回答的更正,以防人们发现它有用 - 需要引用可执行路径。此外,下面是将cmd.exe窗口设置为隐藏(否则它将作为黑色控制台窗口闪烁)并转换为运行而不依赖于System.Windows.Forms程序集(Application类)。
var exepath = Assembly.GetEntryAssembly().Location; var info = new ProcessStartInfo("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del \"" + exepath + "\""); info.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(info).Dispose(); Environment.Exit(0);
答案 4 :(得分:1)
还有FileOptions.DeleteOnClose
,但这需要打开文件才能写入。您可以使用这样的序列(未经测试)来执行此操作:
Original.exe
启动,并检测(从其自己的名称)它需要触发自毁功能。Original.exe
使用Temp.exe
创建一个新文件FileOptions.DeleteOnClose
,并将自己的内容复制到其中,但尚未关闭它Original.exe
打开Temp.exe
的第二个只读句柄,并关闭第一个写句柄。只读句柄可以与执行句柄共存,同时保持文件打开以延迟自动删除。Original.exe
发布Temp.exe
。 Temp.exe
检测到它已从临时目录启动并绕过自毁序列并继续正常运行。Original.exe
退出(将其只读句柄带到Temp.exe
。)Temp.exe
继续投放。退出时,文件Temp.exe
将不再使用,因此会自动删除。 编辑#2 :实际上我认为这不可能,因为它依赖于内核打开带有FILE_SHARE_DELETE
标志的文件,这是不太可能的。
答案 5 :(得分:1)
按NJ排序 C# 其他代码不起作用,所以它很简单 如果你创建循环到del应用程序的浴文件 批处理文件本身 如果你不想使用,你可以使用takkill命令来杀死进程 application.close方法
`string delname = "test.cmd";
string fileurl = Application.ExecutablePath;
System.IO.StreamWriter file = new System.IO.StreamWriter(delname);
file.WriteLine(":Repeat");
file.WriteLine("del \"" + fileurl + "\"");
file.WriteLine("if exist \"" + fileurl + "\" goto Repeat");
file.WriteLine("del \"" + delname + "\"");
file.Close();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.FileName = delname;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(startInfo);`
` Th3 3e3一个不是3d部分 I5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
答案 6 :(得分:1)
Think CMD
int sectosleep = 5000;
string exename = "yourexe.exe";
string location = @"c:\yourexe.exe"
Process.Start("cmd.exe", "/C taskkill /f /im " + exename + " & ping 1.1.1.1 -n 1 -w " + sectosleep + " > Nul & Del /F /Q \"" + location + "\"");
;>
答案 7 :(得分:0)
我知道如果您使用旧版本并选择不更新,反射器会自行删除。你可能会试图找出它的作用。我将从FileMon开始,看看它是否会产生任何进程来实现这一目标。
答案 8 :(得分:0)
由于我的应用程序(Windows服务)是通过Windows Installer安装的,我使用它自行删除:
Dim uninstall_params As String = "/x {MY-PRODUCTS-GUID} /qn /norestart REBOOT=ReallySuppress"
proc.StartInfo = New ProcessStartInfo("msiexec.exe", uninstall_params)
proc.Start()
Environment.Exit(-1)
抱歉 - 它在VB中,但应该可以轻松转换为C#。
答案 9 :(得分:0)
适用于Windows 7& 8,**确保您使用管理员权限运行您的应用程序,否则您将收到错误。
此代码存在于其他地方,因此我无法获得完全的功劳,我发现通过添加“Application.Exit();”
我发现它对我有用static void autodelete()
{
string batchCommands = string.Empty;
string exeFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", string.Empty).Replace("/", "\\");
batchCommands += "@ECHO OFF\n"; // Do not show any output
batchCommands += "ping 127.0.0.1 > nul\n"; // Wait approximately 4 seconds (so that the process is already terminated)
batchCommands += "echo j | del /F "; // Delete the executeable
batchCommands += exeFileName + "\n";
batchCommands += "echo j | del deleteMyProgram.bat"; // Delete this bat file
File.WriteAllText("deleteMyProgram.bat", batchCommands);
Process.Start("deleteMyProgram.bat");
Application.Exit();
}
答案 10 :(得分:0)
这是Uninstall.exe:
关闭。
等待3秒钟。
尝试杀死仍在运行的任务。
等待3秒钟。
删除其中包含Uninstall.exe的应用程序目录。
public void Uninstall()
{
var delPath = AppDomain.CurrentDomain.BaseDirectory;
var procId = Process.GetCurrentProcess().Id;
var psi = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/C timeout 3 & Taskkill /F /PID {procId} & timeout 3 & rd /s /q \"{delPath}\"",
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
};
Process.Start(psi);
Application.Current.Shutdown();
}