COMANDOS MULTIPLES - VB

Iniciado por rochro, 12 Junio 2014, 18:48 PM

0 Miembros y 2 Visitantes están viendo este tema.

rochro

Cita de: El Benjo en 18 Junio 2014, 06:26 AM
No estoy seguro pero creo que tu problema puede estar en:

Código (vbnet) [Seleccionar]
Invoke(Finished)


Benjo, hice lo que me dijiste y sigue igual.

El Benjo

Estás seguro de que no se ejecuta "runpkr00.exe -d " & nombre por cada archivo? O sólo no te muestra la información en la pantalla?

Para qué es la línea "Invoke(Finished)"?

Has colocado puntos de interrupción en el bucle para comprobar que realmente hace cada iteración que debería?

Si la respuesta a la pregunta anterior es "sí", ¿se ejecuta cada iteración sin problemas o da algún error?
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

rochro

Cita de: El Benjo en 18 Junio 2014, 20:25 PM
Estás seguro de que no se ejecuta "runpkr00.exe -d " & nombre por cada archivo? O sólo no te muestra la información en la pantalla?

Para qué es la línea "Invoke(Finished)"?

Has colocado puntos de interrupción en el bucle para comprobar que realmente hace cada iteración que debería?

Si la respuesta a la pregunta anterior es "sí", ¿se ejecuta cada iteración sin problemas o da algún error?


Se ejecuta todo bien pero no en todos los archivos que se encuentran en el directorio, o sea no me funciona el bucle.

ejem:

directorio
     archivo1.t01 ---- solo ejecuta en el primer archivo
     archivo2.t01
     archivo3.t01
     archivo4.t01


El invoke(Finished) es para que me imprima el resultado de la aplicación de los comandos.

El Benjo

Modifica el código como sigue:

Código (vbnet) [Seleccionar]
Try
      For Each archivo As String In My.Computer.FileSystem.GetFiles(midirectorio, FileIO.SearchOption.SearchAllSubDirectories, "*.t01")
            nombre = My.Computer.FileSystem.GetName(archivo)
            cmdir = "cd " & midirectorio
            comando = "runpkr00.exe -d " & nombre

            SW.WriteLine(cmdir)
            SW.WriteLine(comando)
            Results = SR.ReadToEnd
            Invoke(Finished)
        Catch e As Exception
        End Try
        Next
        SW.Close()
        SR.Close()
    End Sub


Coloca un punto de interrupción en la línea del catch y fíjate en el error que arroja. Si no arroja ningún error no te queda de otra que colocar el punto de interrupción en la primera línea del bucle e ir ejecutando línea por línea para ver el error.
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

rochro

Cita de: El Benjo en 18 Junio 2014, 23:12 PM

Coloca un punto de interrupción en la línea del catch y fíjate en el error que arroja. Si no arroja ningún error no te queda de otra que colocar el punto de interrupción en la primera línea del bucle e ir ejecutando línea por línea para ver el error.

Benjo, realicé el paso a paso para ver el error y al parecer no termina el for porque llega hasta el punto
Código (vbnet) [Seleccionar]
Results = SR.ReadToEnd y de ahi termina o sea no finaliza el for .

El Benjo

Eso significa que se produce el error en esa línea. Me imagino que la función es creada en un hilo independiente del hilo principal, por eso es que no te salta error sólo sale del bucle y de la función... Y YA!

Para comprobar qué tipo de error es coloca el for dentro del tray/catch y coloca el punto de interrupción en la línea correspondiente al cath (como te indiqué en el código anterior) en la variable "e" estará la información correspondiente al error. Dinos cuál es para ver cómo se puede solucionar.
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

rochro

Cita de: El Benjo en 19 Junio 2014, 00:11 AM
Eso significa que se produce el error en esa línea. Me imagino que la función es creada en un hilo independiente del hilo principal, por eso es que no te salta error sólo sale del bucle y de la función... Y YA!

Para comprobar qué tipo de error es coloca el for dentro del tray/catch y coloca el punto de interrupción en la línea correspondiente al cath (como te indiqué en el código anterior) en la variable "e" estará la información correspondiente al error. Dinos cuál es para ver cómo se puede solucionar.

En Results me bota Nothing y como te digo se queda en results y termina. No llega a la parte del Catch.

Código (vbnet) [Seleccionar]
Try
            For Each file As String In My.Computer.FileSystem.GetFiles(midirectorio, FileIO.SearchOption.SearchAllSubDirectories, "*.T01")

                nombre = My.Computer.FileSystem.GetName(file)
                cmdir = "cd " & midirectorio
                comando = "runpkr00.exe -d -s " & nombre
                SW.WriteLine(cmdir)
                SW.WriteLine(comando)
                Results = SR.ReadToEnd
                'SW.Close()
                'SR.Close()
                Invoke(Finished)
            Next
            Catch e As Exception
        End Try
        SW.Close()
        SR.Close()

El Benjo

Ok, intenta llamar a la función dentro del mismo hilo para que la aplicación te bote el error y "a la fuerza" se detenga la ejecución. De esta manera podrás ver por qué la segunda vez que se ejecuta "Results = SR.ReadToEnd" No te funciona.

Estoy viendo otra cosa: No veo en ninguna parte del código que declares la variable Results. Puedes por favor poner cómo la declaras, creo que el error puede estar ahí.
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

rochro

Cita de: El Benjo en 19 Junio 2014, 05:41 AM
Ok, intenta llamar a la función dentro del mismo hilo para que la aplicación te bote el error y "a la fuerza" se detenga la ejecución. De esta manera podrás ver por qué la segunda vez que se ejecuta "Results = SR.ReadToEnd" No te funciona.

Estoy viendo otra cosa: No veo en ninguna parte del código que declares la variable Results. Puedes por favor poner cómo la declaras, creo que el error puede estar ahí.

Aquí te paso todo el código de mi aplicación pero ahora tengo otro problema y es que al momento de quitarle todos los puntos de interrupción ya no me ejecuta, se queda en My.Computer.FileSystem.CopyFile .
Cuando le quito el código
Código (vbnet) [Seleccionar]
'Results = SR.ReadToEnd
            'SW.Close()
            'SR.Close()
            'Invoke(Finished)

y coloco el punto de interrupción en el for each me corre todo, algo debe de pasar con eso.



Código (vbnet) [Seleccionar]
Imports System
Imports System.IO
Imports System.IO.StreamWriter

Public Class Form1
    Inherits System.Windows.Forms.Form

    Private Results As String
    Private Delegate Sub delUpdate()
    Private Finished As New delUpdate(AddressOf UpdateText)

  Private Sub btnexaminar_Click(sender As Object, e As EventArgs) Handles btnexaminar.Click
        Dim Dir As New FolderBrowserDialog
        If Dir.ShowDialog = Windows.Forms.DialogResult.OK Then
            TextBox1.Text = Dir.SelectedPath
        End If
    End Sub

    Private Sub btndat_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btndat.Click
        Dim midirectorio As String = TextBox1.Text
        Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
        If midirectorio = "" Then
            MessageBox.Show("Debe seleccionar la ruta donde se encuentra la data", "Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error)
        Else
            My.Computer.FileSystem.CopyFile("C:\Program Files\convert data\runpkr00.exe", midirectorio & "\runpkr00.exe", Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)
        End If
        CMDThread.Start()

    End Sub

    Private Sub CMDAutomate()
        Dim midirectorio As String = TextBox1.Text
        Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        StartInfo.FileName = "cmd"
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False
        StartInfo.CreateNoWindow = True
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
        Dim comando As String
        Dim cmdir As String
        Dim nombre As String

        For Each file As String In My.Computer.FileSystem.GetFiles(midirectorio, FileIO.SearchOption.SearchAllSubDirectories, "*.T01")

            nombre = My.Computer.FileSystem.GetName(file)
            cmdir = "cd " & midirectorio
            comando = "runpkr00.exe -d -s " & nombre
            SW.WriteLine(cmdir)
            SW.WriteLine(comando)
            'Results = SR.ReadToEnd
            'SW.Close()
            'SR.Close()
            'Invoke(Finished)
        Next
           
        SW.Close()
        SR.Close()

    End Sub

   Private Sub UpdateText()
        Dim midirectorio As String = TextBox1.Text
        Dim strStreamW As Stream = Nothing
        Dim strStreamWriter As StreamWriter = Nothing
        Dim fecha As String = DateTime.Now.ToString("dd MMM HHmmss") & ".txt"
        Windows.Forms.Cursor.Current = Cursors.WaitCursor
        Dim rutarchivo As String = String.Concat(midirectorio, "log-", fecha)
        strStreamW = File.Create(rutarchivo)
        strStreamWriter = New StreamWriter(strStreamW, System.Text.Encoding.Default)
        strStreamWriter.WriteLine(Results)
        strStreamWriter.Close()
    End Sub

El Benjo

Lo que dices sobre las líneas de código:

Código (vbnet) [Seleccionar]
'Results = SR.ReadToEnd
'SW.Close()
'SR.Close()
'Invoke(Finished)


Una parte de eso ya te lo había dicho. No sé si recuerdes que te dije que eliminaras las líneas que cierran los streams. Y lo comentar la línea del invoke() y que funcione, pues tiene sentido. Lo que ocurre es que estás usando mal el delegado. Por alguna raón (no estoy seguro cual) sólo te funcionará el delegado la primera vez que lo utilices. Prueba dejando el bucle de la siguiente manera:

Código (vbnet) [Seleccionar]
For Each file As String In My.Computer.FileSystem.GetFiles(midirectorio, FileIO.SearchOption.SearchAllSubDirectories, "*.T01")
            nombre = My.Computer.FileSystem.GetName(file)
            cmdir = "cd " & midirectorio
            comando = "runpkr00.exe -d -s " & nombre
            SW.WriteLine(cmdir)
            SW.WriteLine(comando)
            Results = SR.ReadToEnd
            Finished = New delUpdate(AddressOf UpdateText)
            Invoke(Finished)
        Next


Es decir, asignando la dirección al delegado cada vez que lo quieras utilizar. En caso de que no te funcione puedes hacerlo dejando el código anterior como te lo dejé, pero eliminando la línea donde asignas la dirección del delegado. Y modificando la función UpdateText() de la siguiente manera:

Código (vbnet) [Seleccionar]
    Private Sub UpdateText()
If Me.InvokeRequired = False Then
        Dim midirectorio As String = TextBox1.Text
        Dim strStreamW As Stream = Nothing
        Dim strStreamWriter As StreamWriter = Nothing
        Dim fecha As String = DateTime.Now.ToString("dd MMM HHmmss") & ".txt"
        Windows.Forms.Cursor.Current = Cursors.WaitCursor
        Dim rutarchivo As String = String.Concat(midirectorio, "log-", fecha)
        strStreamW = File.Create(rutarchivo)
        strStreamWriter = New StreamWriter(strStreamW, System.Text.Encoding.Default)
        strStreamWriter.WriteLine(Results)
        strStreamWriter.Close()
Else
Dim D As delUpdate = new delUpdate(AddressOf UpdateText)
Me.Invoke(D)
End If
    End Sub


Si cometí un error al escribir los nombres de las propiedades, busca las correctas (es que no estoy escribiendo desde Visual Studio).

Y sobre lo que dices del FileCopy(), la verdad no tengo idea de a qué se deba. ¿Qué error te da el depurador cuando la aplicación crashea?
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.