Problème Service windows qui s'arrete!

sphaxslayer Messages postés 216 Date d'inscription mardi 5 avril 2005 Statut Membre Dernière intervention 17 septembre 2008 - 3 avril 2006 à 19:05
cs_coq Messages postés 6351 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 - 7 avril 2006 à 19:11
Bonjour tout le monde !
Bien alors voilà: j'ai fait mon premier service windows en C# cette semaine, sachant que je débute plus ou moins dans ce domaine de programmation et dans ce langage que je commence seulement à explorer... Il s'agit d'un petit programme qui doit surveiller si IE et/ou Firefox tourne(nt) sur la machine om il est installé, afficher une alerte (pour l'instant un vulgaire pop-up) au bout de 45min, puis réafficher au bout de 15min supplémentaires en tuant les 2 processus s'ils sont lancés. S'ils sont arrêtés on remet le tout à zéro...enfin je crois que c'est ce que j'ai fait...

Première installation avec une fenêtre DOS et InstallUtil.exe, plantage à la fin du démarrage: "Erreur 1053: le service n'a pas démarré car la machine n'a pas répondu assez vite" (à quelque chose près ^^)...Relecture du code et après avoir vu une erreur énormissime que je corrige:
j'avais mis une boucle continue dans le onStart()...ce qui n'est pas top...

En revanche, j'ai corrigé ça tout simplement en déplaçant le code dans une fonction que j'appelle dans le onStart()....sauf que maintenant à peine il démarre qu'il m'affiche l'erreur suivante :
"Le service sur ordinateur local a démarré puis s'est arrêté. Certains services peuvent s'arrêter automatiquement s'ils n'ont aucune tâche à effectuer, par exemple, le service des alertes et les journaux de performances."

Mon code n'est pas énorme ni même optimisé je pense. En fait il s'agissait là d'une ébauche vraiment basique pour voir si ça marchait avant de charger le code en performances...le voici : (mais jetez pas de cailloux hein)

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Timers;

namespace GoToWorkClock
{
public class GoToWorkClock : System.ServiceProcess.ServiceBase
{
/// <summary>
/// Variable nécessaire au concepteur.
/// </summary>
private System.ComponentModel.Container components = null;

// variables de la classe
private bool _FirefoxStrtd = false;
private bool _IEStrtd = false;
// public static Timer _clock = new Timer(2700000); // par défaut à 45min d'intervalle
public static Timer _clock = new Timer(60000); // test
public static Timer _lastclock = new Timer();

static int nbProcActifs = 0;
static bool stop = false;
static bool launched = false;
static TimeSpan elapsedTime;
static TimeSpan elapsedFinalTime;
static DateTime debut;

public GoToWorkClock()
{
// Cet appel est requis par le Concepteur de composants Windows.Forms.
InitializeComponent();

// TODO : ajoutez les initialisations après l'appel à InitComponent
}

// Le point d'entrée principal pour le processus
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;

// Plusieurs services utilisateurs peuvent s'exécuter dans le même processus. Pour ajouter
// un autre service à ce processus, modifiez la ligne suivante
// afin de créer un second objet service. Par exemple,
//
// ServicesToRun = New System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
//
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new GoToWorkClock() };

System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}

/// <summary>
/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
/// le contenu de cette méthode avec l'éditeur de code.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "GoToWorkClock";
_clock.Elapsed += new ElapsedEventHandler(onTimedEvent);
_lastclock.Elapsed += new ElapsedEventHandler(lastTimedEvent);
}

/// <summary>
/// Nettoyage des ressources utilisées.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

/// <summary>
/// Démarrage du service.
/// </summary>
protected override void OnStart(string[] args)
{
System.Windows.Forms.MessageBox.Show("Service démarré avec succès!");
launcher(); // appel de la fonction qui contient le code...
}

/// <summary>
/// Arrêt du service.
/// </summary>
protected override void OnStop()
{
// TODO : ajoutez ici le code pour effectuer les destructions nécessaires à l'arrêt de votre service.
Dispose();
}

/// <summary>
/// Fonction appelée après la 1ère alerte. Dernier laps de temps avant le shoot.
/// </summary>
/// le timer passé en paramètre

/// marge qu'on pourra réglé dans une version ultérieure. Appel en dur pour l'instant

protected void lastTime(double marge)
{
_lastclock.Interval = marge;
_lastclock.AutoReset = true;
_lastclock.Start();

while (!stop)
{
// liste des processus actifs sur la machine locale
Process[] tabProcs = Process.GetProcesses();
nbProcActifs = tabProcs.Length;

// On regarde si les processus 'firefox.exe' et 'iexplorer.exe' sont dans la liste
foreach(Process proc in tabProcs)
{
if("firefox.exe" == proc.ProcessName.ToLower())
{
_FirefoxStrtd = true;
}
else
{
_FirefoxStrtd = false;
}
if("explorer.exe" == proc.ProcessName.ToLower())
{
_IEStrtd = true;
}
else
{
_IEStrtd = false;
}
}

if(!_FirefoxStrtd && !_IEStrtd)
{
// s'ils ne tournent pas ou plus, alors on arrête les compteurs et on affiche
// le temps total passé en ligne s'ils étaient lancés (launched était = true)
_lastclock.Stop();
_lastclock.Close();
_lastclock.Dispose();

launched = false;
elapsedFinalTime += elapsedTime;
debut = DateTime.Now;
// pop-up pour dire cb de temps a été passé
System.Windows.Forms.MessageBox.Show("Temps passé TOTAL = " + elapsedFinalTime.ToString());
}
}
}

/// <summary>
/// fonction appelée au démarrage du service
/// </summary>
private void launcher()
{
while (!stop)
{
// liste des processus actifs sur la machine locale
Process[] tabProcs = Process.GetProcesses();
nbProcActifs = tabProcs.Length;

// On regarde si les processus 'firefox.exe' et 'iexplorer.exe' sont dans la liste
foreach(Process proc in tabProcs)
{
if("firefox.exe" == proc.ProcessName.ToLower())
{
_FirefoxStrtd = true;
}
else
{
_FirefoxStrtd = false;
}
if("explorer.exe" == proc.ProcessName.ToLower())
{
_IEStrtd = true;
}
else
{
_IEStrtd = false;
}
}

// S'ils y sont, c'est qu'on est connecté à Internet
if(_FirefoxStrtd || _IEStrtd)
{
//s'ils viennent d'être lancés on active le Timer
launched = true;
debut = DateTime.Now;
_clock.AutoReset = true;
_clock.Start();
}
else
{
// s'ils ne tournent pas ou plus, alors on arrête le compteur et on affiche
// le temps total passé en ligne s'ils étaient lancés (launched était = true)
_clock.Stop();
_clock.Close();
_clock.Dispose();

if(launched)
{
launched = false;
elapsedTime = DateTime.Now.Subtract(debut);
debut = DateTime.Now;
// pop-up pour dire cb de temps a été passé
System.Windows.Forms.MessageBox.Show("Temps passé = " + elapsedTime.ToString());
}
}
}
}

/// <summary>
/// Spécifie ce qu'il arrive lorsque l'événement est levé
/// </summary>
private void onTimedEvent(object sender, ElapsedEventArgs e)
{
// Pop-up pour dire qu'on a déjà passé X temps en ligne (45min par défaut)
System.Windows.Forms.MessageBox.Show("TEST");
// on laisse un délai de 15min pour finir
// lastTime(900000);
lastTime(30000); // test
}

private void lastTimedEvent(object sender, ElapsedEventArgs e)
{
// on récupère les processus 'iexplorer.exe' et 'firefox.exe' et on les tue
Process[] procs = Process.GetProcesses();
nbProcActifs = procs.Length;

foreach(Process proc in procs)
{
if("firefox.exe" == proc.ProcessName)
{
proc.Kill();
}
else if("iexplorer.exe" == proc.ProcessName)
{
proc.Kill();
}
}
}
}
}

Voilà j'ai essayé de faire ça au plus propre, mais je suis prêt à répondre à toutes les questions supplémentaires.

"Un seul Être vous manque, et tout est dépeuplé..."

10 réponses

sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
4 avril 2006 à 11:05
la derniere erreur qui s'affiche, c'est quand une exception est levée dans un service, evidement tu n'as pas de moyen de le savoir.

de plus, MessageBox est une fonction interdite dans un service, et le processus qui demarre les service la detecte, met cette fonction en commentaire et tu devrais observer un changement (c'est une fonction bloquante, et une application service est censée ne jamais se bloquer, c'est pour ca)

de plus, d'avoir deplacé ta boucle sans fin du Start vers une autre fonction qui est ensuite appelée dans Start... cela ne change strictement rien.

ce que je te recommande, c'est d'utiliser un timer (celui du namespace System.Timers et surtout pas celui de System.Windows.Forms) et sur chaque "Tick" tu appel ta fonction launcher, en ayant evidement prealablement enlevé le while en entrée
1
Rejoignez-nous