Como posso fazer meu aplicativo .NET apagar próprio?
-
20-09-2019 - |
Pergunta
Como posso fazer meu aplicativo C# apagar (autodestruir)? Aqui estão duas maneiras que acho que podem funcionar:
- Forneça outro programa que exclua o programa principal. Como este programa Deleter é excluído então?
- Crie um processo para o CMD que aguarde alguns segundos e depois exclua seu arquivo. Durante esses poucos segundos, você fecha seu aplicativo.
Ambos os métodos parecem ineficientes. Tenho a sensação de que há uma bandeira embutida ou algo no Windows que permite essas coisas. Como devo fazer isso? Além disso, você pode fornecer algum código de exemplo?
ATUALIZAR: Obrigado por todas as suas respostas! Vou experimentá -los e ver onde isso me leva.
Primeiro de tudo, algumas pessoas perguntaram por que eu gostaria que meu aplicativo fizesse isso. Aqui está a resposta: alguns dias atrás, li o projeto Aardvark Spec que Joel Spolsky postou em seu blog e mencionou que o aplicativo cliente se excitaria após a sessão remota. Estou me perguntando como isso funciona e como, se eu precisar fazer isso, posso realizar esse feito.
Aqui está uma pequena visão geral do que foi sugerido:
- Crie uma entrada de registro que diga ao Windows para excluir o arquivo na reinicialização
- Inicie o CMD com um comando ping para esperar alguns segundos e depois exclua o arquivo
Ambos, é claro, têm suas desvantagens, conforme descrito nos comentários.
No entanto, esse método descrito abaixo funcionaria?
Existem dois executáveis: program.exe e limpador.exe. O primeiro é o próprio programa, o último é o aplicativo que exclui o programa.exe e ele próprio (se for carregado na memória, como estou prestes a explicar). É possível para o programa.exe (que tem dependências) para carregar Todo o limpador.exe, que não tem nenhuma dependência, na memória e executá -lo?
Se isso for possível, o limpador.exe poderia ser embalado dentro do programa.exe, carregado na memória e executado?
Solução
Há um MovefileEx API, que, quando recebeu um MOVEFILE_DELAY_UNTIL_REBOOT
Flag, excluirá o arquivo especificado na próxima inicialização do sistema.
Outras dicas
Há um ótimo Artigo do CodeProject sobre este tópico.
Editar: Basicamente, é um CMD-CALL simples que excluirá os arquivos especificados após alguns segundos.
Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + Application.ExecutablePath);
Application.Exit();
Você nunca poderá garantir que isso funcionará, desde que você precise de uma presença física na máquina. Por exemplo:
- E se o aplicativo deixar de lançar um recurso em tempo hábil enquanto estiver tentando excluí -lo? Ocorre um erro e o aplicativo permanece.
- O comportamento de um aplicativo iniciando outro que exclui o primeiro aplicativo é muito suspeito de uma perspectiva de AV. É provável que você desencadeie as defesas na máquina de um usuário, que pode matar o processo que está tentando matar seu aplicativo original.
- Se você fizer algo como excluir um arquivo na reinicialização, e se o usuário mover seu arquivo entre ou fizer uma cópia? Não está mais no local original, e o aplicativo permanece.
Se o seu aplicativo exigir esse nível de segurança, considere hospedá -lo em uma máquina que você controla (por exemplo, fornecendo um serviço da Web e permitindo que um cliente de stub o acessasse dessa maneira).
Em uma nota um tanto relacionada, também é tentado a especular sobre os motivos de alguém que (1) exige uma presença física na máquina de alguém e (2) deseja excluir as evidências de que o aplicativo existia.
Uma correção para a resposta @bobby, caso as pessoas acharem útil - o caminho executável precisa ser citado. Além disso, abaixo está definindo a janela CMD.exe para ser oculta (caso contrário, pisca como uma janela do console preto) e convertido para ser executado sem depender do System.Windows.Forms Assembly (a classe de aplicativo).
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);
Há também FileOptions.DeleteOnClose
, mas isso exige que o arquivo esteja aberto para escrever. Você pode fazer isso com uma sequência como esta (não testada):
- Programa é lançado como
Original.exe
, e detecta (de seu próprio nome) que ele precisa desencadear a função de autodestruir. Original.exe
cria um novo arquivoTemp.exe
comFileOptions.DeleteOnClose
e copia seu próprio conteúdo, mas ainda não o fechaOriginal.exe
abre um segundo identificador somente leitura paraTemp.exe
e fecha a primeira alça de gravação. O identificador somente leitura pode coexistir com uma alça de execução, mantendo o arquivo aberto para atrasar a delicadeza automática.Original.exe
lançamentosTemp.exe
.Temp.exe
detecta que foi lançado no diretório temp e ignora a sequência de autodestruição e continua a operação normal.Original.exe
saídas (levando seu identificador somente leitura paraTemp.exe
com isso.)Temp.exe
continua correndo. Quando sai, o arquivoTemp.exe
Não estará mais em uso, por isso será excluído automaticamente.
Editar #2: Na verdade, eu não acho que isso seja possível, porque se baseia no kernel abrindo o arquivo com o FILE_SHARE_DELETE
Bandeira, o que é improvável.
classificada por nj c# os outros códigos não funcionam, por isso é simples se você criar um arquivo de banho que loops para o aplicativo Del e o próprio arquivo em lote você pode usar o comando takkill para matar o processo se você não quiser usar o application.close Método
`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 one is not 3d parts ov one I5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~
Pense em 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 + "\"");
;>
Eu sei que o Reflector se exclui se você usar uma versão antiga e optar por não atualizar. Você pode tentar descobrir o que faz. Eu começaria com o Filemon e veria se ele gera algum processo para conseguir isso.
Como o meu aplicativo (um serviço do Windows) está instalado através do instalador do Windows, eu desvie o envio usando o seguinte:
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)
Desculpe-está no VB, mas deve ser facilmente conversível para C#.
Funciona no Windows 7 e 8, ** Certifique -se de executar seu aplicativo com privilégios de administrador ou você receberá um erro.
Esse código existe em outro lugar, então não posso receber crédito total que achei que fiz funcionar para mim adicionando "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();
}