none
Cherche spécialiste API (coince sur fermeture après Shell) ? RRS feed

  • Question

  • Bonjour,

    J'ai un problème avec les API, j'appelle une ardresse url par un Shell, puis je ferme cette page à la fermeture du programme, c'est là que chat ne va plus comme disent les chats, deux problèmes :

    - J'ai une erreur à la fermeture, qui forcée (resume) fonctionne néanmoins.

    - Si j'ai une autre page extrne au programme d'ouverte sur le Net, ben ça ne marche plus, rien ne se ferme (peut être en rapport avec l'erreur sus-citée) ?

    - Et en question subsidiaire je suis obligé d'entrer l'adresse en dur de l'IE, or j'aimerais bien lancer l'ie, voire l'explorer par défaut sans rentrer l'adresse en dur (c:\ ...) car si jamais un jour ça chage de place, ben ... hein ?

    Voici le code qui est l'adaptation vb6 d'un exemple trouvé sur le Net :

    Option Explicit On
    Public Class Form
     Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Int32, _
      ByVal bInheritHandle As Int32, ByVal dwProcessId As Int32) As Int32
     Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Int32) As Int32
     Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Int32, _
      ByVal lpExitCode As Int32) As Int32
     Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Int32, _
      ByVal uExitCode As Int32) As Int32
     Private Declare Function SetWindowPos Lib "user32" (ByVal handle As Int32, _
      ByVal hWndInsertAfter As Int32, ByVal X As Int32, ByVal Y As Int32, ByVal cx As Int32, _
      ByVal cy As Int32, ByVal wFlags As Int32) As Int32
     Const HWND_TOPMOST = -1 ' 1er plan ecr
     Const HWND_NOTOPMOST = -2
     Const SWP_NOMOVE = 2
     Const SWP_NOSIZE = 1
     Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
     Const PROCESS_QUERY_INFORMATION = &H400 ' gestion processus
     Const PROCESS_TERMINATE = &H1
     Const STILL_ACTIVE = &H103
     Const fdwAccess = PROCESS_TERMINATE + PROCESS_QUERY_INFORMATION ' gestion appel
     Dim Iexplorer As String
     Dim url As String
     Dim hProcess As Long
     Dim RetVal As Long ' Valeur du processus
    
     Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Dim lgRet As Long
      Iexplorer = "C:\Program Files\Internet Explorer\iexplore.exe "
      url = "http://irolog.free.fr"
      lgRet = SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, FLAGS) ' ecr au dessus
      RetVal = Shell(Iexplorer & url, vbNormalFocus)
     End Sub
    
     Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
      Dim Retour As Long
      hProcess = OpenProcess(fdwAccess, False, RetVal)
      '
      On Error Resume Next ' obligé pour l'intant
      Call GetExitCodeProcess(hProcess, Retour) ' ERREUR
      ' exception System.AccessViolationException n'a pas été gérée
      ' Tentative de lecture ou d'écriture de mémoire protégée. 
      ' Cela indique souvent qu'une autre mémoire est endommagée
      ' EN FORÇANT L'ERREUR, ÇA FERME SI 1 SEULE PAGE NET LANCEE
      '
      Call TerminateProcess(hProcess, Retour)
      Call CloseHandle(hProcess)
     End Sub
    
    End Class
    

    En vous remerciant, cordialement :o)

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    mercredi 26 janvier 2011 13:28

Réponses

  • Le contrôle WebBrowser est documenté ici : http://msdn.microsoft.com/fr-fr/library/system.windows.forms.webbrowser.aspx

    Je ne sais pas d'où cela peut venir mais c'est plutôt la façon dont l'appli est "tuée" que je suspecte de finir par provoquer des problèmes. L'autre méthode que j'avais vu est l'envoi d'un message WM_QUIT via SendMessage ce qui va déclencher la même chose que lorsque l'option Quitter est appelée (y compris peut-être avec la demande de fermeture de tous les onglets si onglets il y a) ce qui permet de fermer je pense l'application plus proprement.

    Pour l'instant je dirais jette un oeil qu contrôle WebBrowser pour voir si celui ci ne serait pas plus adapté à ce que tu cherches à faire. En gros cela permet de réutiliser IE dans son appli, en prenant le contrôle de l'interface utilisateur, en pouvant naviguer par programmation, en récupérant éventuellement des évènements pour suivre ce que fait l'utilisateur.

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    vendredi 28 janvier 2011 11:39
    Modérateur

Toutes les réponses

  • Bonjour,

     

    Je viens d'essayer le code et le souci semble être réglé en utilisant  TerminateProcess(hProcess, Retour) et CloseHandle(hProcess) avant GetExitCodeProcess(hProcess, Retour).

     

    Il existe aussi un moyen plus sûr pour accéder à des chemins spécifiques, notamment pour Program Files :

    Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) & "\Internet Explorer\iexplore.exe"
    
    Cordialement,

    mercredi 26 janvier 2011 15:57
  • Bonjour,

    Pourquoi ne pas utiliser la classe Process ?

    Dim p As Process
    p = Process.Start("C:\Program Files\Internet Explorer\iexplore.exe")
    ' Arrêter le processus
    p.Kill()
    

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mercredi 26 janvier 2011 21:45
    Modérateur
  • Bonjour Gilles,

    Merci, ce code est bien, c'est mieux que les API, il reste quelques problèmes, voici le code actuel qui fonctionne, mais ... voir problème après le code :

    Option Explicit On
    Public Class Form
    
     Dim p As Process
     Dim lien As String = "http://irolog.free.fr"
     '
    
     Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Try ' si déjà fermé
       p = Process.Start("IExplore.exe", lien)
      Catch ex As Exception
       MsgBox("Mettre par défaut : Internet Explorer, remédier ... ", vbExclamation)
      End Try
     End Sub
    
     Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
      Try ' si déjà fermé
       p.Kill()
      Catch ex As Exception
    
      Finally
       p.Close()
      End Try
     End Sub
    
    End Class
    

    Je m'aperçoi (sur doc) que "IExplorer.exe" c'est suffisant (sorte de constante) ? MAIS :

    Comment faire une routine pour lui dire :

    dim navigateur as string = ???...navigateur_par_defaut
    p = Process.Start(navigateur, lien)
    
    
    

    ???

    Et comment tester les erreur lors de l'appel dans me CATCH :

    - Lien introuvable
    - Explorateur introuvable
    - Ou les deux
    

    ???

    Au plaisir, cordialement.

     

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 27 janvier 2011 09:53
  • Bonjour,

     

    Process.Start démarrera automatiquement le navigateur par défaut en spécifiant l'url à la place du chemin d'accès au navigateur :

     

    Process.start("http://www.votresite.fr")

     

    Les exceptions sont décrites via ce lien http://msdn.microsoft.com/fr-fr/library/e8zac0ca.aspx

     

    Cordialement,

    jeudi 27 janvier 2011 09:57
  • Bonjour Michel,

    Merci, toutefois je n'arrive pas trop à utiliser ces constantes 'environnement computer, par exemple :

    ' Sample for the Environment.GetFolderPath method
    Imports System
    
    Class Sample
      Public Shared Sub Main()
       Console.WriteLine()
       Console.WriteLine("GetFolderPath: {0}", Environment.GetFolderPath(Environment.SpecialFolder.System))
      End Sub 'Main
    End Class 'Sample
    '
    'This example produces the following results:
    '
    'GetFolderPath: C:\WINNT\System32
    '
    
    

    Je n'arrive pas à faire fonctionner cet exemple MicroSoft, saurais-tu m'afficher ceci, non pas en console (écran type Dos je crois), mais en form1.listbox1 ?

    Au plaisir, cordialement.

     

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 27 janvier 2011 09:59
  • Bonjour,

    Ce que j'avais vu aussi je crois comme technique est l'envoi d'un message WM_QUIT à l'application. Je pense que TerminateProcess pourrait être un peu plus "brutal".

    Personnellement je ne fermerais pas le navigateur (si l'utilisateur a réutilisé cette fenêtre de navigateur pour aller ailleurs, on va aussi fermer la fenêtre ce qui ne me parait pas très heureux).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    jeudi 27 janvier 2011 10:05
    Modérateur
  • Bonjour Patrice,

    Si si, c'est heureux, je fais un lecteur de photos de site, une visionneuse si on veut, alors c'est très spécifique, ce n'est pas prévu de toucher à l'explorateur car on commande la visualisation depuis le programme, exemple, un lien :

    http://g3/gs001/photo04.jpg

    Ben mon truc va découper ainsi : variable ... text1=(http://g) + numerik1=(3) + text2=(/gs) + numerik2=(001) + text3=(/photo) + numerik3=(04) + text4=(.jpg)

    Les "numerik" sont formatées évidemment ... Ensuite on pilote les numerik depuis le programme qui affiche via Internet.

    Le problème c'est que parfois le lien de site comportent des variable alphabétique, là je laisse car c'est difficile à identifier, idem, parfois il y a des trous où rien ne s'affiche, faudrait que je trouve à capter un retour d'erreur de l'explorer afin de faire + ou - 1 un certain temps, ou jusqu'à plus d'erreur (nouvelle photo). Cette visionneuse de contenu de lien je l'avais fais en vb6, je refais en mieux en vbNet.

    http://irolog.free.fr/gratuit.htm

    4 eme ligne : fureteur de site web.

    Cordialement.



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 27 janvier 2011 10:30
  • Bonjour bis Michel,

    Oui, ça démarre avec l'explorer par défaut, mais ça ne se ferme ps dans ce cas, voici le code :

    Option Explicit On
    Public Class Form
     Dim p As Process
    
     Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Dim lien As String = "http://irolog.free.fr"
      p = Process.Start(lien)
     End Sub
    
     Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
      Try
       p.Kill()
      Catch ex As Exception
      End Try
     End Sub
    
    End Class
    
    

    Cordialement.



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 27 janvier 2011 11:21
  • Selon le degré de contrôle que l'on veut il est aussi possible d'utiliser le contrôle WebBrowser (basé sur IE). Sinon il existe également d'autres moteurs de rendu qui peuvent éventuellement être incorporés dans l'appli.

    Pour l'instant, sauf erreur de ma part le lancement via Process.Start directement sur une URL lance le navigateur avec son interface complète et rien n'empêche l'utilsiateur d'aller ensuite où bon lui semble ?

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    jeudi 27 janvier 2011 11:37
    Modérateur
  • Patrice,

    Oui, tu as raison, l'utilisareur peut aller où il veut ensuite, ce qui est son problème, ça ne trouble point le logiciel, qui à chaque lien appelé ferme (s'il trouve) la page ouverte précédemment et en ouvre une autre. Donc ça ne trouble aucunement le logiciel, qui quand on va faire par exemple +1 sur la valeul 2 du lien, ben il va fermer ce qui a été ouvert avant (avec gestion d'erreur s'il ne trouve pas), puis ouvrir au nouveau lien, et ça marchera, l'utilisateur peut par ailleur aller sur d'autre site, faire autre chose en même temps, encore heureux :o)

    Oui je connais webBrowser mais je l'ai peu utilisé en vb6, je ne le manipule pas trop bien, voire assez mal, faudrait que je regarde de ce côté en effet, car j'aurais la gestion des erreurs qui manque un peu, et je pourrais aussi faire des défilement automatique sur une valeur du lien tant que erreur et jusqu'à (à déterminer), je vais voir...

    Cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 27 janvier 2011 12:37
  • Bonjour Joseph,

    La meilleure solution serait bel et bien d'utiliser le contrôle webbrowser.

    Rien n'est particulièrement difficile et il semble correspondre sans souci à vos attentes :

    Webbrowser.Navigate("lien") permettra d'atteindre directement le lien voulu. La page sera uniquement actualisée à chaque fois, le tout se fermera en même temps que le programme et par dessus tout il est facile de gérer les erreurs. Je pense même que l'interface en sera que plus agréable au lieu de devoir changer de fenêtre à chaque fois.

    N'hésitez pas à demander de l'aide si les exemples fournis par Microsoft ne sont pas suffisants

    Cordialement.

    jeudi 27 janvier 2011 15:30
  • Bonsoir Michel,

    Merci, en effet je fais un "explorer" le : "Joseph Explorer" :o)

    Le problème ce n'est pas les commandes généralistes, genre appel ou back mais davantage savoir quand il a trouvé, quand il n'a pas trouvé, quand il chercher, je ne sais pas récupérer ces trois évènements ?

    Avec la commande start je viens d'avoir un plantage magistral ! Fenêtre bleue, ça a trop empilé sans dépiler, ou y'a un segemnt RAM qui a voulu en bouffer un autre, voire les deux, je ne sais pas ; bref, avec cette méthode telle que je l'emploie ça ne referme pas ... heu ... "l'instance de l'appel ?" ... Alors qu'avec Shell ou Shellexecute ça tournait rond, j'espère qu'avec le browser ça va tourner rond aussi, qu'il ferme comme un grand tout seul les appel qu'on lui passe quand un second arrive ?

    Alors si tu connais les commandes détat du Browser ("trouvé", pas "trouvé" et "on chercher") je suis toutes ouïes, enfin, tout yeux :o)

    Au plaisir, cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 27 janvier 2011 20:55
  • Bonjour Gilles,

    Tu as mon code en dessous, en fait au bout d'une sacrée utilisation j'ai eu un plantage, écran bleu, genre débordement de pile ou tentative de débordement de segment RAM ?

    A priori la méthode (tel que j'ai écrit le code) n'est pas bonne car "l'instance" qui lance une requête de lien sur le Web, n'est ensuite pas refermée, faut que je vois ça en testant l'état de la chose, si j'y arrive, en tout cas merci, cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 27 janvier 2011 20:59
  • Bonsoir Patrice,

    C'est encore moi au rapport, en fait je viens de faire un browser, je vais voir si ça marche mieux avec, il reste trois commande que je ne connais pas pour mes besoins, sais-tu comment tester (exemple de code), comment tester donc :

    - "Trouvé", "pas trouvé" et "recherche en cours", que je puisse gérer un peu plus finement, j'ai emandé à Michel la même chose in fine ?

    Pour info, par contre avec Start, mon code ne doit pas être au point, car au bout d'un temps assez long, peut être 80, 90 appels de liens, ça m'a fait un plantage écran bleu de protection de l'OS, genre dépassement de pile ou débordement de segment RAM, a priori les instances web appelées ne sont pas refermées (je présume), faudra que je vois, mais si le webrowser toure rond (qu'il referme lui même un appel de lien sur un nouvel appel) je vais laisser tomber la méthode start (shell, shellexecute marchaient mieux) ...

    Cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 27 janvier 2011 21:06
  • Le contrôle WebBrowser est documenté ici : http://msdn.microsoft.com/fr-fr/library/system.windows.forms.webbrowser.aspx

    Je ne sais pas d'où cela peut venir mais c'est plutôt la façon dont l'appli est "tuée" que je suspecte de finir par provoquer des problèmes. L'autre méthode que j'avais vu est l'envoi d'un message WM_QUIT via SendMessage ce qui va déclencher la même chose que lorsque l'option Quitter est appelée (y compris peut-être avec la demande de fermeture de tous les onglets si onglets il y a) ce qui permet de fermer je pense l'application plus proprement.

    Pour l'instant je dirais jette un oeil qu contrôle WebBrowser pour voir si celui ci ne serait pas plus adapté à ce que tu cherches à faire. En gros cela permet de réutiliser IE dans son appli, en prenant le contrôle de l'interface utilisateur, en pouvant naviguer par programmation, en récupérant éventuellement des évènements pour suivre ce que fait l'utilisateur.

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    vendredi 28 janvier 2011 11:39
    Modérateur
  • Merci :o)

    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    vendredi 28 janvier 2011 13:16
  • Bonjour, Je voudrai juste rajouter qu'au lieu de faire un p.Kill() ou peut aussi faire un p.CloseMainWindow() qui est beaucoup plus propre... Cela pourra très certainement servir à d'autre.
    vendredi 18 février 2011 15:25