[résolu] Spouleur bloqué mais pas planté

Bonjour,



Il arrive de temps en temps (ça peut aller jusqu’à plusieurs fois par jour quand même) que le spooler d’un de nos serveurs (2000 server) se bloque. Mais Windows ne le vois pas planté. Il se bloque, et bloque avec lui toutes les sessions, il faut alors le redémarrer pour que ça reparte.



Le souci, c’est que comme Windows le vois toujours actif, pas moyen de mettre en place un redémarrage automatique quand ça se bloque.



J’ai essayé de voir avec le psservice de sysinternals, mais lui aussi vois le service comme normal, alors que dans les faits, pas vraiment :?



Quelqu’un a une idée ?

Ton idée de mise en place d’un redémarrage du service n’est pas possible car tu ne sais pas quand il fige… et comme Windows le soit toujours actif (ce qui est logique car le service ne plante pas) je ne vois pas comment tu pourrais mettre cela en place…



Est-ce que tu utilises le SP4 de Win2000 ? dans ce cas, http://support.citrix.com/article/CTX102523&searchID=10143603



Sinon, je conseille de prendre un dump du spooler avec ADPlus de Microsoft (http://support.microsoft.com/default.aspx?scid=kb;en-us;286350) pour savoir pourquoi le service fige. Une fois que Microsoft aura analysé le dump, ils pourront normalement te dire pourquoi il fige et prendre les actions nécessaires.

"ThinIsFat" wrote:
Une fois que Microsoft aura analysé le dump, ils pourront normalement te dire pourquoi il fige et prendre les actions nécessaires.

Il ne faut pas avoir un accès au support technique (payant) auprès d'eux pour ça ?

Remarque, je peux toujours demander à mon prestataire de faire l'intermédiaire, eux ils en ont un.

effectivement il faut un accès au support … j’oublie toujours que toutes les sociétés n’en possède pas un… :frowning:

dans l’attente de la corection reelle de ton probleme, tu peux (je pense) tester ton service spooler. Si il repond, mal ou pas du tout, le redemarrer. Pour ce faire test ce petit vbs, je ne sais pas si lui il va voir que ton spooler est mort, mais ca vaut la peinne de tester:

on error resume next
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\" & strComputer & "rootcimv2")
Set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_PrinterDriver")
if colInstalledPrinters.count = 0 then
wscript.echo "Spooler error" ' place ici l'arret et le redemarrage du spooler
else
wscript.echo "Spooler ok"
end if


Le code est simple:
- je me connecte en WMI au spooler et lui demande de me lister les pilotes installes. Si le nombre de pilote est null, il y a un probleme.

Dis nous si ca marche, merci.

Si oui, une tache planifiee toutes les 2 minutes (duree de vie 1 minute) et psservice pour le restart.

Good luke.

Merci pour ce petit script, mais une question :



si on prend un serveur qui s’appelle ‘Citrix’ par exemple, il suffit que je change la ligne


strComputer = "." 
par
strComputer = "Citrix" 
et c'est bon ? Parce que j'ai fait l'essai, ça me retourne une erreur alors que le spool se porte bien.

2ème question : ce script marche en réseau non ? Je n'ai pas besoin de nécessairement l'exécuter sur le serveur à tester ?

Si tu l’execute sur le server, laisse le “.” qui signifie “localhost” sinon tu as raison.

Ca ne marche pas… :?

Même en local, il me retourne spooler error.



Qu’est-ce qui coince ?

:chav_Forum34: j’ai encore parle trop vite.


objWMIService.ExecQuery("Select * from Win32_PrinterDriver") 
ne fonctionne que en XP et 2003 pas sous W2K

tu peux utiliser:
objWMIService.ExecQuery("Select * from Win32_Printer") 

a la place, mais il te diras "erreur" si le spooler est plante ou SI IL N'Y A PAS D'IMPRIMANTE. Bref pas cool.

http://www.microsoft.com/technet/prodtechnol/windowsserver2003/library/TechRef/573e8381-1d1f-409f-9ec2-a1d5efb4315b.mspx#w2k3tr_prntt_tools_swit


Je te trouve autre chose... DSL

C’est bon, ça marche. Pas de soucis, il y a toujours des imprimantes.



Y a plus qu’à attendre qu’un spool plante pour que je puisse tester le script… :?



Merci en tout cas

bon en vbscript c’est pas possible pour toi, mais il n’y a pas que le vb dans le vie :!:



Voici le mem chose en delphi7



tspoller.dpr:

program Tspoller;

{$APPTYPE CONSOLE}

uses
printers,
windows,
WinSpool;

var
Numdrivers, bytesNeeded :DWORD;

begin
try
Printer.Refresh;
Numdrivers := 0;
bytesNeeded := 0;
EnumPrinterDrivers(nil, nil, 2, nil, 0, bytesNeeded, NumDrivers);
if bytesNeeded = 0 then
Writeln('1')
else
Writeln('0');
except
Writeln('1');
end;
end.


Donc programme type dos, qui repond 0 si tous va bien ou 1 en cas de probleme, et fonctionne avec W2K !

Donc, j’ai enfin eu un spool planté, j’ai pu tester le script.



Il semble qu’il attende la réponse du spooler puisqu’il se bloque lui aussi.



La question est donc : peut-on mettre un timeout dans le script ?



Je ne suis pas assez doué en vbs pour faire ça…



Et j’ai delphi, mais en version 3, je ne suis pas sûr que ça marche du coup…

arf. Quand j’ai teste le vbs avec le spooler arrete je n’ais pas eut ce probleme.



Pour le timer c’est mort je pense. Il faut gerer le timer dans un tread, et en vbs :lol: :lol: :lol:



Je te pond ca ce matinen D7 ++

Oui, lorsque le spooler est arrêté ça fonctionne aussi, mais comme moi mon souci c’est un spooleur bloqué, il est toujours vu en trai nde tourner par le système, sauf qu’il tourne en rond tout seul dans son coin. :evil:

et voilou :wink:



http://www.chavers.org/download/Tspool.zip

et pour info le code source:

program Tspool;

{$APPTYPE CONSOLE}

uses
printers,
windows,
WinSpool;
Type
// Type procédural : fonction de callback pour timer.
TTimerProc = Procedure ;
// Structure de gestion d'un timer-thread.
TTimerParam = Record
Thread : THandle ; // Handle du thread.
ThreadID : Cardinal ; // Thread ID.
Interval : Cardinal ; // Période du timer.
OnTimer : TTimerProc ; // Procédure de callback.
Running : Boolean ; // Flag d'activation/acquittement de fermeture.
End ;

// Exemple de procédure activée pour un timer.
Procedure OnTimer ;
Begin
Writeln('1');
ExitProcess(0);
End;

{
Thread d'un timer.
lpParam : Pointeur sur une structure TTimerParam.
Retour : Toujours 0.
}
Function TimerThread ( lpParam : Pointer ) : DWORD ; stdcall ;
Var
Param : ^TTimerParam ;
Begin
Result:=0;
Param:=lpParam;
While (Param^.Running) Do Begin
Sleep(Param^.Interval);
If (Param^.Running) Then
Param^.OnTimer;
End;
// Acquittement.
Param^.Running:=True;
End;

{
Création d'un timer sous forme de thread.
Interval : Période du timer, en millisecondes.
OnTimer : Procédure (sans paramètres) appelée lors du déclenchement du timer.
Result : Structure de timer (retournée).
}
Procedure CreateTimer ( Interval : Cardinal ; OnTimer : TTimerProc ; Out Result : TTimerParam ) ;
Begin
// Initialisation des paramètres.
Result.Interval:=Interval ;
Result.OnTimer:=OnTimer ;
Result.Running:=True ;
// Création du thread.
Result.Thread:=CreateThread(Nil,0,@TimerThread,@Result,0,Result.ThreadID);
End;

// Détruit un timer existant.
Procedure DestroyTimer ( Var TimerParam : TTimerParam ) ;
Begin
// Demande de fermeture du thread.
TimerParam.Running:=False;
// Attente fermeture "réelle".
Repeat
Sleep(TimerParam.Interval);
Until TimerParam.Running ;
// Fin du thread.
CloseHandle(TimerParam.Thread);
End;

var
Numdrivers, bytesNeeded :DWORD;
Timer : TTimerParam ;

begin
CreateTimer(1000,@OnTimer,Timer);
try
Printer.Refresh;
Numdrivers := 0;
bytesNeeded := 0;
EnumPrinterDrivers(nil, nil, 2, nil, 0, bytesNeeded, NumDrivers);
if bytesNeeded = 0 then
Writeln('1')
else
Writeln('0');
except
Writeln('1');
end;
DestroyTimer(Timer);
end.

Donc que me ressort-il ? Quand je l’exécute sur mon pc (qui a des imprimantes et dont le spooler se porte comme un charme), j’ai un 0 (zéro) qui s’affiche.



Cela correspond au temps mis pour accéder à la liste des imprimantes ?



Est-il possible de passer un nom de serveur en paramètre ?



A combien est réglé le timeout ? 1000 ms ?



Je pose ses questions car je n’y connnait rien à delphi. (c’est du pascal le langage ?)

oui du pascal object :stuck_out_tongue:


A combien est réglé le timeout ? 1000 ms ?
correct

Si l'appli arrive a lister les pilotes, je pense que le spoole est ok donc je repond "0".
Si j'ai une erreur lors de la recuperation de la liste, j'affiche "1".
Si au time out de 1 second, je n'ais toujours pas cette liste, j'affiche "1".

Est-il possible de passer un nom de serveur en paramètre ?
Non, pas avec ce code. Il faudrait que je le redeveloppe en WMI :evil: mais bon :roll:

Ok, merci de ces précisions. Je vais tester ça dès qu’un de mes spooleurs plantera. :stuck_out_tongue:

Bon, je viens d’avoir le problème, j’ai donc lancé ce petit script et joie, ça fonctionne.

Voilà qui va donc résoudre mon souci. Merci beaucoup ! :smiley: