Probleme avec Pipe Dos

Signaler
Messages postés
16
Date d'inscription
jeudi 20 juillet 2006
Statut
Membre
Dernière intervention
6 février 2008
-
Messages postés
16
Date d'inscription
jeudi 20 juillet 2006
Statut
Membre
Dernière intervention
6 février 2008
-
Bonjours, j'ai un gros probleme depuis 3 jours. Je m'explique :

J'ai pris cette source de  Fredlynx  =>ICI<= et j'ai compilé. Jusqu'ici tous va bien =).
La ou j'ai un probleme c'est que je veux lancer mon client (ou mon server) netcat mais la, le programme de Fredlynx plante et ne repond plus...

Si quelqu'un aurai une idée sa serai vrement sympa.

Merci





je ne suis qu'un débutant...;

11 réponses

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Salut
Si c'était une affaire de syntaxe, le Shell te l'aurait dit (il est très poli)
Le programme plante et ne répond plus : C'est le gestionnaire des tâches qui le dit ou bien c'est le comportement que tu as observé ?
Est-ce le programme VB du pipe qui fige ou bien l'application que tu lances avec ta commande DOS ?
As-tu un antivirus ? un parefeu ?
Ta commande DOS touche t-elle des points sensibles comme TelNet qui pourrait être intercepté par un de ces progiciels ?
Quand tu exécutes à la main la même commande DOS dans une fenêtre du même métal, as-tu une réaction identique ?
Quel Windows utilises-tu ?

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
16
Date d'inscription
jeudi 20 juillet 2006
Statut
Membre
Dernière intervention
6 février 2008

Merci de votre reponse..

Donc, le programme qui plante, c'est d'une part le gestionnaire des tache qui me le dit et d'autre part lorsque je met le curseur de la souris sur le programme, il ny a que le sablier.


Ensuite, c'est bien le prgramme du pipe vb qui plante et non pas l'application lancer par la commande dos.


Je n'est pas d(antivirus, ni de parefeu (meme pas celui de windows).


De plus ma commande dos ne touche aucun point sensible comme Telnet. Je tape juste la cmmande  nc -l -p 80 (par exemple), et des que la connection est établi, sa plante!!


Or, quand j'execute cette commande dans une fenetre CDM.exe, sa marche nikel!

Je suis sous windows XP Pro.

Merci beaucoup
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Re
Merci pour ces précisions.
Si la commande tapée à la main fonctionne, la même commande sous VB ne devrait pas poser de problème.
A mon avis, c'est ton programme qui tourne en rond à attendre quelque chose, et sans DoEvents.
Vérifie si, après le lancement de la commande, tu fais une boucle d'attente/de lecture et vérifie les conditions.
Insère un DoEvents dans cette boucle, ça évitera de perdre la main.
Utilise le mode debuggage pour surveiller ce qui se passe :
- F9 sur une ligne du code
- Quand le programme s'arrête dessus, survol de la souris pour visualiser les valeurs des variables
- F8 pour avancer d'une seule instruction, sinon, F5 pour continuer normalement.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
16
Date d'inscription
jeudi 20 juillet 2006
Statut
Membre
Dernière intervention
6 février 2008

J'ai regardé se que tu m'a dit et :

J'ai vu une boucle qui attent :


    Result = ReadFile(HLecturePipe, strBuff, 256, LngOctetRec, 0&)
        mOutputs = mOutputs & Left(strBuff, LngOctetRec)
        'Envoie les données au programme via l'événement
        RaiseEvent ReceiveOutputs(Left(strBuff, LngOctetRec))
        DoEvents
        Loop While Result <> 0

J'ai changer la derniere ligne  par :

Loop While Result = 0

La sa fonctionne nikel, le client se connecte et le programme ne plante plus mais par contre plus rien ne s'affiche dans la fenetre DOS qui est dans le pregramme VB.

Ou penses tu qu'il y aurai un probleme?
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Salut
Manque un "Do" juste avant le "Result = ..."
Result prend la valeur renvoyée par la Sub nommée "ReadFile" qui n'est pas une fonction de VB.
Le test "Loop While" en <> ou en = dépend de ce qu'est sensé renvoyer cette Sub. A analyser car peut-être ressors-tu de la boucle en n'ayant fait qu'une seule lecture et c'est peut-être insuffisant.
Je ne pense pas que ce soit cette boucle qui merdouillait puisqu'elle est équipée du DoEvents (qui te permettrait de stopper ton programme en cas de bouclage permanent sans passer par un "Pas de réponse")
Je pense qu'il faut regarder ce qu'il y a dans ReadFile ET vérifier quels paramètres tu lui donnes.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
16
Date d'inscription
jeudi 20 juillet 2006
Statut
Membre
Dernière intervention
6 février 2008

Bon ba j'ai chercher pendant 2h sur se que vous m'avais dit mais serieusement je ne trouve vrement rien (en plus je debute seulement en Visual Basic donc...)

J'ai regarder ces 2 fonctions :

'API CreatePipe permet de créer un "pipe" anonime,
'on récupére un handle pour lire et un pour ecrire.
Private Declare Function CreatePipe Lib "kernel32" _
                (phReadPipe As Long, _
                phWritePipe As Long, _
                lpPipeAttributes As Any, _
                ByVal nSize As Long) As Long


'Utiliser pour lire le "pipe" rempli par le process qui
'sera créé par l'API CretaProcessA
Private Declare Function ReadFile Lib "kernel32" _
                (ByVal hFile As Long, _
                ByVal lpBuffer As String, _
                ByVal nNumberOfBytesToRead As Long, _
                lpNumberOfBytesRead As Long, _
                ByVal lpOverlapped As Any) As Long
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Re
Bon, prends le problème différemment :
Recharge la source d'origine de FredLynx dans un coin.
Modifie le code du bouton_click que l'on voit en haut "Windows XP Dir c:" avec ta propre commande puis lance l'appli.
Est-ce qu'elle fontionne ?
Si oui, ce sont les modifs que tu y as apportées qui coincent ... tu n'as plus qu'à éplucher tout ça.
On ne peut t'en dire plus sans avoir le code sous les yeux.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés





<hr />

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
16
Date d'inscription
jeudi 20 juillet 2006
Statut
Membre
Dernière intervention
6 février 2008

Oui avec la source original c'est toujours le meme probleme : le programme ne repond plus...

Voila la form du programme :

'Private MyDOS As DOSClass


Private WithEvents MyDOS As DOSClass




Private Sub CmdQuitter_Click()
    Unload Me
End Sub


Private Sub Form_Load()
    Set MyDOS = New DOSClass
End Sub


Private Sub Form_Unload(Cancel As Integer)
    MyDOS.ClosedCommand
    Set MyDOS = Nothing
End Sub


Private Sub MyDOS_ReceiveOutputs(CommandOutputs As String)
    TextDos = TextDos & CommandOutputs
End Sub


Private Sub Command1_Click()
    'Faire un dir de c: sur les environnement de type XP 2000
    TextDos = ""
    MyDOS.CommandLine = "nc 192.168.1.174 80"
    MyDOS.ExecuteCommand
End Sub


Private Sub Command2_Click()
    'Lancer la commande NET
    TextDos = ""
    MyDOS.CommandLine = "net.exe"
    MyDOS.ExecuteCommand
End Sub


Private Sub Command3_Click()
    'Lancer un ping
    TextDos = ""
    MyDOS.CommandLine = "Ping.exe 127.0.0.1"
    MyDOS.ExecuteCommand
End Sub


Private Sub Command4_Click()
    'Lancer un programme X
    CommonDialog1.DialogTitle = "Choisir un programme de type 'dos'"
    CommonDialog1.Filter = " Programmes |*.exe"
    CommonDialog1.ShowOpen
    If CommonDialog1.FileName <> "" Then
        TextDos = ""
        MyDOS.CommandLine = CommonDialog1.FileName
        MyDOS.ExecuteCommand
    End If
End Sub

(le fichier nc.exe se trouve dans le meme dossier que le programme )





Maintenant voila le Module du programme :


Option Explicit


'API CreatePipe permet de créer un "pipe" anonime,
'on récupére un handle pour lire et un pour ecrire.
Private Declare Function CreatePipe Lib "kernel32" _
                (phReadPipe As Long, _
                phWritePipe As Long, _
                lpPipeAttributes As Any, _
                ByVal nSize As Long) As Long


'Utiliser pour lire le "pipe" rempli par le process qui
'sera créé par l'API CretaProcessA
Private Declare Function ReadFile Lib "kernel32" _
                (ByVal hFile As Long, _
                ByVal lpBuffer As String, _
                ByVal nNumberOfBytesToRead As Long, _
                lpNumberOfBytesRead As Long, _
                ByVal lpOverlapped As Any) As Long


'Structure utilisée par l'API CreateProcessA
Private Type SECURITY_ATTRIBUTES
    nLength              As Long
    lpSecurityDescriptor As Long
    bInheritHandle       As Long
End Type


'Structure utilisée par l'API CreateProcessA
Private Type STARTUPINFO
    cb                  As Long
    lpReserved          As Long
    lpDesktop           As Long
    lpTitle             As Long
    dwX                 As Long
    dwY                 As Long
    dwXSize             As Long
    dwYSize             As Long
    dwXCountChars       As Long
    dwYCountChars       As Long
    dwFillAttribute     As Long
    dwFlags             As Long
    wShowWindow         As Integer
    cbReserved2         As Integer
    lpReserved2         As Long
    hStdInput           As Long
    hStdOutput          As Long
    hStdError           As Long
End Type


'Structure utilisée par l'API CreateProcessA
Private Type PROCESS_INFORMATION
    hProcess            As Long
    hThread             As Long
    dwProcessID         As Long
    dwThreadID          As Long
End Type


'Cette API lance un commande et renvoie les infos sur le process
'dans la structure PRECESS_INFORMATION
Private Declare Function CreateProcessA Lib "kernel32" _
                (ByVal lpApplicationName As Long, _
                ByVal lpCommandLine As String, _
                lpProcessAttributes As SECURITY_ATTRIBUTES, _
                lpThreadAttributes As SECURITY_ATTRIBUTES, _
                ByVal bInheritHandles As Long, _
                ByVal dwCreationFlags As Long, _
                ByVal lpEnvironment As Long, _
                ByVal lpCurrentDirectory As Long, _
                lpStartupInfo As STARTUPINFO, _
                lpProcessInformation As PROCESS_INFORMATION) As Long


'Cette API Permet de terminer prématurément un process KILLLL :)
Private Declare Function TerminateProcess Lib "kernel32" _
                (ByVal hProcess As Long, _
                ByVal uExitCode As Long) As Long
   
'Fermeture d'un handle
Private Declare Function CloseHandle Lib "kernel32" (ByVal hHandle As Long) As Long


'Constantes utilisée pour les API
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const STARTF_USESTDHANDLES = &H100&
Private Const STARTF_USESHOWWINDOW = &H1




Private mCommand        As String               'Variable privée contenant la ligne de commande
Private mOutputs        As String               'Variable privée pour la lecture du texte renvoié
Private ProcI           As PROCESS_INFORMATION  'Process utilisé
Private HLecturePipe    As Long                 'Handle de lecture du "pipe"
Private HEcriturePipe   As Long                 'Handle d'écriture du "pipe"


'Evénement de reception de donnée de l'objet
Public Event ReceiveOutputs(CommandOutputs As String)


'------------------------------------------------------------
' Propriété publique qui permet de passer ou de lire la ligne
' de commande passer au module
'------------------------------------------------------------
Public Property Let CommandLine(DOSCommand As String)
    mCommand = DOSCommand
End Property


Public Property Get CommandLine() As String
    CommandLine = mCommand
End Property


'------------------------------------------------------------
' Propriété publique qui permet de lire la totalité des données
' reçues après l'exécution
'------------------------------------------------------------
Public Property Get Outputs()
    Outputs = mOutputs
End Property




'------------------------------------------------------------
' Fonction publique qui lance l'éxécution de la ligne de commande
'------------------------------------------------------------
Public Function ExecuteCommand() As String
  'Variable contenant le résultat des fonction API
    Dim Result          As Long
  'Variable Structure utilisée par l'API CreateProcessA
    Dim Start           As STARTUPINFO
  'Variable Structure utilisée par l'API CreateProcessA
    Dim Sa              As SECURITY_ATTRIBUTES
  'Variable contenant le nombre d'octet lus dans le "pipe"
    Dim LngOctetRec     As Long
  'Variable buffer de lecture du "pipe"
    Dim strBuff         As String * 256


  'Ca c'est pour les couillons qui oublis de donner
  'la commande avant de lancer l'exécution....
    If Len(mCommand) = 0 Then
        MsgBox "La commande à lancer n'a pas été renseignée!!!", vbCritical
        Exit Function
    End If
   
  'Renseignement de la structure SECURITY_ATTRIBUTES
    Sa.nLength = Len(Sa)
    Sa.bInheritHandle = 1&
    Sa.lpSecurityDescriptor = 0&
 
  'Création du "Pipe" et Test du résultat
    If CreatePipe(HLecturePipe, HEcriturePipe, Sa, 0) = 0 Then
        'Si une erreur
        MsgBox "Erreur de création du Pipe. Erreurr: " & Err.LastDllError, vbCritical
        Exit Function
    End If
   
  'Renseignement de la structure STARTUPINFO
    Start.cb = Len(Start)
    Start.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
    Start.hStdOutput = HEcriturePipe
    Start.hStdError = HEcriturePipe
 
  'Création du process = Exécution de la commande
    If CreateProcessA(0&, mCommand, Sa, Sa, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, Start, ProcI) <> 1 Then
        'Si une erreur, fermeture des Handles
        Result = CloseHandle(HLecturePipe)
        Result = CloseHandle(HEcriturePipe)
        MsgBox "Fichier ou commande non trouvé.", vbCritical
        Exit Function
    End If
   
  'Fermeture du "pipe" de sortie
    Result = CloseHandle(HEcriturePipe)
    mOutputs = ""
   
  'Lecture du "pipe" en lecture pour récupérer les infos !
    Do
        Result = ReadFile(HLecturePipe, strBuff, 256, LngOctetRec, 0&)
        mOutputs = mOutputs & Left(strBuff, LngOctetRec)
        'Envoie les données au programme via l'événement
        RaiseEvent ReceiveOutputs(Left(strBuff, LngOctetRec))
        DoEvents
    Loop While Result <> 0
   
  'Fermeture de tous les Handles
    Result = CloseHandle(ProcI.hProcess)
    Result = CloseHandle(ProcI.hThread)
    Result = CloseHandle(HLecturePipe)
   
  'Renvoie du résultat
    ExecuteCommand = mOutputs
End Function


Public Sub ClosedCommand()
  'Variable contenant le résultat des fonction API
    Dim Result          As Long
   
  'Force la fermeture du process en cours
    TerminateProcess ProcI.hProcess, 0
  'Fermeture de tous les Handles
    Result = CloseHandle(ProcI.hProcess)
    Result = CloseHandle(ProcI.hThread)
    Result = CloseHandle(HLecturePipe)
End Sub

Le Server.bat qui attend une connecter est :

nc -l -p 80
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Re
Si le programme est l'original, ce n'était pas la peine de le coller, les redéfinitions des Command button auraient suffit.
Excuse mon ignorance mais "NC.EXE" est-il un programme appartenant à l'environnement Windows ou bien un EXE perso ?

Dans le Command3, la commande "Ping" (enlève le ".EXE") : Elle non plus ne fonctionne pas ? ou n'y en a t-il qu'une seule qui merdouille ? (laquelle)

Tu es sous XP ?

Est-ce que MyDOS_ReceiveOutputs se déclenche au moins une fois ? (as-tu tenter de debuguer ?)
Idem dans la classe, dans le Do-Loop : Reste t-on coincé ici ou en sort-on trop tôt ?
Que vaut mOutputs à la sortie du Loop ?

Pourquoi parles-tu de Module ?
Il n'y a pas de module dans cette application, seulement une Classe qui renvoie des évènements ...
Erreur de terme ou modif réelle ?

Ta dernière phrase est énigmatique : "Le Server.bat qui attend une connecter est :"
Que vient faire un fichier BAT dans cette histoire ?

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Idée comme ça : Essaye de faire précéder toutes tes commandes DOS par 
   cmd /c
Exemple :
    MyDOS.CommandLine = "cmd /c nc 192.168.1.174 80"

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
16
Date d'inscription
jeudi 20 juillet 2006
Statut
Membre
Dernière intervention
6 février 2008

Merci mais meme si je precede toutes mes commandes DOS pas cmd /c cela de change rien. A tu essayer mon programme
 ché toi?