IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Supprimer l'exécutable lors de son exécution


Sujet :

C#

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 14
    Points : 6
    Points
    6
    Par défaut Supprimer l'exécutable lors de son exécution
    Bonjour,
    Je fais un programme en C# et j'aimerai que à la fin du script il se supprime tout seul.
    J'ai fais ceci mais ça lève un exception:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.IO.File.Delete(Application.ExecutablePath);
    Merci d'avance pour vos réponses

  2. #2
    En attente de confirmation mail
    Inscrit en
    Août 2006
    Messages
    550
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Août 2006
    Messages : 550
    Points : 669
    Points
    669
    Par défaut
    Un executable ne peut pas se supprimer lui-même étant donné qu'il est en cours d'execution...

    En lançant ton application à partir d'un fichier cmd ou bat tu peux supprimer à la fin de l'execution via une command dos...

  3. #3
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Comme dit précédemment un exécutable ne peut pas s'autosupprimer, simplement parce que pour exécuter son code Windows verrouille l'exe et ça se comprend ...
    Mais il existe des subterfuges pour donner l'illusion :
    - Lancer ton application à partir d'un fichier bat, mais ça c'est pas élégant
    - Créer un fichier bat à la volée à la fin de l'exécution de ton application avec un code genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Beg:
    erase PATH_DE_TON_EXE
    if exists PATH_DE_TON_EXE goto Beg
    erase LE_FICHIER_BAT
    mais il faudrait vérifier, ça fait longtemps que j'ai pas touché aux fichiers bat (si tu veux je peut te passer une classe que j'ai crée à cet effet ... là j'y ai pas accès, mais ça se fait).
    L'avantage avec les bats c'est que eux, il peuvent s'autosupprimer
    - Créer ton exe et y mettre un autre exe qui sera extrait dans le dossier temp de Windows et qui aura en charge de supprimer ton application. Ensuite, pour supprimer le "supprimeur" tu peut utiliser l'api MoveFileEx avec comme chemin source le supprimeur, chemin de destination vide, et attributs "MOVE_FILE_ON_REBOOT" et dans ce cas ton "supprimeur" sera supprimé par Windows au prochain redémarrage

    Voilà en gros les options ...

  4. #4
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Excellent, le .Bat généré en fin d'éxécution.
    Je mettrai quand même une petite ligne "Sleep 1" après Beg:

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 14
    Points : 6
    Points
    6
    Par défaut merci pour vos réponses
    Merci beaucoup pour toutes ces méthodes.
    Je vais essayer la méthode du MoveFileEx et je vous tien au courant du résultat.

  6. #6
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Mon autodeleter, éprouvé par DreamShield depuis 2 ans sans bugs (a priori )

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.Reflection;
    using System.Diagnostics;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
     
    namespace IoDeleterApp
    {
        class AutoDeleter
        {
            public static bool WindowsIsClosing { get; protected set; }
     
            static AutoDeleter()
            {
                WindowsIsClosing = false;
                Microsoft.Win32.SystemEvents.SessionEnding += delegate
                {
                    WindowsIsClosing = true;
                };
                Microsoft.Win32.SystemEvents.SessionEnded += delegate
                {
                    WindowsIsClosing = true;
                };
            }
     
            static string GetTmpBatName()
            {
                const string model = "{0}\\DS_Unist{1}.bat";
     
                string WinTmpDir = Path.GetTempPath();
                int nm = 0;
                while (File.Exists(String.Format(model,WinTmpDir,nm.ToString())))
                {
                    nm++;
                }
     
                return String.Format(model, WinTmpDir, nm.ToString());
            }
     
            [Flags]
            public enum MoveFileFlags
            {
                MOVEFILE_REPLACE_EXISTING = 0x00000001,
                MOVEFILE_COPY_ALLOWED = 0x00000002,
                MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004,
                MOVEFILE_WRITE_THROUGH = 0x00000008,
                MOVEFILE_CREATE_HARDLINK = 0x00000010,
                MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
            }
     
            [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName,
               MoveFileFlags dwFlags);
     
            public static void AutoDeleterStart()
            {
                string file_name = Assembly.GetEntryAssembly().Location;
     
                if (WindowsIsClosing)
                {
                    /* Si Windows est en train de se fermer, on va se supprimer au prochain redémarrage */
                    MoveFileEx(file_name, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);
                }
                else
                {
                    Environment.CurrentDirectory = Path.GetDirectoryName(Application.ExecutablePath);
     
                    FileStream fi = null;
     
                    int try_count = 20;
                    do
                    {
                        try { fi = new FileStream(GetTmpBatName(), FileMode.Create); }
                        catch { }
                        try_count--;
     
                        System.Threading.Thread.Sleep(1000);
                    }
                    while (try_count >= 0 && fi == null);
     
                    if (try_count < 0)
                    {
                        MessageBox.Show("Impossible de supprimer certains fichiers temporraires car la création du fichier d'auto-suppression a échouée",
                            "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
     
                    if (fi == null)
                        fi = new FileStream(GetTmpBatName(), FileMode.Create); /* erreur possible, si le do a échoué ... */
     
                    string name = fi.Name;
     
                    StreamWriter wr = new StreamWriter(fi, Encoding.Default);
                    wr.WriteLine("@echo off");
                    wr.WriteLine("REM DreamShield.IO.Utils AutoDeleter Bat");
                    wr.WriteLine("REM BatGenerator v 1.0");
                    wr.WriteLine();
     
                    wr.WriteLine(":del_process");
                    wr.WriteLine(String.Format("@if exist \"{0}\" del \"{0}\"", file_name));
                    wr.WriteLine(String.Format("@if exist \"{0}\" goto del_process", file_name));
                    wr.WriteLine();
     
                    wr.WriteLine(String.Format("del \"{0}\"", name));
     
                    wr.Flush();
                    fi.Flush();
                    fi.Close();
     
                    ProcessStartInfo info = new ProcessStartInfo();
                    info.WindowStyle = ProcessWindowStyle.Hidden;
                    info.FileName = name;
                    Process.Start(info);
                }
            }
        }
    }

    Pour l'utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AutoDeleter.AutoDeleterStart();
    à la fin de l'exécution du programme pour que celui ci soit autosupprimé dès l'arrêt du process.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 14
    Points : 6
    Points
    6
    Par défaut [Résolu] Merci
    Merci beaucoup à vous tous (particulièrement à smyley ) pour votre aide.
    J'ai utiliser la class de smyley et ça marche nickel.

    Visual Studio 2005 m'a quand même relevé une erreur à la compilation à cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static bool WindowsIsClosing {get; protected set; }
    je l'ai donc remplacée par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static bool WindowsIsClosing = false;
    et maintenant tout marche bien

  8. #8
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    C'est parce que moi je code en C# 3.0 avec VS 2008 alors que toi tu utilises le C# 2.0 avec VS 2005. Le C# 3.0 peut générer automatiquement les champs qui correspondent aux propriétés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public virtual bool Test{get;set;}
    deviens en gros
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    bool _test = false;
    public virtual bool Test
    {
     get {return _test;}
     set {_test = value;}
    }
    Sinon, il aura fallu que je dise que ça marche pour trouver un hic :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
     
    class AutoDeleter
        {
            public static bool WindowsIsClosing { get; protected set; }
     
            static AutoDeleter()
            {
                WindowsIsClosing = false;
                Microsoft.Win32.SystemEvents.SessionEnding += delegate
                {
                    WindowsIsClosing = true;
                };
                Microsoft.Win32.SystemEvents.SessionEnded += delegate
                {
                    WindowsIsClosing = true;
                };
            }
     
            static string GetTmpBatName()
            {
                const string model = "{0}\\DS_Unist{1}.bat";
     
                string WinTmpDir = Path.GetTempPath();
                int nm = 0;
                while (File.Exists(String.Format(model,WinTmpDir,nm.ToString())))
                {
                    nm++;
                }
     
                return String.Format(model, WinTmpDir, nm.ToString());
            }
     
            [Flags]
            public enum MoveFileFlags
            {
                MOVEFILE_REPLACE_EXISTING = 0x00000001,
                MOVEFILE_COPY_ALLOWED = 0x00000002,
                MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004,
                MOVEFILE_WRITE_THROUGH = 0x00000008,
                MOVEFILE_CREATE_HARDLINK = 0x00000010,
                MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
            }
     
            [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName,
               MoveFileFlags dwFlags);
     
            public static bool IsFullASCIIString(string str)
            {
                /*
                 * Windows pour l'instant (même jusqu'à Vista) ne supporte
                 * pas l'exécution (via cmd) de fichiers bat qui contient
                 * des caractères accentués.
                 * 
                 * Dans le cas où on en a, on va donc repasser
                 * vers le MoveFileEx ...
                 * */
     
                byte[] b = Encoding.ASCII.GetBytes(str);
                string ascii_equivalent = Encoding.ASCII.GetString(b);
     
                return str.Equals(ascii_equivalent);
            }
     
            public static void AutoDeleterStart()
            {
                string file_name = Assembly.GetEntryAssembly().Location;
     
                if (!IsFullASCIIString(file_name) || WindowsIsClosing)
                {
                    /* Si Windows est en train de se fermer, on va se supprimer au prochain redémarrage */
                    MoveFileEx(file_name, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);
                }
                else
                {
                    Environment.CurrentDirectory = Path.GetDirectoryName(Application.ExecutablePath);
     
                    FileStream fi = null;
     
                    int try_count = 20;
                    do
                    {
                        try { fi = new FileStream(GetTmpBatName(), FileMode.Create); }
                        catch { }
                        try_count--;
     
                        System.Threading.Thread.Sleep(1000);
                    }
                    while (try_count >= 0 && fi == null);
     
                    if (try_count < 0)
                    {
                        MessageBox.Show("Impossible de supprimer certains fichiers temporraires car la création du fichier d'auto-suppression a échouée",
                            "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
     
                    if (fi == null)
                        fi = new FileStream(GetTmpBatName(), FileMode.Create); /* erreur possible, si le do a échoué ... */
     
                    string name = fi.Name;
     
                    StreamWriter wr = new StreamWriter(fi, Encoding.Default);
                    wr.WriteLine("@echo off");
                    wr.WriteLine("REM DreamShield.IO.Utils AutoDeleter Bat");
                    wr.WriteLine("REM BatGenerator v 1.0");
                    wr.WriteLine();
     
                    wr.WriteLine(":del_process");
                    wr.WriteLine(String.Format("@if exist \"{0}\" del \"{0}\"", file_name));
                    wr.WriteLine(String.Format("@if exist \"{0}\" goto del_process", file_name));
                    wr.WriteLine();
     
                    wr.WriteLine(String.Format("del \"{0}\"", name));
     
                    wr.Flush();
                    fi.Flush();
                    fi.Close();
     
                    ProcessStartInfo info = new ProcessStartInfo();
                    info.WindowStyle = ProcessWindowStyle.Hidden;
                    info.FileName = name;
                    Process.Start(info);
                }
            }
        }

    En gros ce qui change c'est :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    !IsFullASCIIString(file_name) || WindowsIsClosing
    Parce que si le nom de l'utilisateur (par exemple) contient un accent, cmd ne sais pas gérer donc il faut repasser à la suppression au redémarrage.

    Sinon si vous trouvez un moyen de faire à cmd exécuter un fichier batch unicode ...

Discussions similaires

  1. Réponses: 5
    Dernier message: 31/08/2013, 13h21
  2. trigger me signal une erreur lors de son exécution
    Par scofild20 dans le forum SQL
    Réponses: 7
    Dernier message: 02/05/2009, 14h22
  3. Réponses: 2
    Dernier message: 07/01/2008, 18h01
  4. Limiter la charge lors de l'exécution de son application
    Par Bazunga dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 04/07/2007, 23h16
  5. Réponses: 14
    Dernier message: 26/05/2006, 00h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo