none
La méthode Process.Start() génère une exception de type Windows32Exception - Access is denied RRS feed

  • Question

  • Problème

    Lorsqu'un utilisateur double-clique sur un objet (thumbnail d'une image) sur une Windows Form, j'appelle la méthode Process.Start(processStartInfo) avec uniquement le nom du fichier spécifié dans l'objet "ProcessStartInfo". Grâce à l'association des fichiers Windows, Windows Server 2008 ouvre l'application "Windows Photo Gallery" et affiche l'image en taille réel.

    À ce stade, tout fonctionne parfaitement bien. Par contre, tous nos utilisateurs sont connectés à notre application via une session Terminal Server. Les problèmes commencent lorsqu'un utilisateur minimise "Windows Photo Gallery", qui a été ouvert par l'appel de Process.Start et dépasse le délai d'inactivité de Terminal Server. À ce moment, la session est terminé, mais le processus semble lancer une erreur, ce qui démarre le processus "wermgr.exe" (Windows Error Reporting Manager) dans "Windows Task Manager". Ce processus ne se termine jamais automatiquement.

    À partir de ce moment, aucun autre utilisateur n'est capable de double-cliquer sur un thumbnail (objet) afin que celui-ci appelle la méthode Process.Start correctement. En fait, la méthode est bel et bien appelé, mais elle lève automatiquement une exception de type "Windows32Exception - Access is denied". On dirait que Windows Server n'est plus capable d'ouvrir ou d'afficher correctement "Windows Photo Gallery", car il est en train d'envoyer une erreur via le processus "wermgr.exe".

    Tout ce que j'ai trouvé à faire pour l'instant est de me connecter à distance chez mon client, d'ouvrir "Windows Task Manager", de tuer le processus "wermgr.exe", me connecter sur la session qui a généré le problème (car le processus wermrg.exe est ouvert pour la session qui a créé le problème) et fermer "Windows Photo Gallery". Une fois tout ceci fait, l'application fonctionne à nouveau et les utilisateurs sont en mesure de double-cliquer sur un thumbnail pour ouvrir "Windows Photo Gallery" et afficher l'image en taille réel.

    Voici le code utilisé :

     

    Try

     

    Dim psiAsNew Diagnostics.ProcessStartInfo(fileName)

     

    Dim procAsNew Diagnostics.Process

    psi.WindowStyle = ProcessWindowStyle.Normal

    proc = Diagnostics.Process.Start(psi)

     

    'Il est possible que proc = Nothing s'il existait dj avant d'appeler la mthode .Start

     

    IfNot procIsNothingThen

    proc.WaitForExit()

     

    EndIf

     

    Catch exAs ObjectDisposedException

    Librairie.MsgBoxes.MessageErreur(

    "Le processus a dj t dispos.{0}{0}{1}","The process object has already been disposed.{0}{0}{1}", vbCrLf.ToString, ex.Message)

     

    Catch exAs InvalidOperationException

    Librairie.MsgBoxes.MessageErreur(

    "Une exception en raison d'une opration invalide a t leve.{0}{0}{1}","An error because of an invalid operation has been raised.{0}{0}{1}", vbCrLf.ToString, ex.Message)

     

    Catch exAs System.ComponentModel.Win32Exception

     

    Dim baseExAs Exception = ex.GetBaseException

     

    Dim messDetailAsString ="Message : {1}{0}" & _

     

    "Base exc. message : {6}{0}" & _

     

    "Error code : {2}{0}" & _

     

    "Native error code : {3}{0}" & _

     

    "Source : {5}{0}" & _

     

    "Stack trace : {4}"

     

    Dim messFraAsString ="Une erreur est survenue lors de l'ouverture du fichier.{0}{0}" & messDetail

     

    Dim messAngAsString ="An error has occured while opening the file.{0}{0}" & messDetail

    Librairie.MsgBoxes.MessageErreur(messFra, messAng, vbCrLf.ToString, ex.Message, ex.ErrorCode, ex.NativeErrorCode, ex.StackTrace, ex.Source, baseEx.Message)

     

    Catch exAs Exception

    Librairie.MsgBoxes.MessageErreur(

    "Une erreur inconnue est survenue.{0}{0}{1}","An unknown error has occured.{0}{0}{1}", vbCrLf.ToString, ex.Message)

     

    EndTry

    Notre application a été développé sous Visual Studio 2005 et nous utilisons le framework 2.0. Tel que mentionné précédemment, toutes les sessions utilisateurs roulent sous un serveur Windows Server 2008 via une connection Terminal Server.

    Dans mes expériences passées, j'avais déjà réussi à "trappé" la fermeture d'une session Terminal Server à partir de notre application .Net, mais c'était relativement compliqué. Existe-t-il une solution plus simple afin que tout fonctionne correctement ??

    vendredi 16 avril 2010 14:11

Toutes les réponses

  • Bonjour,

    dans votre code vous utilisez la méthode WaitForExit après avoir lancé le process. Avez vous essayé sans cette méthode afin de repasser la main à l'application .Net après avoir lancé Windows Photo Gallery ? Sinon pour quelle raison souhaitez vous bloquer l'exécution ?

    Cordialement

    lundi 19 avril 2010 12:21
    Modérateur
  • En fait, j'ai fait plusieurs tests chez le client avec des versions différentes de ce bout de code. Dans certains tests, je n'appelais pas la méthode "WaitForExit", mais je finissais tout de même par avoir le même problème à long terme. Exactement le même problème survenait, soit qu'en bout de ligne l'appelle de la méthode "Start" lançait systématiquement une exception  de type "Win32Exception".

    De plus, une fois que le processus aïe été lancé une 1ère fois, l'appelle de la méthode .Start retournait un pointeur "Nothing" étant donné que le processus était déjà existant tel que discuté dans la documentation .Net. Donc, la mtéhode "WaitForExit" n'était jamais appelé dans le code ci-dessous :

    If Not Proc Is Nothing Then

       proc.WaitForExit()

    End If

     

    Afin de trouver la solution à ce problème, je peux bien réessayer encore une fois de simplement commenter la portion "WaitForExit", qui peut être appelé à la 1er appelle de Process.Start. Par contre, au stade actuel et avec les expériences tentées, je crois que le problème ce situe ailleurs.

    Merci !

    lundi 19 avril 2010 13:07
  • Bonjour,

     

    Le problème ne semble pas venir du façon de démarrage du processus dans Process.Start(), mais du Terminal Server et son interaction avec votre application. Avez-vous essayé de gérer la durée de vie de l’application pour être sure qu’elle ne dépasse pas la période d’inactivité de Terminal Server ?

     

    Cordialement,

    Alex


    Appel à contribution ! http://social.msdn.microsoft.com/Forums/fr-FR/vbasicfr/thread/ff4910bf-dca4-4664-b01e-b58bd860a643
    mardi 20 avril 2010 09:39
  • Bonjour Alex,

    Je crois moi aussi que le problème est dû à Terminal Server. Votre solution semble un bon "work-around". J'avais déjà également pensé à "handler" la fermeture de la session Terminal Server au niveau de notre application et effectuer une fermeture "propre" de notre application. Ceci peut être fait relativement facilement en gérant l'évenement "Form.WndProc".

    Cet méthode reçoit uniquement un paramètre "byref m as system.windows.forms.message") et il est alors possible de vérifier si m.msg = Constante (WMs.WMTSSESSION_CHANGE) et ensuite évaluer m.WParam.ToInt32 pour voir le type d'événement lancé par Terminal Server. En fait, à la création de notre application, nous pouvons enregistrer Terminal Server pour détecter les interactions entre TS et notre application.

    Voici les événements que nous pouvons détecter :

    Select

     

    Case m.WParam.ToInt32

     

    Case WTs.WTS_CONSOLE_CONNECT : Me.OnConsoleConnect() '1

     

    Case WTs.WTS_CONSOLE_DISCONNECT : Me.OnConsoleDisconnect() '2

     

    Case WTs.WTS_REMOTE_CONNECT : Me.OnRemoteConnect() '3

     

    Case WTs.WTS_REMOTE_DISCONNECT : Me.OnRemoteDisconnect() '4

     

    Case WTs.WTS_SESSION_LOGON : Me.OnSessionLogOn() '5

     

    Case WTs.WTS_SESSION_LOGOFF : Me.OnSessionLogOff() '6

     

    Case WTs.WTS_SESSION_LOCK : Me.OnSessionLock() '7

     

    Case WTs.WTS_SESSION_UNLOCK : Me.OnSessionUnLock() '8

     

    Case WTs.WTS_SESSION_REMOTE_CONTROL : Me.OnSessionRemoteControl() '9

     

    End Select

     

    ElseIf m.Msg = WMs.WM_DESTROY Then

    Après plusieurs tests, je suis capable de "trapper" la majorité de ces événements, mais certaines ne sont jamais géré, tel que "SESSION_LOGOFF". Nous sommes capable de gérer une fermeture dû à un time-out, mais pas un log-off normal. Du moins, je n'ai jamais réussi à le "trapper".

    Donc, pour cette raison, j'aimerais tenter le plus possible de ne pas "trapper" les événements TS, mais bien si possible mieux gérer les processus à partir de mon application. J'aimerais comprendre pourquoi le processus semble être "gelé" et ne plus répondre. D'après ma compréhension, il semble être dans l'attente du processus "wermgr.exe" ou "wercon.exe" qui est lancé une fois que le processus pour l'affichage de l'image "plante" en raison de la fermeture de la session TS. Est-ce qu'il y a un autre moyen de relancer le processus sans avoir à s'occuper de TS.

    De plus, j'aimerais le plus possible de ne pas faire d'appelle de processus directement par leur nom. Ça me semble un peu trop "hard coded". Il est important de rappeler que j'appelle la méthode process.start avec un objet de type processStartInfo où seul le nom du fichier de l'image est spécifié, afin que windows ouvre le programme par défaut selon les associations système.

    Merci beaucoup !

    mardi 20 avril 2010 13:39
  • Bonjour,

     

    Votre problème est assez compliqué, et il me semble difficile à faire une analyse sur ce forum sans avoir accès à votre système. J’ai cherché de la documentation qui pourrait traiter ces sujets mais, malheureusement, ce sont des choses particulières et la documentation ne couvre pas tous les cas.

     

    Comme dernière tentative, je vous conseille de fermer Windows Error Reporting Service et peut-être wermgr.exe et wercon.exe ne seront plus lancés.

     

    Cordialement,

    Alex


    Appel à contribution ! http://social.msdn.microsoft.com/Forums/fr-FR/vbasicfr/thread/bd974e0e-5519-4122-b8fc-3b998207c34f
    mercredi 21 avril 2010 10:01