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

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 47
    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 : 47
    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 : 47
    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 : 47
    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
    Expert confirmé
    Avatar de fring
    Homme Profil pro
    Engineering
    Inscrit en
    Février 2008
    Messages
    3 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : Belgique

    Informations professionnelles :
    Activité : Engineering

    Informations forums :
    Inscription : Février 2008
    Messages : 3 900
    Par défaut
    Bonjour,

    J'allais justement poster une proposition du même style mais qui ferme toutes les instances Excel (visible ou non) sauf l'instance contenant la macro

    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
    Option Explicit
    Private Const WM_QUIT = &H12
    Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function GetDesktopWindow Lib "user32" () As Long
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim lhWnd As Long, TitreFen As String, ret As Long
     
    Sub Stop_Instances_Xl()
     
    lhWnd = GetWindow(GetDesktopWindow(), 5)
    Do While lhWnd <> 0
        TitreFen = String(255, 0)
        ret = GetWindowText(lhWnd, TitreFen, 255)
        If TitreFen <> String(255, 0) Then
            If Split(TitreFen, " - ")(0) = "Microsoft Excel" Then
                If StrComp(TitreFen, Application.Caption, vbTextCompare) <> 0 Then PostMessage lhWnd, WM_QUIT, 0, 0
            End If
        End If
        lhWnd = GetWindow(lhWnd, 2)
    Loop
     
    End Sub

  8. #8
    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
    bonjour fring

    j'étais en train justement de lui écrire un code similaire au tiens

    parce que finalement c'est exactement ça qu'il veux fermer tout les autre fichiers que celui de la macro
    tu a été plus rapide que moi

    voila un truc sympa ahhhh!! jadore faire joujou avec les apis

    nickel tout les deux

    au plaisir

    en regardant un peu dans mes anciens exercices
    je me suis rendu compte qu'il y avait encore une solution


    puisque tu arrive a trouver les handles des fenetres visible ou pas

    donc certainement le nom du fichier

    tu pouvais aussi utiliser l'api "findexecutable"
    et tu kill

    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

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 47
    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

  10. #10
    Expert confirmé
    Avatar de fring
    Homme Profil pro
    Engineering
    Inscrit en
    Février 2008
    Messages
    3 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : Belgique

    Informations professionnelles :
    Activité : Engineering

    Informations forums :
    Inscription : Février 2008
    Messages : 3 900
    Par défaut
    Citation Envoyé par Hindioumax Voir le message
    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 ! ^^
    Au temps pour moi ... je n'avais pas bien lu et j'ai zappé le fait que tu ne voulais supprimer que les applications invisibles.

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

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut
    No probleme fring
    J'ai trouvé une classe sur vbfrance
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ' si notepad est ouvert
    ' pour récupérer son PID à partir du nom de son fichier.exe
    ' et pour récupérer l'handle de sa fenêtre à partir du nom de son fichier.exe
     
    ' set the class
    Dim clsP As CProcessInfo
    Set clsP = New CProcessInfo
     
    ProcessPID = clsP.GetProcessPidByName("notepad.exe")
    ProcessHwnd = clsP.GetProcessWindowHwndByName("notepad.exe")
     
    ' release the class
    Set clsP = Nothing
    Mais je n'ai pas eu le temps de la tester encore.

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

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut
    C'est interdit de mettre un lien externe ? parce qu'en fait le code n'a pas de sens si on ne peux pas télécharger la classe (et vu que mon lien a été supprimé après modération...)

  13. #13
    Expert confirmé
    Avatar de fring
    Homme Profil pro
    Engineering
    Inscrit en
    Février 2008
    Messages
    3 900
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : Belgique

    Informations professionnelles :
    Activité : Engineering

    Informations forums :
    Inscription : Février 2008
    Messages : 3 900
    Par défaut
    C'est à éviter dans la mesure du possible pour les raisons suivantes
    Dans la plupart des cas nos ressources, c'est-à-dire aussi bien les FAQ, cours et tutoriels en ligne, que nos membres sur les forums, permettent de trouver une solution à un problème donné.

    Nous ne pouvons en aucun cas nous porter garants d'un quelconque site extérieur au Club, pour des raisons évidentes et nombreuses : problème de la durée de vie des autres sites, de la validité des liens externes, problèmes de navigation plus ou moins lente ailleurs, du contenu technique ou moral, etc.

    Par ailleurs, lorsque vous postez une question ou une réponse sur le forum, il est indispensable, aussi bien pour des raisons d'efficacité que par respect pour le travail qu'effectue au quotidien notre équipe bénévole, de consulter ou de vous appuyer sur la base de connaissances mise à votre disposition à travers nos différents sites.
    Car c'est en travaillant à partir des ressources qui y sont proposées que nous pourrons en améliorer sans cesse le contenu et l'accessibilité.

    Developpez.com est hébergé sur un serveur dédié et de ce fait, les ressources de Developpez.com s'affichent jusqu'à 10 fois plus vite que sur les autres serveurs.
    C'est pourquoi dans l'intérêt de tous les visiteurs vous devez privilégier les liens présents sur les ressources de Developpez.com.

    90%% des liens externes deviennent morts en moins d'un an. Afin de mieux servir nos visiteurs, notre choix est donc d'héberger les ressources et non de faire des liens qui deviennent morts, et vous êtes le bienvenu pour nous aider à héberger ces ressources.

    Merci donc de privilégier soit une réponse directe, soit des références aux ressources sur Developpez.com.
    Mais je te l'accorde, ce bout de code n'a plus bcp de sens.
    Il serait intéressant de télécharger la classe, de la tester et de poster le code complet tout en citant la source. Donc, si tu t'en sens le courage...

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

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut
    Euhhhh, ben justement je vais d'abord la tester et je verrais si c'est utile de poster le code complet
    Merci de ce rappel argumenté

  15. #15
    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

    en fait puisque tu arrive a trouver les handles
    donc le nom des fenetres donc le nom de fichiers

    tu passe la variable fichier a la moulinette de find executable

    ensuite il ne te reste plus qu'a lister les applications actives

    et les mettre dans un tableau

    et u ferme tout les tableau(X) avant celle que tu veux garder

    ca c'etait pour le find executable

    ensuite
    il y a meme une autre solution en cherchant bien et meme plus simple

    puisque encore une fois tu sais trouver les handles des fenetres des fichiers ouverts

    en utilisantla combinaison de l'api "iswindowvisible" pour le rendre visible l'api "showindowA" pour les activer et les mettre en premier plan

    ensuite quand le fichier est activé et donc au premier plan tu fait
    activewindows.close


    enfin tout ca pour dire qu'il y a bien des solutions mais la derniere que tu a deniché me plait beaucoup


    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

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

    Informations forums :
    Inscription : Juin 2006
    Messages : 49
    Par défaut
    J'ai abandonné l'API PostMessageA car de temps en temps, j'avais une erreur fatale sur la tentative de fermeture d'excel.
    Du coup, voici mon code final, reprenant certaines fonctions de mon 1er post.
    Après tests, il fonctionne sur XP et Win7 32 et 64bits. Pour récupérer l'ID du processus (pid) lié à une fênetre, j'ai utilisé l'Api GetWindowThreadProcessId en passant l'handle de la fenêtre qui nous intéresse en argument.
    Les pid sont ensuite stockés dans une collection et les processus sont fermés avec la procédure KillProcess.
    Petite note, je suis obligé de stocker les pid dans une collection car si je tue le processus pendant le scan des fenêtres, ma variable hWnd retourne 0 et la boucle s'arrête.

    Je tenais à remercier les contributeurs patricktoulon et fring pour m'avoir donné les pistes nécessaires à l'écriture de ce code (qui j'espère ne comporte pas d'erreurs majeures !?! ^^)
    Un grand merci en tout cas.

    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    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 GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
    Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
    Declare Function CloseHandle Lib "Kernel32.dll" (ByVal hObject As Long) As Long
    Declare Function TerminateProcess Lib "Kernel32.dll" (ByVal hProcess As Long, ByVal dwExitCode As Long) As Long
    Const PROCESS_TERMINATE As Long = &H1
     
    Sub FermerProcessAvecFenetreInvisible(sNomFenetre As String)
    '---------------------------------------------------------------------------------------
    ' Procedure : FermerProcessAvecFenetreInvisible
    ' Date      : 16/04/2012
    ' Purpose   : Ferme les processus comportant des fenêtres cachées (testé sur XP et Win7 32bits et 64)
    ' Argument  : une partie du nom de la fenêtre (minuscule ou majuscule indifférent)
    '---------------------------------------------------------------------------------------
        Dim titre As String
        Dim hWnd As Long
        Dim pid As Long
        Dim i As Long
        Dim colPid As Collection
        Set colPid = New Collection
     
        '1ère fenêtre
        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 trouvée
                    'Récupération de l'ID du processus (pid) lié à la fenêtre
                    GetWindowThreadProcessId hWnd, pid
     
                    'Ajout du pid dans la collection
                    colPid.Add pid
                End If
            End If
            hWnd = GetWindow(hWnd, 2) 'Prochaine fenêtre
        Loop
     
        'Fermeture de tous les processus stockés dans la collection
        For i = 1 To colPid.Count
            KillProcess colPid(i)
        Next i
     
        Set colPid = Nothing
    End Sub
     
    Sub KillProcess(pid As Long)
        'Fermeture du processus
        Dim hProc As Long
        Dim Retval As Long
     
        hProc = OpenProcess(PROCESS_TERMINATE, 0, pid)
        If hProc <> 0 Then
            Retval = TerminateProcess(hProc, 0)
            ' Si Retval = 0 échec de la fonction TerminateProcess(..)
            CloseHandle hProc
        End If
    End Sub
     
    Sub test()
        'Nécessite la référence Microsoft Word x.0 Object Library
        Dim oAppWord As Word.Application, oAppWord2 As Word.Application
        Set oAppWord = CreateObject("Word.Application")
        Set oAppWord2 = CreateObject("Word.Application")
     
        oAppWord2.Visible = True 'une instance visible
        oAppWord.Visible = False 'une instance invisible
     
        MsgBox "Ouvrez le gestionnaire des tâches, une fois cliqué sur 'OK' les instances Word invisibles doivent disparaitre"
        FermerProcessAvecFenetreInvisible "microsoft word"
     
        'autre exemple
        'FermerProcessAvecFenetreInvisible "microsoft excel"
    End Sub

  17. #17
    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


    j'en etais venu au meme procédé

    boucler sur les fenetre,recupérer le handle du process dans un tabeau

    et killer tout simplement

    bravo pour ton travail mon code etait beaucoup moins propre


    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

+ 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, 11h43
  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, 17h45
  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, 18h30
  4. [VBA-A]pb ouvrir processus excel
    Par JulienCEA dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 07/02/2006, 11h50
  5. [VBA][EXCEL] GetExternalData sous Excel97
    Par Scuriolus dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 23/12/2005, 09h33

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