Page 1 sur 1

WriteProgramStringN

Publié : mer. 25/oct./2006 16:40
par Droopy
J'ai un soucis avec WriteProgramStringN qui ne renvoie pas la chaine passée / ne renvoie pas le bon nombre d'octets envoyés.

Code : Tout sélectionner

#Commande="Google.com"

OpenWindow(0, 0, 0, 640, 480, "---", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
CreateGadgetList(WindowID(0)) 
EditorGadget(0, 10, 10, 620, 460) 
SetGadgetFont(0,LoadFont(0,"Courier",8))

Procedure Lancement()

  Handle = RunProgram("nslookup","","", #PB_Program_Hide|#PB_Program_Connect|#PB_Program_Open|#PB_Program_Write|#PB_Program_Read) 
  
  If Handle 
   
   While ProgramRunning(Handle)
      Delay(10)
      TailleRecu=AvailableProgramOutput(Handle)
      
      If TailleRecu
        AddGadgetItem(0, -1, "###### Taille reçue "+Str(TailleRecu))
        *Tampon=AllocateMemory(TailleRecu)
        ReadProgramData(Handle,*Tampon,TailleRecu)
        AddGadgetItem(0, -1, PeekS(*Tampon,TailleRecu))
        If FindString(PeekS(*Tampon,TailleRecu),">",1)
          TailleEnvoie=WriteProgramStringN(Handle,#Commande)
          AddGadgetItem(0, -1, "###### Envoie de la commande : "+#Commande+" ("+Str(TailleEnvoie)+" caractère)")
          CloseProgram(Handle)
          ProcedureReturn
        EndIf
        FreeMemory(*Tampon)
      EndIf
    Wend
  CloseProgram(Handle)  
  EndIf
   
  AddGadgetItem(0, -1, "Fin normale")
  
EndProcedure

CreateThread(@Lancement(),0)
  
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 

Publié : jeu. 26/oct./2006 22:49
par RegisLG
Moi ce que je ne comprends pas, c'est que la commande passée par WriteProgramStringN est bien envoyée au programme, mais effectivement le résultat de WriteProgramStringN est erroné.

Et concernant l'usage de nslookup, autre chose bizarre, quand je tape "nslookup google.com" dans une console, j'ai cette réponse :
Serveur : KOOGAR-1234
Address: 192.168.1.1

Réponse ne faisant pas autorité :
Nom : google.com
Addresses: 64.233.187.99, 72.14.207.99, 64.233.167.99
Or avec le programme ci-dessous (inspiré de celui de Droopy), la ligne "Réponse ne faisant pas autorité" disparaît mystérieusement... c'est pareil chez vous ?

Code : Tout sélectionner

#Commande="Google.com"

OpenWindow(0, 0, 0, 640, 480, "---", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
EditorGadget(0, 10, 10, 620, 460)
SetGadgetFont(0,LoadFont(0,"Courier",8))

Procedure Lancement(Valeur)

  Handle = RunProgram("nslookup","","", #PB_Program_Hide|#PB_Program_Connect|#PB_Program_Open|#PB_Program_Write|#PB_Program_Read)
  
   If Handle
   
   While ProgramRunning(Handle)
    
    TailleRecu=AvailableProgramOutput(Handle)
    ;enlevez le commentaire de la ligne ci-dessous pour avoir le détail
    ;AddGadgetItem(0, -1, "TailleRecu = "+Str(TailleRecu))
    
    Select TailleRecu

      Case 0
       ; on ne fait rien (on attend une réponse de la commande)

      Case 63
       ;réception du premier affichage de la commande
         *Tampon=AllocateMemory(TailleRecu)
         ReadProgramData(Handle,*Tampon,TailleRecu)
         ;enlevez le commentaire de la ligne ci-dessous pour avoir le détail
         ;AddGadgetItem(0, -1, PeekS(*Tampon,TailleRecu))
         FreeMemory(*Tampon)
         ; on envoie notre ordre (l'url)
         OctetsEcrits1=WriteProgramStringN(Handle,#Commande)

      Default
       ;reponse de la commande apres passage du parametre
        *Tampon=AllocateMemory(TailleRecu)
        ReadProgramData(Handle,*Tampon,TailleRecu)
        AddGadgetItem(0, -1, PeekS(*Tampon,TailleRecu))
        FreeMemory(*Tampon)
       ;on quitte le programme
        OctetsEcrits2=WriteProgramStringN(Handle,"exit")
       
    EndSelect

   Wend
  EndIf
  CloseProgram(Handle)
  AddGadgetItem(0, -1, Chr(13)+"Youpi ! Ca marche, enfin presque ... :")
  AddGadgetItem(0, -1, Chr(13)+"OctetsEcrits1 ="+Str(OctetsEcrits1))
  AddGadgetItem(0, -1, Chr(13)+"OctetsEcrits2 ="+Str(OctetsEcrits2))
   
EndProcedure

CreateThread(@Lancement(),0)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Publié : ven. 27/oct./2006 10:04
par Droopy
J'ai l'impression que la valeur renvoyée est correcte, il n'enverrais qu'un seul caractère, et ce serait pour cela que la commande n'est pas envoyée à Nslookup. ( et pour cela qu'on a pas la réponse à la commande )

Publié : ven. 27/oct./2006 12:26
par RegisLG
Droopy a écrit :J'ai l'impression que la valeur renvoyée est correcte, il n'enverrais qu'un seul caractère, et ce serait pour cela que la commande n'est pas envoyée à Nslookup. ( et pour cela qu'on a pas la réponse à la commande )
Pourtant dans l'exemple que j'ai posté, la commande ("google.com", valeur attendue par nslookup) est bien passée et on récupère bien la réponse (l'IP), le seul truc qui n'est pas correct c'est la valeur renvoyée par WriteProgramStringN (1 octet).

Publié : ven. 27/oct./2006 18:24
par Droopy
la commande ("google.com", valeur attendue par nslookup) est bien passée
Voila ce que j'ai en lançant ton code :
Serveur par défaut : passerelle.mshome.net
Address: 192.168.0.1

>

Youpi ! Ca marche, enfin presque ... :

OctetsEcrits1 =0

OctetsEcrits2 =1
En fait après le > c'est que tu as lancé Nslookup.
Si tu avais réussis à passer google.com tu aurais eu une réponse, non, là tu n'en a eu aucune.

Publié : ven. 27/oct./2006 20:09
par RegisLG
Ah ben là on a un problème car moi j'ai ça en sortie de mon programme (donc ca marche):
Serveur : KOOGAR-1234
Address: 192.168.1.1

Nom : Google.com
Addresses: 64.233.187.99, 64.233.167.99, 72.14.207.99

>

Youpi ! Ca marche, enfin presque ... :

OctetsEcrits1 =1

OctetsEcrits2 =1
Par contre avec ton programme, j'obtiens ça :
###### Taille reçue 63
Serveur par défaut : WANADOO-9BDD
Address: 192.168.1.1

>
###### Envoie de la commande : Google.com (1 caractère)
De plus, si tu "actives la gestion des threads "dans les options du compilateur, ton programme plante (apparemment c'est parce que tu as oublié de mettre un paramètre dans la déclaration de la procédure Lancement).

Publié : ven. 27/oct./2006 20:48
par Droopy
Ouai 8O On a un Big problème, et je sais plus où chercher :cry:

Publié : sam. 28/oct./2006 1:33
par RegisLG
Peux-tu me dire si le code ci-dessous donne un meilleur résultat (ou pire lol) :

Code : Tout sélectionner

MonProgramme = RunProgram("nslookup", "", "", #PB_Program_Hide|#PB_Program_Open|#PB_Program_Read|#PB_Program_Write)

Sortie$ = ""

If MonProgramme
    
  While AvailableProgramOutput(MonProgramme) = 0 :Wend ;synchro
  ReadProgramString(MonProgramme) ; lit le serveur par defaut
  ReadProgramString(MonProgramme) ; lit l'adresse du serveur

  OctetsEcrits1=WriteProgramStringN(MonProgramme, "google.com") ; passe le parametre a nslookup
     
  For i=1 To 7
    ;récupère les infos
    ; ligne 1 : >
    ; ligne 2 : Serveur : KOOGAR-1234
    ; ligne 3 : Adresse : 192.168.1.1
    ; ligne 4 : ligne vide
    ; ligne 5 : Réponse ne faisant pas autorité
    ; ligne 6 : Nom : google.com
    ; ligne 7 : Addresses : 72.14.207.99 etc...
    While AvailableProgramOutput(MonProgramme) = 0 :Wend ;synchro    
    Sortie$+ReadProgramString(MonProgramme)+Chr(13) 
  Next
  
  OctetsEcrits2=WriteProgramStringN(MonProgramme, "exit") ; passe exit en parametre pour quitter nslookup

  While AvailableProgramOutput(MonProgramme) = 0 :Wend ;synchro
  ReadProgramString(MonProgramme) ; lit le >
  ReadProgramString(MonProgramme) ; lit la ligne vide
EndIf

Sortie$ + Chr(13) + "OctetsEcrits1 = "+Str(OctetsEcrits1)
Sortie$ + Chr(13) + "OctetsEcrits2 = "+Str(OctetsEcrits2)
Sortie$ + Chr(13) + Chr(13) + "Code de retour : " + Str(ProgramExitCode(MonProgramme))

CloseProgram(MonProgramme)

OpenWindow(0, 0, 0, 640, 480, "Test_WriteProgramStringN 2", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
EditorGadget(0, 10, 10, 620, 460)
SetGadgetFont(0,LoadFont(0,"Courier",8))
AddGadgetItem(0, -1, Sortie$)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Pour information, j'obtiens ce résultat :
> Serveur : KOOGAR-1234
Address: 192.168.1.1

Nom : google.com
Addresses: 64.233.167.99, 64.233.187.99, 72.14.207.99


OctetsEcrits1 = 1
OctetsEcrits2 = 1

Code de retour : 0

Publié : sam. 28/oct./2006 7:04
par Droopy
C'est nettement mieux
> Serveur : passerelle.mshome.net
Address: 192.168.0.1

Nom : google.com
Addresses: 64.233.187.99, 64.233.167.99, 72.14.207.99


OctetsEcrits1 = 1
OctetsEcrits2 = 1

Code de retour : 0
Mais il faut savoir à l'avance le nombre de ligne à recevoir !.

Publié : sam. 28/oct./2006 11:12
par RegisLG
Mais il faut savoir à l'avance le nombre de ligne à recevoir !.
Oui c'est vrai mais je cherchais à "valider" une idée : j'ai l'impression qu'il faut toujours s'assurer d'avoir lu l'intégralité de la réponse de la commande (nslookup) avant de lui envoyer un ordre (google.com), c'est une histoire de synchro.
Le problème c'est comment être sûr que la commande a fini de transmettre quelque chose (si on ne connaît pas la quantité d'info à recevoir) ?

En tout cas l'exemple (qui fonctionne) confirme le problème soulevé dans ton post initial, car on récupère 1 comme nombre d'octets envoyés, et pourtant on en a transmis plus ! Il y a donc quelque chose de bizarre là-dedans, ou alors on ne comprend pas tous les deux comment s'en servir lol ;)

à défaut d'un pain au chocolat, un bout de code

Publié : lun. 30/oct./2006 8:42
par electron

Code : Tout sélectionner

OpenConsole()
Delay(1000)
Global Handle.l,TailleRecu.l,a.s

#Commande="google.com"+#CRLF$
Handle = RunProgram("c:\windows\system32\nslookup.exe","","",#PB_Program_Open|#PB_Program_Write|#PB_Program_Read)

Procedure.s stdout()
  *Tampon=AllocateMemory(TailleRecu)
  ReadProgramData(Handle,*Tampon,TailleRecu)
  ProcedureReturn PeekS(*Tampon,TailleRecu)
EndProcedure 

If Handle
  Delay(4000)
  While ProgramRunning(Handle)
    TailleRecu=AvailableProgramOutput(Handle)
    If FindString(stdout(),">",1)
      WriteProgramString(Handle,#Commande)
    EndIf
    While 1
      a=stdout()
         Debug a
      If FindString(a,Chr(10)+">",1)
        WriteProgramString(Handle,"exit"+#CRLF$)
        Input()
       End
      EndIf
      FreeMemory(*Tampon)
    Wend
    End
  Wend
  CloseProgram(Handle)
EndIf


CloseConsole()
:idea:

Publié : lun. 30/oct./2006 12:25
par RegisLG
@Electron pour info, j'ai testé ton code :

il me sort bien les IPs par contre il bloque ensuite, la console ne se ferme pas. Quand j'arrête l'exécution, ça donne ça :
[12:22:17] Attente du démarrage du programme...
[12:22:17] Exécutable démarré.
[12:22:24] [ERROR] Line: 25
[12:22:24] [ERROR] The Program is no longer running.
[12:22:24] Exécution du programme terminée.
En fait nslookup s'est déjà terminé avant même que la commande 'exit' lui soit envoyée, et donc on reste coincé dans la boucle while). On retombe dans les histoires de synchro dont je parlais plus haut.

ps1 : on parle de la commande WriteProgramStringN et pas WriteProgramString, ça change pas grand chose (ça évite d'avoir à ajouter le #CRLF$), j'ai testé avec les 2, le résultat est le même.

ps2 : avant d'appeler ta procédure stdout() il faut vérifier que la taille soit différente de 0 (que qqchose ait été lu, sinon ça plante lors de la réservation de la zone mémoire).

correction

Publié : mar. 31/oct./2006 8:42
par electron
je savais pour writeprogramstring et writeprogramstringN (le crlf)
je pense que c'est lié effectivement à la commande nslookup en mode interactif et le(s) writeprogramstring*,bug :?:

http://support.microsoft.com/kb/200525/fr