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

On a un Big problème, et je sais plus où chercher

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()

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