Masquer les messages d'erreur Windows AU SECOURS !!!!

gerbito Messages postés 39 Date d'inscription mardi 14 décembre 2004 Statut Membre Dernière intervention 20 octobre 2015 - 4 juin 2008 à 18:04
gerbito Messages postés 39 Date d'inscription mardi 14 décembre 2004 Statut Membre Dernière intervention 20 octobre 2015 - 5 juin 2008 à 14:55
Bonjour,

   Quelqu'un connaîtraît-il une méthode valable pour masquer les messages d'erreur Windows ?

   En effet j'ai une appli développée en C# dont le graphisme est pollué par l'apparition d'un message d'erreur
"svchost.exe Application Error L'instruction à l'adresse 0x77c43dbd référence l'adresse 0x90909090 la mémoire ne peut pas être écrite"

   Après avoir passé 2 semaines à essayer de résoudre cette erreur en vain, le seul recours qui me reste est d'essayer de la mettre "sous le tapis", et pour cela il faudrait éviter que cette boîte grise n'apparaisse DEVANT le formulaire de mon appli.

   J'ai mis la TopMost de la form à vrai, je l'affiche avec la méthode ShowDialog et pourtant rien n'y fait.

Ce serait excellent si quelqu'un connaissait la réponse...

Merci !

4 réponses

Liverion Messages postés 296 Date d'inscription mardi 22 avril 2008 Statut Membre Dernière intervention 18 août 2008
5 juin 2008 à 10:07
Salut,
Euh pour ma part ca fait très moche de camoufler une fenetre d'erreur ^^
En plus je crois que les fenetres d'erreur sont modales non ? Tu pourras pas utiliser ta form tant que tu n'auras pas cliquer sur l'erreur.
Sinon tu peux toujours afficher ton code, peut etre que des personnes pourront t'aider à resoudre ton problème.
Bonne chance ;)

~~~~~~~~~~
Les trois lois de Codes-Sources :
1) Tu lis et respecte le reglement
2) Tu pense a valider si une reponse apportée a ton probleme t'a aidé
3) Si tu ne respecte pas les 2 premières ....TU SORS !!!
~~~~~~~~
0
gerbito Messages postés 39 Date d'inscription mardi 14 décembre 2004 Statut Membre Dernière intervention 20 octobre 2015
5 juin 2008 à 13:31
Bonjour,

Il est clair que ce n'est pas très joli de masquer des fenêtres d'erreur, mais si tu as une meilleure solution, elle est bienvenue. L'erreur ne vient pas de mon appli mais de svchost, il m'est impossible de la détecter avec des gestionnaires d'exception, cela fait plus de 2 semaines que je m'acharne à déterminer la cause de cette erreur, et il ne reste plus de temps à passer dessus, donc sachant que l'erreur ne bloque pas le fonctionnement de mon appli tant qu'on ne clique pas sur le "OK" de la boîte grise, j'essaie de parer au plus pressé et donc de la faire passer "sous le tapis".

J'avais déjà posé une question dans une autre partie du forum à propos de ce problème. Il m'avait alors été répondu que le problème pouvait venir de l'utilistion par une DLL native d'un pointeur transmis par mon appli C# et supprimé par le ramasse-miettes, ou d'une mauvaise utilisation du Marshal pour formater les variables à transmettre. Mon appli utilise en effet l'API Ras.

Plus loin la classe que j'ai amélioré pour empêcher le ramasse-miettes de buter mes variables dans mon dos. C'est fait un peu à l'arrache, tout est dans la même méthode (située à la fin) qui fait tout et dont les dernières instructions ordonnent au ramasse-miettes de ne pas toucher à mes variables. Auparavant j'utilisais une classe avec une connexion Ras asynchrone et le passage d'un délégué de traitement des messages de statut de la connexion Ras, mais le seul moyen d'utiliser GC.KeepAlive c'était à l'intérieur d'une même méthode, voilà pourquoi j'ai tout mis dans la même méthode, avec des principes de codage qui pourront paraître sales (goto...). L'interface MBTClient est dérivée par mon composant qui contient le Socket Tcp. Malgré tous mes efforts, ca plante encore.

Pour décrire sommairement l'appli, c'est une appli dont l'affichage graphique dépend de données reçues en permanence d'un serveur via une liaison par modem GPRS et protocole Tcp. L'appli doit pouvoir tourner sans discontinuer pendant plusieurs mois. Pour éviter ce problème de svchost, j'ai pensé aussi à :
-> injecter une méthode du style : void faitRien() {;} en lieu et place de la fonction système qui affiche les boîte grise (ca doit etre faisable)
->mettre svchost sous surveillance (apparement pas possible)
->Abandonner l'API Ras et utiliser un client Port série pour causer directement au modem et reproduire le protocole Tcp dans ce client port série (j'avais déjà commencé à m'y intéresser, mais pas assez de temps pour le faire)

Mais si quelqu'un pense pouvoir m'aider en regardant mon code utilisant l'API Ras :

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Runtime.InteropServices;

using System.Threading;

using System.Diagnostics;

using XPe_Win32;

namespace XPe_Ras

{

public static class RasSimple

{

public interface MBTClient

{

bool Connecte();

void Deconnecte();

void Erreur();

string RasName { get; }

string RasPseudo { get;}

string RasMdp { get;}

bool Ecoute { get;}

}

#region Structures

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

public struct RASCONN

{

public uint dwSize;

public IntPtr hrasconn;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (RAS_MaxEntryName + 1))]

public string szEntryName;

}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

unsafe public struct RASDIALEXTENSIONS

{

public uint dwSize;

public uint dwfOptions;

public IntPtr hwndParent;

public uint reserved;

}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

unsafe public struct RASDIALPARAMS

{

public uint dwSize;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName + 1)]

public string szEntryName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxPhoneNumber + 1)]

public string szPhoneNumber;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxCallbackNumber + 1)]

public string szCallbackNumber;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = UNLEN + 1)]

public string szUserName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = PWLEN + 1)]

public string szPassword;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = DNLEN + 1)]

public string szDomain;

}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

unsafe public struct RASENTRYNAME

{

public uint dwSize;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RAS_MaxEntryName + 1)]

public string szEntryName;

}

#endregion

#region Constants

private const int MAX_PATH = 260;

private const int DNLEN = 15;

internal const int ERROR_INVALID_HANDLE = RASBASE + 1;

private const int PWLEN = 256;

private const int RAS_MaxAreaCode = 10;

private const int RAS_MaxCallbackNumber = 48;

private const int RAS_MaxDeviceName = 32;

private const int RAS_MaxDeviceType = 16;

private const int RAS_MaxEntryName = 20;

private const int RAS_MaxFacilities = 200;

private const int RAS_MaxIpAddress = 15;

private const int RAS_MaxIpxAddress = 21;

private const int RAS_MaxPadType = 32;

private const int RAS_MaxParamKey = 32;

private const int RAS_MaxParamValue = 128;

private const int RAS_MaxPhoneNumber = 128;

private const int RAS_MaxUserData = 200;

private const int RAS_MaxX25Address = 200;

internal const int RASBASE = 600;

private const int RASCS_DONE = 0x2000;

private const int RASCS_PAUSED = 0x1000;

private const int RASCF_AllUsers = 1;

private const int RASCF_GlobalCreds = 2;

private const int REN_AllUsers = 1;

private const int UNLEN = 256;

internal const int WM_RASDIALEVENT = 0xCCCD;

private const int ATTENTE_EVTS = 1000;

private const int PAUSE_EVTS = 100;

private const uint RASCN_Disconnection = 2;

#endregion

#region Imports Dll

[DllImport("rasapi32.dll", SetLastError = true, EntryPoint = "RasDialW")]

public static extern uint RasDialW([In] ref RASDIALEXTENSIONS lpRasDialExtensions,[In] IntPtr lpszPhoneBook,

[In] ref RASDIALPARAMS lpRasDialParams,[In] uint dwNotifierType,[In] IntPtr lpNotifier,[In, Out] ref IntPtr lphRasConn);

[DllImport("rasapi32.dll", SetLastError=true, EntryPoint="RasEnumConnectionsW")]

public static extern uint RasEnumConnections([In, Out] RASCONN[] lprasconn,[In, Out] ref uint lpcb,[Out] out uint lpcConnections);

[DllImport("rasapi32.dll", SetLastError=true, EntryPoint="RasEnumEntriesW")]

public static extern uint RasEnumEntries([In] IntPtr reserved,[In] IntPtr lpszPhoneBookPath,[In,Out] RASENTRYNAME[] lprasentryname,[In,Out] ref uint lpcb,[Out] out uint lpcEntries);

[DllImport("rasapi32.dll", CharSet = CharSet.Auto)]

public static extern uint RasHangUp(IntPtr hRasConn);

[DllImport("rasapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]

public static extern uint RasConnectionNotification([In] IntPtr hrasconn,[In] IntPtr hEvent,[In] uint dwFlags);

[DllImport("kernel32.dll", SetLastError = true, EntryPoint = "CreateEventW")]

public static extern IntPtr CreateEvent([In] IntPtr lpEventAttributes, [In] bool bManualReset, [In] bool bInitialState, [In] string lpName);

[DllImport("kernel32.dll", SetLastError = true)]

public static extern uint WaitForSingleObject(IntPtr handle, uint milliseconds);

[DllImport("kernel32.dll", SetLastError = true)]

public static extern bool CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll", SetLastError = true)]

public static extern void Sleep(uint dwMilliseconds);

#endregion



public static void EcouteRasSure(MBTClient mbt)

{

Thread t = new Thread(new ParameterizedThreadStart(Ras));

t.Start((object)mbt);

}

private static void Ras(object o)

{

unsafe

{

MBTClient mbt = (MBTClient)o;

string nomRas = mbt.RasName;

IntPtr hdleRas = IntPtr.Zero;

IntPtr evtDisc = IntPtr.Zero;

List poubellePtr = new List();

RASCONN[] rasConnTest = new RASCONN[1];

RASCONN[] rasConnsToutes = null;

RASENTRYNAME[] rasEntryTest = new RASENTRYNAME[1];

RASENTRYNAME[] rasEntryToutes = null;

RASDIALPARAMS dialParams = new RASDIALPARAMS();

RASDIALEXTENSIONS dialExt = new RASDIALEXTENSIONS();

uint cbC = (uint)Marshal.SizeOf(typeof(RASCONN)),

cbE = (uint)Marshal.SizeOf(typeof(RASENTRYNAME)),

nbEntries = 0,

nbRasConn = 0,

ret = 0;

int i;

//Initialisation des paramètres d'appel

dialParams.dwSize = (uint)Marshal.SizeOf(typeof(RASDIALPARAMS));

dialParams.szEntryName = nomRas;

dialParams.szCallbackNumber = null;

dialParams.szDomain = "";

dialParams.szPhoneNumber = null;

dialParams.szPassword = mbt.RasMdp;

dialParams.szUserName = mbt.RasPseudo;

//Initialisation des extensions d'appel

dialExt.dwSize = (uint)Marshal.SizeOf(typeof(RASDIALEXTENSIONS));

dialExt.dwfOptions = 0;

dialExt.hwndParent = IntPtr.Zero;

dialExt.reserved = 0;

//Test l'existence de l'entrée choisie

rasEntryTest.Initialize();

rasEntryTest[0].dwSize = cbE;

// Teste la version de la structure passée en paramètre (si ret=0 la version est bonne, fausse sinon)

ret = RasEnumEntries(IntPtr.Zero, IntPtr.Zero, rasEntryTest, ref cbE, out nbEntries);

if (ret != 0)

{

TraceExecution.NoteErreur(ret, "RasEnumEntries");

mbt.Erreur();

goto fin;

}

if (nbEntries == 0)

{

TraceExecution.NoteAlerte("Aucune entrée RAS détectée");

mbt.Erreur();

goto fin;

}

// Ajustement du nombre d'entrées RAS

rasEntryToutes = new RASENTRYNAME[nbEntries];

for (i = 0; i < nbEntries; i++)

rasEntryToutes[i].dwSize = (uint)Marshal.SizeOf(typeof(RASENTRYNAME));

// Récupère les entrées RAS

ret = RasEnumEntries(IntPtr.Zero, IntPtr.Zero, rasEntryToutes, ref cbE, out nbEntries);

if (ret != 0)

{

TraceExecution.NoteErreur(ret, "RasEnumEntries");

mbt.Erreur();

goto fin;

}

//Recheche si l'entrée voulue existe

for (i = 0; i < rasEntryToutes.Length && rasEntryToutes[i].szEntryName != nomRas; i++) ;

if (i == rasEntryToutes.Length)

{

TraceExecution.NoteAlerte("L'entrée RAS " + nomRas + " n'existe pas");

mbt.Erreur();

goto fin;

}

//Test la connexion

rasConnTest.Initialize();

rasConnTest[0].dwSize = cbC;

// Teste la version de la structure passée en paramètre (si ret=0 la version est bonne, fausse sinon)

ret = RasEnumConnections(rasConnTest, ref cbC, out nbRasConn);

if (ret != 0)

{

TraceExecution.NoteErreur(ret, "RasEnumConnections");

mbt.Erreur();

goto fin;

}

if (nbRasConn != 0)

{

// Ajustement du nombre de connections RAS actives

rasConnsToutes = new RASCONN[nbRasConn];

for (i = 0; i < nbRasConn; i++)

rasConnsToutes[i].dwSize = (uint)Marshal.SizeOf(typeof(RASCONN));

// Recherche si l'entrée voulue est active

ret = RasEnumConnections(rasConnsToutes, ref cbC, out nbRasConn);

if (ret != 0)

{

TraceExecution.NoteErreur(ret, "RasEnumConnections");

mbt.Erreur();

goto fin;

}

for (i = 0; i < rasConnsToutes.Length && rasConnsToutes[i].szEntryName != nomRas; i++) ;

if (i < rasConnsToutes.Length)

{

TraceExecution.NoteInfo("La connexion " + nomRas + " est déjà active");

goto connexion;

}

}

appel:

TraceExecution.NoteInfo("Appel de la connexion " + nomRas);

for (i = 0; i < 5000; i++)

{

ret = RasDialW(ref dialExt, IntPtr.Zero, ref dialParams, 1, IntPtr.Zero, ref hdleRas);

if (ret == 0) goto connexion;

if (!mbt.Ecoute) goto fin;

TraceExecution.NoteErreur(ret, "RasDial");

Kernel32.Sleep(PAUSE_EVTS);

}

TraceExecution.NoteAlerte("Echec de la connexion RAS");

mbt.Erreur();

goto fin;

connexion:

mbt.Connecte();

TraceExecution.NoteInfo("Création de l'évènement");

evtDisc = Kernel32.CreateEvent(IntPtr.Zero, false, false, null);

for (i = 0; i < 100; i++)

{

ret = RasConnectionNotification(hdleRas, evtDisc, RASCN_Disconnection);

if (ret == 0) goto attente;

TraceExecution.NoteErreur(ret, "RasConnectionNotification");

Kernel32.Sleep(PAUSE_EVTS);

}

attente:

do

{

ret = Kernel32.WaitForSingleObject(evtDisc, ATTENTE_EVTS);

Kernel32.Sleep(PAUSE_EVTS);

if (!mbt.Ecoute) goto deconnexion;

} while (ret != 0);

TraceExecution.NoteInfo("Déclenchement de l'évènement déconnexion");

mbt.Deconnecte();

poubellePtr.Add(evtDisc);

poubellePtr.Add(hdleRas);

hdleRas = IntPtr.Zero;

if (mbt.Ecoute) goto appel;

goto fin;

deconnexion:

Kernel32.CloseHandle(evtDisc);

for (i = 0; i < 100; i++){

ret = RasHangUp(hdleRas);

if (ret == 0) goto fin;

TraceExecution.NoteErreur(ret, "RasHangUp");

}

TraceExecution.NoteAlerte("Erreur dans la fermeture de la connexion");

fin:

GC.KeepAlive(mbt);

GC.KeepAlive(nomRas);

GC.KeepAlive(dialExt);

GC.KeepAlive(dialParams);

GC.KeepAlive(hdleRas);

GC.KeepAlive(evtDisc);

GC.KeepAlive(poubellePtr);

GC.KeepAlive(rasConnTest);

GC.KeepAlive(rasConnsToutes);

GC.KeepAlive(rasEntryTest);

GC.KeepAlive(rasEntryToutes);

GC.KeepAlive(cbE);

GC.KeepAlive(cbC);

GC.KeepAlive(nbRasConn);

poubellePtr.Clear();

}}
0
Nikoui Messages postés 794 Date d'inscription vendredi 24 septembre 2004 Statut Membre Dernière intervention 19 août 2008 13
5 juin 2008 à 13:48
Je ne suis pas sur du tout que tu puisses arriver à masquer les boites d'erreur modale (et ce n'est pas une vrai solution à ton problème de toute façon).

Dans ton cas (pas simple), ce que je ferai (dans l'ordre):
- Etre sur que le problème ne vient pas de ton code
- Si le problème vient d'une librairie tierce, voir avec les personnes à l'origine de cette librairie (est ce un bug connu ? est il possible/prévu de le corriger ? quand? etc)
- Si pas de support de fournit sur cette librairie : est ce qu'il est possible d'en récupérer les sources et corriger toi même le bug ?
- Si tout ça n'est pas possible : changer de librairie
- Si pas de librairie équivalente -> faire autrement ou en développer une soi même.

Masquer l'erreur ne peut être (à mon avis) qu'une solution temporaire...

<hr size="2" width="100%" />
Working as designed
www.nikoui.fr
0
gerbito Messages postés 39 Date d'inscription mardi 14 décembre 2004 Statut Membre Dernière intervention 20 octobre 2015
5 juin 2008 à 14:55
Tout d'abord, merci aux personnes qui m'ont répondu.

J'ai longuement vérifié le code utilisé précédemment qui comme je le disais était plus "propre" avec utilisation d'une vrai classe, des méthodes plus petites, des délégués de rappel.

Supposant que le problème venait de la suppression par le GC de pointeurs transmis à la dll Ras, j'ai fait, dans l'ordre, les modifs de code suivantes :

->Tentative de passer toutes les variables transmises à l'API en statique dans la classe alors utilisée : aucun effet

->Tentative de créer un projet en C++ natif pour utiliser la dll Ras, avec un autre projet en C++ .Net managé utilisable directement depuis C# et utilisant cette ma dll native : Peine perdue, dans mon projet natif j'incluais pourtant le ras.h et utilisais directement ses structures, mais la méthode RasDial me renvoyait une erreur au motif que la taile de la structure déclarée dans ras.h était mauvaise, apparement à cause d'un #ifdef WINVER >= 0x500 qui rajoute 2 variables superflues dans la structure RasDialParams. J'ai alors essayé de mettre "#define WINVER 0x4ee" avant l'inclusion de ras.h, mais je me ramassais une erreur de compilation à cause de la structure jugée du coup trop petite. J'ai dû renoncer à cette option.

->Enfin, j'ai refait le code tel que vous pouvez le voir, tout dans une seule méthode encapsulée dans un thread, connexion synchrone sans délégué essayée 5000 fois avant de déclarer la connexion inutilisable, et utilisation de la méthode GC.KeepAlive sur toutes les variables transmises à la dll interdisant
leur ramassage par le GC depuis le début de la méthode jusqu'à l'appel de cette méthode KeepAlive (enfin c'est ce qui est dit dans msdn). Résultat : idem que précédemment, erreur dans svchost.exe.

Je me suis documenté sur l'API Ras (c'est pas facile de trouver de la doc francophone sur le sujet), le PInvoke, le Marshall de structures. J'ai appliqué toutes les recommandations que j'ai pu trouver à ce propos, pour chaque fois un résultat inchangé.

Les sources de l'API Ras sont apparemment indisponibles, donc aucun moyen de savoir ce qui se trame derrière tout ceci, à moins de pouvoir décompiler ce truc, mais de toutes façons je n'y connais rien en assembleur.

Sinon, ce qui me pousse à incriminer l'API Ras dans l'apparition de cette erreur, c'est le fait que svchost s'occuppe apparemment des connexions réseau sur un ordi, ainsi que de l'utilisation de dll. Toutes les autres libraries que j'utilise sont intégrées à mon projet, elles ont été codées en C#, blindées de try..catch, et elles ont été testées et retestées par d'autres développeurs.

Lorsque je me suis documenté sur les erreurs du même type que la mienne, on m'a parlé d'un virus de type "Blast", ou de problèmes récurrents dans Outlook ou Internet Explorer. Mais rien qui ne puisse me faire avancer, l'image XPe que j'utilise sur la cible ou va tourner mon appli est garantie sans virus. Peut-être IE et Outlook utilisent-ils l'API Ras...

L'erreur se produit au bout d'un temps d'éxécution qui varie de 20 mn à 22 h. A chaque fois qu'elle se produit Windows me signale ensuite que la connexion GPRS vient d'être établie, alors que mon programme n'avait rien demandé au préalable (toutes les actions de mon appli sont tracées, et je n'ai pas trouvé la survenue de l'évènement de déconnexion ni la tentative de reconnexion dans le fichier de trace dans les minutes qui précèdent l'apparition de l'erreur).
Peut-être que Windows surveille lui aussi cette connexion, il me faudrait alors trouver un moyen de l'en empêcher. Je dois préciser que ma connexion GPRS est déclarée au préalable dans les connexions réseau du panneau de configuration, et utilise un modem que j'ai configuré via ce même panneau de configuration. Il y a sans doute un moyen de la créer de toutes pièces par l'API Ras, mais je ne le connais pas.

Apparemment l'API Ras est le seul moyen de manier des connexions réseau, si quelqu'un en connaît un autre, je ne demande que cela.

Sinon, l'option "en développer une soi-même" est une très bonne idée que j'aimerais beaucoup appliquer si j'en avais le temps. Au moins jze pourrais garder une totale maîtrise du code éxécuté au lieu de passer des pointeurs marshallés à des API en croisant les doigts pour que ca marche. J'y avais en pensé car je souhaitais développer un client port-série (j'utilise un modem externe relié par port COM) qui dans un premier temps enverrait les commande AT, (AT+CGDCONT=1,"IP","[mon APN]", etc...) et ensuite discuterai directement avec le serveur. J'avais télécharger un espion de port série voir voir les trames qui passait. Pour les commandes AT ca allait, mais pour la discussion avec le serveur, il le faudrait connaître le protocole Tcp, ses checksum, les réponses, l'en-tête. J'avais posé une demande sur ce forum à ce sujet mais personne n'y a répondu.
0
Rejoignez-nous