elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Tutorial básico de Quickjs


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  EJECUTAR CMD EN APLICACIÓN .NET
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: EJECUTAR CMD EN APLICACIÓN .NET  (Leído 6,876 veces)
rochro

Desconectado Desconectado

Mensajes: 42


Ver Perfil
EJECUTAR CMD EN APLICACIÓN .NET
« en: 11 Noviembre 2014, 15:39 pm »

Buen día a todos, quisiera que me apoyen en poder ver cual es mi error ya que al momento de ejecutar la app se marca error en la linea txtResults.Text = SR.ReadToEnd.
La idea es que en vez que se muestre en la ventana del cmd, figure en el cuadro de texto txtResults y sería mucho mejor si fuera continuo o sea el resultado de ping 127.0.0.1 -t figure en el cuadro de texto.

Código
  1. Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
  2.        Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
  3.        CMDThread.Start()
  4.    End Sub
  5.    Private Sub CMDAutomate()
  6.        Dim PROCESO As New Process
  7.        Dim INFO As New System.Diagnostics.ProcessStartInfo
  8.        INFO.FileName = "cmd"
  9.        INFO.RedirectStandardInput = True
  10.        INFO.RedirectStandardOutput = True
  11.        INFO.UseShellExecute = False
  12.        PROCESO.StartInfo = INFO
  13.        PROCESO.Start()
  14.        Dim SR As System.IO.StreamReader = PROCESO.StandardOutput
  15.        Dim SW As System.IO.StreamWriter = PROCESO.StandardInput
  16.        Dim comandoping As String = String.Concat("ping ", TextBox1.Text, ".", TextBox2.Text, ".", TextBox3.Text, ".", TextBox4.Text)
  17.        SW.WriteLine(comandoping)
  18.        SW.WriteLine("exit")
  19.        txtResults.Text = SR.ReadToEnd
  20.        SW.Close()
  21.        SR.Close()
  22.    End Sub

Gracias por todo. Saludos.


En línea

Eleкtro
Ex-Staff
*
Conectado Conectado

Mensajes: 9.878



Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #1 en: 11 Noviembre 2014, 18:29 pm »

al momento de ejecutar la app se marca error en la linea txtResults.Text = SR.ReadToEnd.

1. Cuando tengas un error, por favor da los detalles necesarios para poder ayudarte. El mensaje exacto de error que te indica el debugger de VisualStudio. ya que de lo contrario estamos haciendo el paripé sin tener información precisa.

Sea cual sea el error que te indique imagino que es porque estás intentando modificar un control desde un Thread distinto al Thread donde creaste el cotnrol. es decir, tienes el control txtResults en el thread "X" e intentas modificarlo desde el thread "Y", no puedes modificar un control así como así desde otro thread, primero debes comprobar si el control necesita ser invocado, y después, invocarlo.

Ejemplo:
Código
  1. Imports System.Threading.Tasks
  2.  
  3. Public Class Form1
  4.  
  5.    ''' <summary>
  6.    ''' The CMD <see cref="System.Diagnostics.Process"/> instance.
  7.    ''' </summary>
  8.    Private WithEvents cmdProcess As New Process With
  9.        {
  10.            .EnableRaisingEvents = True,
  11.            .StartInfo = New ProcessStartInfo With
  12.                             {
  13.                                .FileName = "cmd.exe",
  14.                                .Arguments = String.Empty,
  15.                                .RedirectStandardInput = False,
  16.                                .RedirectStandardOutput = True,
  17.                                .RedirectStandardError = True,
  18.                                .UseShellExecute = False,
  19.                                .CreateNoWindow = True
  20.                             }
  21.        }
  22.  
  23.    ''' <summary>
  24.    ''' Gets the ping commandline arguments.
  25.    ''' </summary>
  26.    Private ReadOnly Property PingArguments As String
  27.        Get
  28.            Return String.Format("ping.exe ""{0}.{1}.{2}.{3}""",
  29.                                TextBox1.Text, TextBox2.Text,
  30.                                TextBox3.Text, TextBox4.Text)
  31.        End Get
  32.    End Property
  33.  
  34.    Private Sub btnSend_Click(ByVal sender As Object, ByVal e As EventArgs) _
  35.    Handles btnsend.Click
  36.  
  37.        Task.Factory.StartNew(AddressOf CMDAutomate)
  38.  
  39.    End Sub
  40.  
  41.    Private Sub CMDAutomate()
  42.  
  43.        With Me.cmdProcess
  44.  
  45.            .StartInfo.Arguments = String.Format("/C ""{0}""", Me.PingArguments)
  46.            .Start()
  47.            .BeginOutputReadLine()
  48.            .BeginErrorReadLine()
  49.            .WaitForExit()
  50.  
  51.        End With
  52.  
  53.    End Sub
  54.  
  55.    ''' <summary>
  56.    ''' Occurs when an application writes to its redirected <see cref="System.Diagnostics.Process.StandardOutput"/> stream.
  57.    ''' Occurs when an application writes to its redirected <see cref="System.Diagnostics.Process.StandardError"/>  stream.
  58.    ''' </summary>
  59.    Private Sub cmdProcess_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs) _
  60.    Handles cmdProcess.OutputDataReceived,
  61.            cmdProcess.ErrorDataReceived
  62.  
  63.        Select Case txtResults.InvokeRequired
  64.  
  65.            Case True
  66.                txtResults.Invoke(Sub() txtResults.AppendText("" & e.Data))
  67.                txtResults.Invoke(Sub() txtResults.AppendText(Environment.NewLine))
  68.  
  69.            Case Else
  70.                txtResults.AppendText(e.Data)
  71.                txtResults.AppendText(Environment.NewLine)
  72.  
  73.        End Select
  74.  
  75. #If DEBUG Then
  76.        ' Debug.WriteLine(e.Data)
  77. #End If
  78.  
  79.    End Sub
  80.  
  81.    ''' <summary>
  82.    ''' Occurs when a <see cref="System.Diagnostics.Process"/> exits.
  83.    ''' </summary>
  84.    Private Sub cmdProcess_Exited(ByVal sender As Object, ByVal e As EventArgs) _
  85.    Handles cmdProcess.Exited
  86.  
  87.        Debug.WriteLine(String.Format("cmdProcess has exited with exit code: {0}",
  88.                                      DirectCast(sender, Process).ExitCode))
  89.  
  90.    End Sub
  91.  
  92. End Class

Saludos


« Última modificación: 11 Noviembre 2014, 18:53 pm por Eleкtro » En línea



rochro

Desconectado Desconectado

Mensajes: 42


Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #2 en: 11 Noviembre 2014, 19:13 pm »


Sea cual sea el error que te indique imagino que es porque estás intentando modificar un control desde un Thread distinto al Thread donde creaste el cotnrol. es decir, tienes el control txtResults en el thread "X" e intentas modificarlo desde el thread "Y", no puedes modificar un control así como así desde otro thread, primero debes comprobar si el control necesita ser invocado, y después, invocarlo.


Woww.. en serio eres un capo en esto. Muchas gracias por tu ayuda. Era exactamente lo que queria. Prometo que seré mas cuidadosa con mis publicaciones y poner la información completa.

Gracias por todo.  :D
En línea

Eleкtro
Ex-Staff
*
Conectado Conectado

Mensajes: 9.878



Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #3 en: 11 Noviembre 2014, 19:41 pm »

De nada, para eso estamos, de todas formas esto que te expliqué es quizás lo más básico de la programación asíncrona en .Net.

Se me olvidó comentar algo importante para que no te pierdas en el largo código que te mostré (en caso de que te hayas perdido un poco xD), todo ese código es solo una mejora del código que tú publicaste... por si lo quieres usar de esa manera (suscribiéndote a los eventos de la instancia del proceso), pero lo importante del código es lo siguiente, donde llamo a la propiedad .Invokerequired y el método .Invoke desde el subproceso/thread secundario:

Cita de: Eleкtro
Código
  1. ...
  2.        Select Case txtResults.InvokeRequired
  3.  
  4.           Case True
  5.               txtResults.Invoke(Sub() txtResults.AppendText("" & e.Data))
  6.               txtResults.Invoke(Sub() txtResults.AppendText(Environment.NewLine))
  7.  
  8.           Case Else
  9.               txtResults.AppendText(e.Data)
  10.               txtResults.AppendText(Environment.NewLine)
  11.  
  12.       End Select
  13. ...


Control.InvokeRequired Property - MSDN
Control.Invoke(Lambda) Method - MSDN

Saludos
« Última modificación: 11 Noviembre 2014, 19:43 pm por Eleкtro » En línea



rochro

Desconectado Desconectado

Mensajes: 42


Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #4 en: 12 Noviembre 2014, 17:56 pm »

De nada, para eso estamos, de todas formas esto que te expliqué es quizás lo más básico de la programación asíncrona en .Net.


Tengo un inconveniente y quisiera que me ayudes. En el código que me entregaste sólo aumenté el -t al comando ping pero al crear un linklabel para que vacie los campos, el comando ping se sigue ejecutando. Como lo puedo parar?

Código
  1. ...
  2. Private ReadOnly Property PingArguments As String
  3.        Get
  4.            Return String.Format("ping.exe ""{0}.{1}.{2}.{3}"" -t",
  5.                                TextBox1.Text, TextBox2.Text,
  6.                                TextBox3.Text, TextBox4.Text)
  7.        End Get
  8.    End Property
  9. ...
  10.  
  11. Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
  12.        Dim x As Control
  13.        For Each x In Me.Controls
  14.            If TypeOf x Is System.Windows.Forms.TextBox Then x.Text = ""
  15.        Next
  16.  
  17.    End Sub
En línea

Eleкtro
Ex-Staff
*
Conectado Conectado

Mensajes: 9.878



Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #5 en: 12 Noviembre 2014, 18:24 pm »

Como lo puedo parar?

Depende.

1) ¿Al clickar en el linklabel es cuando quieres detener Ping?

Debes detener la ejecución del thread que está corriendo la cmd, si estás usando la Class Thread entonces puedes llamar al método Thread.Abort, si estás usando la class Tasks entonces puedes llamar al método Task.Cancel usando un token de cancelación para esa Task.

O también puedes hacerlo desde la winAPi, con la función TerminateThread: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686717%28v=vs.85%29.aspx

2) ¿Estás usando la misma Task del código que te mostré?;
Muestra el resto del código relevante, es decir, la declaración del thread y el método del thread (donde ejecutas la cmd)

EDITO: De todas formas hace tiempo escribí un ejemplo de uso de la class Tasks para cancelar una Task, te podría servir hasta nueva respuesta:

Código
  1. #Region " TASK Example "
  2.  
  3. Public Class Form1
  4.  
  5.    ' NORMAL TASK USAGE:
  6.    ' ------------------
  7.    Private Task1 As Threading.Tasks.Task
  8.    Private Task1CTS As New Threading.CancellationTokenSource
  9.    Private Task1CT As Threading.CancellationToken = Task1CTS.Token
  10.  
  11.    Private Sub MyTask1(ByVal CancellationToken As Threading.CancellationToken)
  12.  
  13.        For x As Integer = 0 To 9999
  14.  
  15.            If Not CancellationToken.IsCancellationRequested Then
  16.                Debug.Print("Task1: " & x)
  17.            Else
  18.                MsgBox(String.Format("Task1 Canceled at ""{0}""", x))
  19.                Exit Sub
  20.            End If
  21.  
  22.        Next x
  23.  
  24.    End Sub
  25.  
  26.    ' ANONYMOUS TASK METHOD:
  27.    ' ---------------------
  28.    Private Task2 As Threading.Tasks.Task
  29.    Private Task2CTS As New Threading.CancellationTokenSource
  30.    Private Task2CT As Threading.CancellationToken = Task2CTS.Token
  31.  
  32.    Private Delegate Function Task2Delegate(ByVal CancellationToken As Threading.CancellationToken)
  33.  
  34.    Private MyTask2 As Task2Delegate =
  35.      Function(CancellationToken As Threading.CancellationToken) As Boolean
  36.  
  37.          For x As Integer = 0 To 9999
  38.  
  39.              If Not CancellationToken.IsCancellationRequested Then
  40.                  Debug.Print("Task2: " & x)
  41.              Else
  42.                  MsgBox(String.Format("Task2 Canceled at ""{0}""", x))
  43.                  Return False
  44.              End If
  45.  
  46.          Next x
  47.  
  48.          Return True
  49.  
  50.      End Function
  51.  
  52.    Private Sub TaskTest() Handles MyBase.Shown
  53.  
  54.        ' Run an asynchronous Task.
  55.        Task1 = Threading.Tasks.Task.Factory.StartNew(Sub() MyTask1(Task1CT), Task1CT)
  56.  
  57.        ' Wait 2 seconds (Just to demonstrate this example)
  58.        Threading.Thread.Sleep(2 * 1000)
  59.  
  60.        ' Cancel the Task.
  61.        Task1CTS.Cancel()
  62.  
  63.        ' Wait for the Task to finish the being cancelled.
  64.        Task1.Wait()
  65.  
  66.        ' Show the task status
  67.        MsgBox(Task1.Status.ToString) ' Result: RanToCompletion
  68.  
  69.        ' ReStart the Task1.
  70.        Task1 = Threading.Tasks.Task.Factory.StartNew(Sub() MyTask1(Task1CT), Task1CT)
  71.  
  72.        ' Start the Task2
  73.        Task2 = Threading.Tasks.Task.Factory.StartNew(Of Boolean)(Function() MyTask2(Task2CT), Task2CT)
  74.  
  75.        ' Wait for both Tasks to finish their execution.
  76.        Threading.Tasks.Task.WaitAll()
  77.  
  78.    End Sub
  79.  
  80. End Class
  81.  
  82. #End Region

Saludos
« Última modificación: 12 Noviembre 2014, 18:31 pm por Eleкtro » En línea



rochro

Desconectado Desconectado

Mensajes: 42


Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #6 en: 13 Noviembre 2014, 15:51 pm »

Depende.

1) ¿Al clickar en el linklabel es cuando quieres detener Ping?


Si. Quiero que al hacer clic en el linklabel se cancele el task. Trato de entender el código pero ya me confundí :(

Disculpa por tanta molestia elektro.
« Última modificación: 13 Noviembre 2014, 16:35 pm por rochro » En línea

Eleкtro
Ex-Staff
*
Conectado Conectado

Mensajes: 9.878



Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #7 en: 13 Noviembre 2014, 16:54 pm »

No es ninguna molestía, ayudar es mi hobbie favorito (y más cuando se trata de VB.Net) :)

He añadido el método StartTask, CancelTask, y el linklabel al código que mostré arriba, aquí esta todo lo necesario:

Código
  1. Imports System.Threading
  2. Imports System.Threading.Tasks
  3.  
  4. Public Class Form1
  5.  
  6.    Private cmdTask As Task
  7.    Private cmdTaskCTS As New CancellationTokenSource
  8.    Private cmdTaskCT As CancellationToken
  9.  
  10.    ''' <summary>
  11.    ''' The CMD <see cref="System.Diagnostics.Process"/> instance.
  12.    ''' </summary>
  13.    Private WithEvents cmdProcess As New Process With
  14.        {
  15.            .EnableRaisingEvents = True,
  16.            .StartInfo = New ProcessStartInfo With
  17.                             {
  18.                                .FileName = "cmd.exe",
  19.                                .Arguments = String.Empty,
  20.                                .RedirectStandardInput = False,
  21.                                .RedirectStandardOutput = True,
  22.                                .RedirectStandardError = True,
  23.                                .UseShellExecute = False,
  24.                                .CreateNoWindow = True
  25.                             }
  26.        }
  27.  
  28.    ''' <summary>
  29.    ''' Gets the ping commandline arguments.
  30.    ''' </summary>
  31.    Private ReadOnly Property PingArguments As String
  32.        Get
  33.            Return String.Format("ping.exe -t ""{0}.{1}.{2}.{3}""",
  34.                                TextBox1.Text, TextBox2.Text,
  35.                                TextBox3.Text, TextBox4.Text)
  36.        End Get
  37.    End Property
  38.  
  39.    Private Sub btnSend_Click(ByVal sender As Object, ByVal e As EventArgs) _
  40.    Handles btnsend.Click
  41.  
  42.        Me.StartTask()
  43.  
  44.    End Sub
  45.  
  46.    Private Sub CMDAutomate()
  47.  
  48.        With Me.cmdProcess
  49.  
  50.            .StartInfo.Arguments = String.Format("/C ""{0}""", Me.PingArguments)
  51.            .Start()
  52.            .BeginOutputReadLine()
  53.            .BeginErrorReadLine()
  54.            .WaitForExit(Integer.MaxValue)
  55.  
  56.        End With
  57.  
  58.    End Sub
  59.  
  60.    ''' <summary>
  61.    ''' Occurs when an application writes to its redirected <see cref="System.Diagnostics.Process.StandardOutput"/> stream.
  62.    ''' Occurs when an application writes to its redirected <see cref="System.Diagnostics.Process.StandardError"/>  stream.
  63.    ''' </summary>
  64.    Private Sub cmdProcess_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs) _
  65.    Handles cmdProcess.OutputDataReceived,
  66.            cmdProcess.ErrorDataReceived
  67.  
  68.        Select Case txtresults.InvokeRequired
  69.  
  70.            Case True
  71.                txtresults.Invoke(Sub() txtresults.AppendText("" & e.Data))
  72.                txtresults.Invoke(Sub() txtresults.AppendText(Environment.NewLine))
  73.  
  74.            Case Else
  75.                txtresults.AppendText(e.Data)
  76.                txtresults.AppendText(Environment.NewLine)
  77.  
  78.        End Select
  79.  
  80. #If DEBUG Then
  81.        ' Debug.WriteLine(e.Data)
  82. #End If
  83.  
  84.    End Sub
  85.  
  86.    ''' <summary>
  87.    ''' Occurs when a <see cref="System.Diagnostics.Process"/> exits.
  88.    ''' </summary>
  89.    Private Sub cmdProcess_Exited(ByVal sender As Object, ByVal e As EventArgs) _
  90.    Handles cmdProcess.Exited
  91.  
  92.        Debug.WriteLine(String.Format("cmdProcess has exited with exit code: {0}",
  93.                                      DirectCast(sender, Process).ExitCode))
  94.  
  95.    End Sub
  96.  
  97.    Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) _
  98.    Handles LinkLabel1.LinkClicked
  99.  
  100.        ' limpio el texto de cada textbox.
  101.        For Each tb As TextBox In Me.Controls.OfType(Of TextBox)()
  102.            tb.Clear()
  103.        Next tb
  104.  
  105.        ' cancelo la tarea en segundo plano.
  106.        Me.CancelTask()
  107.  
  108.    End Sub
  109.  
  110.    Private Sub StartTask()
  111.  
  112.        Me.cmdTask = Task.Factory.StartNew(AddressOf CMDAutomate)
  113.        Me.cmdTaskCTS = New Threading.CancellationTokenSource
  114.        Me.cmdTaskCT = cmdTaskCTS.Token
  115.  
  116.    End Sub
  117.  
  118.    Private Sub CancelTask()
  119.  
  120.        ' Si el proceso no se ha detenido...
  121.        If Not Me.cmdProcess.HasExited Then
  122.  
  123.            With Me.cmdProcess
  124.                ' cancelo la lectura de los outputs.
  125.                .CancelOutputRead()
  126.                .CancelErrorRead()
  127.                .Kill() ' mato el proceso (cmd.exe)
  128.            End With
  129.  
  130.            ' Cancelo la tarea en segundo plano.
  131.            Me.cmdTaskCTS.Cancel()
  132.            ' Espero a que la tarea se haya cancelado.
  133.            Me.cmdTask.Wait()
  134.  
  135.        End If
  136.  
  137.    End Sub
  138.  
  139. End Class

EDITO: Fíjate que también cambié esto en el método CMDAutomate, para que funcionase del modo esperado:
Citar
Código
  1. .WaitForExit(Integer.MaxValue)

Saludos.
« Última modificación: 13 Noviembre 2014, 17:04 pm por Eleкtro » En línea



rochro

Desconectado Desconectado

Mensajes: 42


Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #8 en: 18 Noviembre 2014, 17:57 pm »

No es ninguna molestía, ayudar es mi hobbie favorito (y más cuando se trata de VB.Net) :)

Gracias Elektro. Como que ya voy entendiendo un poco este tema de los tasks. Ahora no se como hacer, ya que como se va avanzando con esta pequeña app se me ocurre si hay alguna manera de que grabe los datos del textbox y por mas que se cierre y vuelva a abrir aparece con esos valores hasta que se cambie.

Gracias por tu atención :)
En línea

Eleкtro
Ex-Staff
*
Conectado Conectado

Mensajes: 9.878



Ver Perfil
Re: EJECUTAR CMD EN APLICACIÓN .NET
« Respuesta #9 en: 18 Noviembre 2014, 18:35 pm »

se me ocurre si hay alguna manera de que grabe los datos del textbox y por mas que se cierre y vuelva a abrir aparece con esos valores hasta que se cambie.

Hay muchas maneras de hacer eso, lo que más sencillo te resultará es utilizar la infrastructura de My.Settings.

Puedes crear la propiedad desde las opciones del proyecto, y luego acceder a dicha propiedad en tiempo de ejecución para guardar/cargar valores.

Es muy sencillo, pero lee un poco acerca de ello para enterarte:

Managing Application Settings
Using My.Settings in Visual Basic 2005
How to: Change User Settings in Visual Basic

Saludos
« Última modificación: 18 Noviembre 2014, 18:38 pm por Eleкtro » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Ejecutar una aplicacion en Web
Programación Visual Basic
CsarGR 4 2,280 Último mensaje 2 Abril 2007, 16:23 pm
por ~~
Ejecutar aplicacion (Winsock)
Programación Visual Basic
mdg 2 1,941 Último mensaje 26 Diciembre 2007, 23:55 pm
por ~~
Ejecutar aplicacion externa con c#
.NET (C#, VB.NET, ASP)
kateme 1 8,647 Último mensaje 11 Septiembre 2008, 19:29 pm
por MANULOMM
Problemas al ejecutar aplicacion .net en XP
.NET (C#, VB.NET, ASP)
Skeletron 9 7,092 Último mensaje 18 Mayo 2009, 13:13 pm
por Meta
Ejecutar desde PHP una aplicación GUI
GNU/Linux
SnakeDrak 2 2,862 Último mensaje 24 Octubre 2010, 23:05 pm
por SnakeDrak
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines