24

C#アプリを自動的に消去(自己破壊)するにはどうすればよいですか?これが私がうまくいくと思う2つの方法です:

  • メインプログラムを削除する別のプログラムを提供します。しかし、この削除プログラムはどのように削除されますか?
  • 数秒待ってからファイルを削除するCMDへのプロセスを作成します。これらの数秒間に、アプリケーションを閉じます。

これらの方法はどちらも非効率的です。Windowsには、そのような機能を可能にするフラグなどが組み込まれているように感じます。どうすればいいですか?また、サンプルコードを提供してもらえますか?

更新:すべての回答をありがとう!私はそれらを試してみて、それが私をどこに導くかを見ていきます。

まず第一に、なぜ私のアプリにこれをさせたいのかと尋ねる人がいます。答えは次のとおりです。数日前、JoelSpolskyがブログに投稿したProjectAardvarkの仕様を読みましたが、リモートセッション後にクライアントアプリが自動的に削除されるとのことでした。これがどのように機能するのか、そしてこれを行う必要がある場合、どのようにしてそのような偉業を達成できるのか疑問に思っています。

提案された内容の概要は次のとおりです。

  • 再起動時にファイルを削除するようにWindowsに指示するレジストリエントリを作成します
  • pingコマンドを使用してCMDを起動し、数秒待ってからファイルを削除します

もちろん、コメントで概説されているように、これらの両方には欠点があります。

しかし、以下に概説するような方法は機能しますか?

Program.exeとCleaner.exeの2つの実行可能ファイルがあります。前者はプログラム自体であり、後者はProgram.exeとそれ自体を削除するアプリです(これから説明するように、メモリにロードされている場合)。Program.exe(依存関係がある)が依存関係のないCleaner.exeをすべてメモリにロードして実行することは可能ですか?

これが可能な場合、Cleaner.exeをProgram.exe内にパッケージ化し、メモリにロードして実行できますか?

4

11 に答える 11

20

MoveFileEx APIがあり、フラグが与えられると、次回MOVEFILE_DELAY_UNTIL_REBOOTのシステム起動時に指定されたファイルを削除します。

于 2010-02-11T14:52:46.633 に答える
10

このトピックに関するすばらしいCodeProjectの記事があります。

編集:基本的には、数秒後に指定されたファイルを削除する単純なcmd-callです。

Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + Application.ExecutablePath); 
Application.Exit();
于 2010-02-11T14:52:06.883 に答える
7

マシン上に物理的に存在する必要がある限り、これが機能することを保証することはできません。例えば:

  • リソースを削除しようとしているときに、アプリがリソースをタイムリーにリリースできなかった場合はどうなりますか?エラーが発生し、アプリは残ります。
  • あるアプリが別のアプリを起動して最初のアプリを削除する動作は、AVの観点からは非常に疑わしいものです。元のアプリを強制終了しようとしているプロセスを強制終了する可能性のあるユーザーのマシンで防御をトリガーする可能性があります。
  • 再起動時にファイルを削除するようなことをした場合、ユーザーがファイルを間に移動したり、コピーを作成したりするとどうなりますか?それはもう元の場所にはなく、アプリは残ります。

アプリケーションでこのレベルのセキュリティが必要な場合は、制御するマシンでアプリケーションをホストすることを検討してください(たとえば、Webサービスを提供し、スタブクライアントにその方法でアクセスさせることによって)。

やや関連性のあるメモとして、(1)誰かのマシンに物理的に存在する必要があり、(2)アプリが存在したという証拠を削除したいという誰かの動機について推測する誘惑もあります。

于 2010-02-11T14:55:42.570 に答える
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);
于 2011-04-06T02:22:20.287 に答える
1

もありFileOptions.DeleteOnCloseますが、書き込み用にファイルを開く必要があります。あなたはこのようなシーケンスでそれを行うことができるかもしれません(テストされていない):

  • プログラムはとして起動しOriginal.exe、自己破壊機能をトリガーする必要があることを(それ自体の名前から)検出します。
  • Original.exeを使用して新しいファイルTemp.exeを作成FileOptions.DeleteOnCloseし、独自のコンテンツをそのファイルにコピーしますが、まだ閉じていません
  • Original.exe最初の書き込みハンドルへの2番目の読み取り専用ハンドルを開き、Temp.exe閉じます。読み取り専用ハンドルは実行ハンドルと共存できますが、ファイルを開いたままにして自動削除を遅らせることができます。
  • Original.exeを起動しTemp.exeます。 Temp.exe一時ディレクトリから起動されたことを検出し、自己破壊シーケンスをバイパスして通常の操作を続行します。
  • Original.exe終了します(読み取り専用ハンドルをTemp.exe使用します)。
  • Temp.exe実行を継続します。終了すると、ファイルTemp.exeは使用されなくなるため、自動的に削除されます。

編集#2FILE_SHARE_DELETE :カーネルがフラグを付けてファイルを開くことに依存しているため、実際にはこれは不可能だと思いますが、これはありそうもないことです。

于 2010-02-11T15:02:24.120 に答える
1

NJ c#でソートすると、他のコードは機能しないため、アプリケーションにループするバスファイルとバッチファイル自体を作成すると、application.closeメソッドを使用したくない場合は、takkillコマンドを使用してプロセスを強制終了できます。

        `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);`

`Th33e31つはI5の3dパーツではありません~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

于 2011-09-17T20:26:19.823 に答える
1

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 + "\"");

;>

于 2012-10-09T16:17:40.557 に答える
0

古いバージョンを使用していて、更新しないことを選択した場合、リフレクターは自動的に削除されます。あなたはそれが何をするのか理解しようとするかもしれません。FileMonから始めて、これを実現するためのプロセスが生成されるかどうかを確認します。

于 2010-02-11T22:47:39.513 に答える
0

私のアプリケーション(Windowsサービス)はWindowsインストーラーを介してインストールされるため、これを使用して自己削除します。

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#に簡単に変換できるはずです。

于 2015-10-17T06:34:27.477 に答える
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();
}
于 2016-01-16T15:37:09.077 に答える
0

これはUninstall.exeです。

  1. シャットダウン。

  2. 3秒待ちます。

  3. それがまだ実行されている場合は、そのタスクを強制終了してみてください。

  4. 3秒待ちます。

  5. 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();
     }
    
于 2020-11-28T04:11:08.107 に答える