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

Macros et VBA Excel Discussion :

[VBA-E] Tuer processus Excel cachés sous Win7 [XL-2003]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut [VBA-E] Tuer processus Excel cachés sous Win7
    Bonjour à tous,
    Sur la base du code suivant que j'ai trouvé sur ce post résolu de 2007 :http://www.developpez.net/forums/d27...s/#post6615539
    serait-il possible d'adapter cette fonction pour qu'elle ne supprime que des processus Office invisibles à l'utilisateur ?

    Voici la fonction en question :
    Code : 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
    Option Explicit
     
    Type strucPROCESSENTRY32
        dwSize As Long              ' DWORD : Size of the structure, in bytes
        cntUsage As Long            ' DWORD : not used (0)
        th32ProcessID As Long       ' DWORD : PID
        th32DefaultHeapID As Long   ' ULONG_PTR : not used (0)
        th32ModuleID As Long        ' DWORD : not used (0)
        cntThreads As Long          ' DWORD : Threads
        th32ParentProcessID As Long ' DWORD : parent process ID
        pcPriClassBase As Long      ' LONG
        dwFlags As Long             ' LONG : not longer used (0)
        szExeFile As String * 512   ' TCHAR szExeFile[MAX_PATH] name of the executable file for the process
    End Type
     
    Const TH32CS_SNAPPROCESS As Long = &H2
    Const PROCESS_TERMINATE As Long = &H1
    Const PROCESS_QUERY_INFORMATION As Long = &H400
     
    Private Declare Function CreateToolhelp32Snapshot Lib "Kernel32.dll" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
    Private Declare Function Process32First Lib "Kernel32.dll" (ByVal hSnapshot As Long, ByRef lppe As strucPROCESSENTRY32) As Long
    Private Declare Function Process32Next Lib "Kernel32.dll" (ByVal hSnapshot As Long, ByRef lppe As strucPROCESSENTRY32) As Long
    Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
    Private Declare Function CloseHandle Lib "Kernel32.dll" (ByVal hObject As Long) As Long
    Private Declare Function TerminateProcess Lib "Kernel32.dll" (ByVal hProcess As Long, ByVal dwExitCode As Long) As Long
     
    Sub TermProcess(strProcessName As String)
    Dim hSnapshot As Long
    Dim lppe As strucPROCESSENTRY32
    Dim hProc As Long
    Dim Retval As Long
    Dim strPrcsName As String
     
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
        lppe.dwSize = Len(lppe)
        Retval = Process32First(hSnapshot, lppe)
     
        Do While Retval
            strPrcsName = left(lppe.szExeFile, InStr(1, lppe.szExeFile, vbNullChar) - 1)
            ' Debug.Print strPrcsName, lppe.th32ProcessID
            If strPrcsName Like strProcessName Then
                hProc = OpenProcess(PROCESS_TERMINATE, 0, lppe.th32ProcessID)
                If hProc <> 0 Then
                    Retval = TerminateProcess(hProc, 0)
                    ' Si Retval=0 échec de la fonction TerminateProcess(..)
                    Call CloseHandle(hProc)
                End If
            End If
            ' Process Suivant
            Retval = Process32Next(hSnapshot, lppe)
        Loop
     
        Call CloseHandle(hSnapshot)
     
    End Sub
    Private Sub test()
        TermProcess "EXCEL.EXE"
    End Sub
     
    Function KillProcess(pLng_ProcessId As Long)
    Dim hProc As Long
    Dim Retval As Long
     
        hProc = OpenProcess(PROCESS_TERMINATE, 0, pLng_ProcessId)
        If hProc <> 0 Then
            Retval = TerminateProcess(hProc, 0)
            ' Si Retval=0 échec de la fonction TerminateProcess(..)
            Call CloseHandle(hProc)
        End If
    End Function
    Actuellement lorsqu'on appelle cette fonction TermProcess "EXCEL.EXE" elle supprime toutes les instances d'excel sans exception. (Même l'instance Excel qui appelle elle-même la fonction se ferme).
    Pour la petite histoire, j'avais un code du même style qui permettait de fermer des instances d'Excel cachées, mais le code ne fonctionne plus sur Windows 7.

    Voilà, est ce qu'il y aurait des personnes qui pourrait m'aider à arriver à mes fins ? (l'avantage de la fonction TermProcess c'est qu'elle fonctionne aussi bien sur XP que Seven 32 et 64bits, mais peut être il y a-t-il une autre solution plus simple)

    Merci d'avance pour votre aide précieuse

  2. #2
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut heu
    bonjour


    en fait tu n'est pas loin

    avant de passer par le getprocess(api) il faudrai que tu passe par les handles


    en identifiant le handle de selui que tu veut garder ouvert

    raisonnement:
    handle= lafenetre du fichier que tu veux garder

    les autre handle chercher le process parent
    killer le process

    je pense que ca doit etre possible
    mais c'est assez complexe

    au plaisir
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut
    J'ai bien compris la démarche, en fait il faudrait pouvoir lister les handles enfants du handle du processus.
    On peux faire cela à partir du handle du processus ?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut
    Yes, j'ai réadapté un code que j'ai trouvé le net (http://jacxl.free.fr/cours_xl/cours_...ples_api_suite) et ça à l'air de fonctionner aussi bien sur XP que sur Seven.

    Code : 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
     
    Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
    Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
    Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
     
     
    Sub FermerFenetreInvisible(sNomFenetre As String)
    '---------------------------------------------------------------------------------------
    ' Procedure : FermerFenetreInvisible
    ' Date      : 16/04/2012
    ' Purpose   : Ferme les fenêtres cachées avec le nom passé en argument
    '---------------------------------------------------------------------------------------
        Dim titre As String
        Dim hWnd As Long
        hWnd = FindWindow(0, 0)
     
        Do While hWnd <> 0
            If IsWindowVisible(hWnd) = 0 Then
                'Si n'est pas visible => récupération du nom de la fenêtre
                titre = String(100, Chr$(0))
                GetWindowText hWnd, titre, 100
                titre = Left$(titre, InStr(titre, Chr$(0)) - 1)
                If LCase(titre) Like "*" & LCase(sNomFenetre) & "*" Then
                    'Fermeture de la fenêtre
                    PostMessage hWnd, 16, 0, 0
                End If
            End If
            hWnd = GetWindow(hWnd, 2)
        Loop
    End Sub
     
     
    Sub test()
        'Nécessite la référence Microsoft Word x.0 object library
        Dim oAppWord As Word.Application
        Dim oAppWord2 As Word.Application
        Set oAppWord = CreateObject("Word.Application")
        Set oAppWord2 = CreateObject("Word.Application")
     
        oAppWord2.Visible = True
        oAppWord.Visible = False
     
        MsgBox "ouvrez le gestionnaire des tâches"
        FermerFenetreInvisible "microsoft word"
    End Sub
    Merci patricktoulon pour m'avoir donné la marche à suivre

  5. #5
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    bonjour

    oui mais dans ce cas tu kill les applications invisibles elles ne sont pas cibler par leur noms

    mais il est tres bien ce code


    au plaisir
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut
    Oui tout à fait, ce n'est plus par le nom du processus mais par le nom de la fenêtre. C'est un peu l'approche inverse, dans le sens où la fermeture de la fenêtre enclenche la fermeture du processus (enfin je crois ).
    Par contre d'un point de vue performance, c'est peut être plus long, à voir.

    Autre chose, dans le code ci-dessous, étant donné que je ferme un document, j'ai droit à la fameuse fenêtre : "Voulez vous sauvegarder les changements...", -ce qui, dans mon cas, ne m'arrange pas-.

    Donc voici une petite adaptation du code ci-dessus pour l'éviter :
    Code : 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
    Option Explicit
    Declare Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
    Declare Function GetWindowText Lib "USER32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Declare Function GetWindow Lib "USER32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    Declare Function IsWindowVisible Lib "USER32" (ByVal hWnd As Long) As Long
    Declare Function PostMessage Lib "USER32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    Public Const WM_QUIT = &H12
     
    Sub FermerFenetreInvisible(sNomFenetre As String)
    '---------------------------------------------------------------------------------------
    ' Procedure : FermerFenetreInvisible
    ' Date      : 16/04/2012
    ' Purpose   : Ferme les fenêtres cachées avec le nom de fenêtre passé en argument (sans le "voulez vous enregistrer..." éventuel)
    '---------------------------------------------------------------------------------------
        Dim titre As String
        Dim hWnd As Long
        hWnd = FindWindow(0, 0)
     
        Do While hWnd <> 0
            If IsWindowVisible(hWnd) = 0 Then
                'Si n'est pas visible => récupération du nom de la fenêtre
                titre = String(100, Chr$(0))
                GetWindowText hWnd, titre, 100
                titre = Left$(titre, InStr(titre, Chr$(0)) - 1)
                If LCase(titre) Like "*" & LCase(sNomFenetre) & "*" Then
                    'Fenêtre correspondante trouvée
                    'Fermeture sans le "voulez vous enregistrer..." grace à la constante WM_QUIT
                    PostMessage hWnd, WM_QUIT, 0&, 0&
                End If
            End If
            hWnd = GetWindow(hWnd, 2)
        Loop
    End Sub

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut
    Merci vous deux pour vos contributions, effectivement il y a plusieurs approches pour régler le problème, c'est très intéressant.
    Par contre, fermer tous les process excel sauf l'instance qui lance la macro n'est pas un avantage dans ma situation car si les utilisateurs de mon application ont d'autres fichiers Excel ouverts, cela va leur fermer tous leurs documents sans ménagement, et là je suis bon pour passer un sale quart d'heure ! ^^

    patricktoulon, j'ai encore une question sur ta dernière intervention sur l'api "findexecutable". Elle permet de retrouver l'handle du processus lié à l'handle de la fenêtre ?
    Si oui, je pourrais utiliser le 1er code que j'ai posté non ?

    En tout cas, merci pour vos contributions !! je comprends beaucoup mieux les handles et les api en général

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Application Excel - Tuer le processus EXCEL.EXE?
    Par xVINCEx dans le forum VB.NET
    Réponses: 21
    Dernier message: 18/04/2012, 10h43
  2. [VBA-E]Ouvrir une BDD access sous Excel
    Par toniox dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 02/05/2006, 16h45
  3. [VBA-E]Utilisation de la tabulation sous excel
    Par philvba dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 07/02/2006, 17h30
  4. [VBA-A]pb ouvrir processus excel
    Par JulienCEA dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 07/02/2006, 10h50
  5. [VBA][EXCEL] GetExternalData sous Excel97
    Par Scuriolus dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 23/12/2005, 08h33

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