|
6261
|
Programación / .NET (C#, VB.NET, ASP) / Re: EJECUTAR CMD EN APLICACIÓN .NET
|
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: Imports System.Threading Imports System.Threading.Tasks Public Class Form1 Private cmdTask As Task Private cmdTaskCTS As New CancellationTokenSource Private cmdTaskCT As CancellationToken ''' <summary> ''' The CMD <see cref="System.Diagnostics.Process"/> instance. ''' </summary> Private WithEvents cmdProcess As New Process With { .EnableRaisingEvents = True, .StartInfo = New ProcessStartInfo With { .FileName = "cmd.exe", .Arguments = String.Empty, .RedirectStandardInput = False, .RedirectStandardOutput = True, .RedirectStandardError = True, .UseShellExecute = False, .CreateNoWindow = True } } ''' <summary> ''' Gets the ping commandline arguments. ''' </summary> Private ReadOnly Property PingArguments As String Get Return String.Format("ping.exe -t ""{0}.{1}.{2}.{3}""", TextBox1.Text, TextBox2.Text, TextBox3.Text, TextBox4.Text) End Get End Property Private Sub btnSend_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles btnsend.Click Me.StartTask() End Sub Private Sub CMDAutomate() With Me.cmdProcess .StartInfo.Arguments = String.Format("/C ""{0}""", Me.PingArguments) .Start() .BeginOutputReadLine() .BeginErrorReadLine() .WaitForExit(Integer.MaxValue) End With End Sub ''' <summary> ''' Occurs when an application writes to its redirected <see cref="System.Diagnostics.Process.StandardOutput"/> stream. ''' Occurs when an application writes to its redirected <see cref="System.Diagnostics.Process.StandardError"/> stream. ''' </summary> Private Sub cmdProcess_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs) _ Handles cmdProcess.OutputDataReceived, cmdProcess.ErrorDataReceived Select Case txtresults.InvokeRequired Case True txtresults.Invoke(Sub() txtresults.AppendText("" & e.Data)) txtresults.Invoke(Sub() txtresults.AppendText(Environment.NewLine)) Case Else txtresults.AppendText(e.Data) txtresults.AppendText(Environment.NewLine) End Select ' Debug.WriteLine(e.Data) #End If End Sub ''' <summary> ''' Occurs when a <see cref="System.Diagnostics.Process"/> exits. ''' </summary> Private Sub cmdProcess_Exited(ByVal sender As Object, ByVal e As EventArgs) _ Handles cmdProcess.Exited Debug. WriteLine(String. Format("cmdProcess has exited with exit code: {0}", DirectCast(sender, Process).ExitCode)) End Sub Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) _ Handles LinkLabel1.LinkClicked ' limpio el texto de cada textbox. For Each tb As TextBox In Me.Controls.OfType(Of TextBox)() tb.Clear() Next tb ' cancelo la tarea en segundo plano. Me.CancelTask() End Sub Private Sub StartTask() Me.cmdTask = Task.Factory.StartNew(AddressOf CMDAutomate) Me.cmdTaskCTS = New Threading.CancellationTokenSource Me.cmdTaskCT = cmdTaskCTS.Token End Sub Private Sub CancelTask() ' Si el proceso no se ha detenido... If Not Me.cmdProcess.HasExited Then With Me.cmdProcess ' cancelo la lectura de los outputs. .CancelOutputRead() .CancelErrorRead() .Kill() ' mato el proceso (cmd.exe) End With ' Cancelo la tarea en segundo plano. Me.cmdTaskCTS.Cancel() ' Espero a que la tarea se haya cancelado. Me.cmdTask.Wait() End If End Sub End Class
EDITO: Fíjate que también cambié esto en el método CMDAutomate, para que funcionase del modo esperado: .WaitForExit(Integer.MaxValue)
Saludos.
|
|
|
6262
|
Programación / Programación General / Re: duda con IDE para programar
|
en: 12 Noviembre 2014, 23:27 pm
|
Creo que aquí hay una pequeña confusión, lo que se está comentando no es la CMD ni MS-DOS en si mismo, sinó la programación orientada a DOS o para Win16, realmente no se si es eso lo que pides, es decir, ¿crear una GUI para un entorno de 8/16 Bits?, ¿algo como esto de aquí abajo?, pero estamos en el 2014... ¿a donde vas con eso que pides? :-/, ¿o por lo contrario quieres una IDE moderna con un framework capaz de simular este diseño de los años 80-90? :-/ Ese tipo de interfaces ya solo se ven como menues de un LiveCD, aplicaciones muy antiguas bajo un WinPE antiguo, o el BootMenu de Windows (y ya ni eso en Windows 8), no pretendo cuestionarte pero si no tienes una razón de peso me parece una involución totalmente innecesaria, anti-estética e inproductiva, ¿realmente necesitas desarrollar una aplicación de ese estilo?. Respondiendo a tu pregunta: Sinceramente... no lo se, pero lo que está claro es que cualquier IDE de aquella época que cumpla el requisito de tener un VisualBuilder/Designer te serviría: WATCOM C/C++ 10a 16-bit development for the following platforms: OS/2 1.x DOS Windows 3.x applications Visual Basic for DOS ¿Más actuales?, lo desconozco, quizás la IDE de WinBatch haga algo parecido: Winbatch is a Microsoft Windows scripting language developed by Wilson WindowWare. Its environment includes an interpreter and a code editor along with a dialog designer and optional compiler to create self-contained executables. Its language structure and syntax is a cross between DOS batch command, Basic and C. Saludos
|
|
|
6264
|
Programación / .NET (C#, VB.NET, ASP) / Re: DUDA ASP.NET C#
|
en: 12 Noviembre 2014, 20:00 pm
|
Buenas. No manejo ASP.Net, ni tampoco tengo muy claro si esto es lo que andas buscando, pero he intentado reproducir el problema que tienes en tecnología WinForms. Mira a ver si el siguiente source te resuelve todas o al menos alguna de tus dudas... Para las operaciones artiméticas he recurrido a LINQ ya que se puede utilizar de forma "global". Descarga del proyecto: https://www.mediafire.com/?y1yifofj0s8i6r8VB.Net:Public Class Form1 Private WithEvents dt As DataTable Private ReadOnly columns As DataColumn() = { New DataColumn("Codigo_Articulo", GetType(String)), New DataColumn("Descripcion", GetType(String)), New DataColumn("Cantidad", GetType(Integer)), New DataColumn("Precio", GetType(Decimal)) } ' añadir fila Private Sub Button_añadir_Click() Handles Button_añadir.Click If dt Is Nothing Then dt = New DataTable dt.Columns.AddRange(columns) dgvCostos.DataSource = dt ' dgvCostos.DataBind() End If Dim dr As DataRow = dt.NewRow() dr(columns(0)) = txtCodArt.Text dr(columns(1)) = txtDescripcion.Text dr(columns(2)) = txtCantidad.Text dr(columns(3)) = txtPrecio.Text dt.Rows.Add(dr) dt.AcceptChanges() End Sub ' Sumar y Multiplicar Private Sub Button_sumar_Click(sender As Object, e As EventArgs) Handles Button_sumar.Click ' total de cantidades Dim sumaCantidades As Integer = (From row As DataRow In dt.Rows Select CType(row.Item(2I), Integer)).Sum ' total de precios Dim sumaPrecios As Integer = (From row As DataRow In dt.Rows Select CType(row.Item(3I), Integer)).Sum ' un type anónimo, el cual contiene cada DataRow, y cada "cantidad * precio" de cada DataRow. Dim multi = From row As DataRow In dt.Rows Let multiply As Integer = CType(row.Item(2I), Integer) * CType(row.Item(3I), Integer) Dim sb As New System.Text.StringBuilder sb.AppendLine(String.Format("Cantidad total: {0}", CStr(sumaCantidades))) sb.AppendLine(String.Format("Precio total: {0}", CStr(sumaPrecios))) sb.AppendLine() For index As Integer = 0 To (multi.Count - 1) sb.AppendLine(String.Format("Row: {0}, Cantidad: {1}, Precio: {2}, Precio total: {3}", CStr(index), CStr(multi(index).row.Item(2I)), CStr(multi(index).row.Item(3I)), CStr(multi(index).multiply))) Next index MessageBox.Show(sb.ToString) End Sub End Class
C# (traducción online)using Microsoft.VisualBasic; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; public class Form1 { private DataTable dt; private readonly DataColumn[] columns = { new DataColumn ("Codigo_Articulo", typeof(string)), new DataColumn ("Descripcion", typeof(string)), }; // añadir fila private void Button_añadir_Click() { this.dt = (DataTable)dgvCostos.DataSource; if (dt == null) { dt.Columns.AddRange(columns); dgvCostos.DataSource = dt; // dgvCostos.DataBind() } DataRow dr = dt.NewRow(); dr(columns(0)) = txtCodArt.Text; dr(columns(1)) = txtDescripcion.Text; dr(columns(2)) = txtCantidad.Text; dr(columns(3)) = txtPrecio.Text; dt.Rows.Add(dr); dt.AcceptChanges(); } // Sumar y Multiplicar private void Button_sumar_Click(object sender, EventArgs e) { // total de cantidades int sumaCantidades = (from row in dt.RowsConvert.ToInt32(row.Item(2))).Sum; // total de precios int sumaPrecios = (from row in dt.RowsConvert.ToInt32(row.Item(3))).Sum; // un type anónimo, el cual contiene cada DataRow, y cada "cantidad * precio" de cada DataRow. dynamic multi = from row in dt.RowsConvert.ToInt32(row.Item(2)) * Convert.ToInt32(row.Item(3))int; System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.AppendLine(string.Format("Cantidad total: {0}", Convert.ToString(sumaCantidades))); sb.AppendLine(string.Format("Precio total: {0}", Convert.ToString(sumaPrecios))); sb.AppendLine(); for (int index = 0; index <= (multi.Count - 1); index++) { sb.AppendLine(string.Format("Row: {0}, Cantidad: {1}, Precio: {2}, Precio total: {3}", Convert.ToString(index), Convert.ToString(multi(index).row.Item(2)), Convert.ToString(multi(index).row.Item(3)), Convert.ToString(multi(index).multiply))); } MessageBox.Show(sb.ToString); } } //======================================================= //Service provided by Telerik (www.telerik.com) //Conversion powered by NRefactory. //Twitter: @telerik //Facebook: facebook.com/telerik //=======================================================
|
|
|
6265
|
Programación / .NET (C#, VB.NET, ASP) / Re: EJECUTAR CMD EN APLICACIÓN .NET
|
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.aspx2) ¿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: #Region " TASK Example " Public Class Form1 ' NORMAL TASK USAGE: ' ------------------ Private Task1 As Threading.Tasks.Task Private Task1CTS As New Threading.CancellationTokenSource Private Task1CT As Threading.CancellationToken = Task1CTS.Token Private Sub MyTask1(ByVal CancellationToken As Threading.CancellationToken) For x As Integer = 0 To 9999 If Not CancellationToken.IsCancellationRequested Then Debug. Print("Task1: " & x ) Else MsgBox(String.Format("Task1 Canceled at ""{0}""", x)) Exit Sub End If Next x End Sub ' ANONYMOUS TASK METHOD: ' --------------------- Private Task2 As Threading.Tasks.Task Private Task2CTS As New Threading.CancellationTokenSource Private Task2CT As Threading.CancellationToken = Task2CTS.Token Private Delegate Function Task2Delegate(ByVal CancellationToken As Threading.CancellationToken) Private MyTask2 As Task2Delegate = Function(CancellationToken As Threading.CancellationToken) As Boolean For x As Integer = 0 To 9999 If Not CancellationToken.IsCancellationRequested Then Debug. Print("Task2: " & x ) Else MsgBox(String.Format("Task2 Canceled at ""{0}""", x)) Return False End If Next x Return True End Function Private Sub TaskTest() Handles MyBase.Shown ' Run an asynchronous Task. Task1 = Threading.Tasks.Task.Factory.StartNew(Sub() MyTask1(Task1CT), Task1CT) ' Wait 2 seconds (Just to demonstrate this example) Threading.Thread.Sleep(2 * 1000) ' Cancel the Task. Task1CTS.Cancel() ' Wait for the Task to finish the being cancelled. Task1.Wait() ' Show the task status MsgBox(Task1.Status.ToString) ' Result: RanToCompletion ' ReStart the Task1. Task1 = Threading.Tasks.Task.Factory.StartNew(Sub() MyTask1(Task1CT), Task1CT) ' Start the Task2 Task2 = Threading.Tasks.Task.Factory.StartNew(Of Boolean)(Function() MyTask2(Task2CT), Task2CT) ' Wait for both Tasks to finish their execution. Threading.Tasks.Task.WaitAll() End Sub End Class #End Region
Saludos
|
|
|
6266
|
Programación / .NET (C#, VB.NET, ASP) / Re: eliminar registros con ceros
|
en: 12 Noviembre 2014, 12:07 pm
|
No hay "doble cero" Luis, son "0" sin más, ni tampoco "01" etc, recuerda que estás usando una lista numérica, no de String, el resto de ceros los añades (de forma "temporal") solamente para mostrarlos en el listbox con ese formato de ceros. combinations.ForEach(Sub(combination As List(Of Integer)) ListBox2.Items.Add(String.Join(", ", From value As Integer In combination Select If(value.ToString.Length = 1I, value.ToString.Insert(0I, "0"c), value.ToString)))
Así que puedes comprobar si el primer elemento de cada sub-lista es "0", eliminar la sub-lista, y ya está: Public Class Form1 Private Sub test() Handles MyBase.Shown ' instancio la lista que contiene las sub-listas Dim lists As New List(Of List(Of Integer)) ' instancio las sub-listas Dim list1 As New List(Of Integer) From {0, 1, 3, 4, 5, 6} Dim list2 As New List(Of Integer) From {0, 1, 4, 5, 6, 8} Dim list3 As New List(Of Integer) From {0, 1, 4, 5, 6, 9} Dim list4 As New List(Of Integer) From {1, 2, 4, 5, 6, 18} Dim list5 As New List(Of Integer) From {10, 20, 45, 88, 87, 90} ' añado las sub-listas lists.AddRange({list1, list2, list3, list4, list5}) ' elimino las sub-listas cuyo primer elemento sea "0" lists.RemoveAll(Function(list As List(Of Integer)) list.First = 0) ' Compruebo las listas que han quedado... Dim sb As New System.Text.StringBuilder For Each list As List(Of Integer) In lists sb.AppendLine(String.Join(", ", list)) Next MessageBox.Show(sb.ToString, "Listas que no se han eliminado", MessageBoxButtons.OK, MessageBoxIcon.Information) End Sub End Class
Deberías verte capaz de hacer el resto de modificaciones en caso de que necesite modificaciones para tus necesidades, simplemente puedes repetir esta instrucción con la condición que quieras comprobar: lists.RemoveAll(Function(list As List(Of Integer)) list.First = 0)
lists.RemoveAll(...list.Contains(0)...), por ejemplo... también puedes añadirle los "0" de forma temporal para crear esa condición y evaluarla, de la mimsma manera que en el código que cité donde añades los "0". saludos
|
|
|
6267
|
Programación / .NET (C#, VB.NET, ASP) / Re: Unas dudas sobre .NET
|
en: 12 Noviembre 2014, 11:50 am
|
Si un ordenador no tiene instalado .NET Framework, ¿Qué ocurrirá? ¿Se llegará a abrir el formulario? Lo que ocurrirá es que te saldrá un msgbox de Windows advirtiéndote de que la versión de .NetFW requerida por la aplicación en cuestión no está instalada en tu equipo, y por lo tanto no se podrá iniciar, ni mucho menos se llegará a abrir el form principal. El mensaje varía según la versión de Windows que se utilice, en Win7 si no recuerdo mal no te sale nada para descargar la versión requerida, y en XP directamente te sale un error de aplicación no válida sin información sobre el error. La versión 3.5 de .NetFW es la versión recomendada de forma general al ser la más común en cualquier equipo, pero obviamente si usas la 3.5 no podrás usar las "nuevas" características de la librería de classes de las versiones 4.0, 4.5, 4.5.1 y 4.5.2 ⇲What's New in the .NET Framework 4What's New in the .NET Framework 4.5, 4.5.1, and 4.5.2PD: Sinceramente, en mi humilde opinión personal utiliar la versión 3.5 a estas alturas... es seguir estancado en el pasado sin ningún motivo coherente, a menos que seas una compañía y tu única alternativa sea utilizar la versión 3.5 por motivos de compatibilidad en múltiples PC's o por lo que sea, como última opción.
¿Es posible que entre una versión del framework y otra, cambien las DLL? ¿Algún método de asegurarse de que un ordenador tiene instalada la versión adecuada?
Por supuesto, se van actualizando y agregando nuevas funciones y otras quedan obsoletas/eliminadas, pero cada versión de .NetFW instalada en el equipo expande sus propias dll's, es decir, una versión nueva no reemplaza las dll de versiones anteriores, así que mientras tu aplicación use un .NetFW objetivo que esté instalado en el equipo no habrá problema alguno. Lo correcto es distribuir junto tu software o al menos indicar la versión de .Net Framework Runtimes que necesita tu aplicación para iniciarse, y proveer el paquete por separado (el instalador online no pesa ni 1 mb), o un link de descarga oficial, en fin, lo que sea, pero algo útil para el end-user. De todas formas sí que puedes averiguar que versiones de .Net Framework están instaladas en el equipo, en tiempo de ejecución, pero ten en cuenta que la solución propuesta por el compañero KuBox no te servirá en todos los casos, por ejemplo en versiones de Windows que vengan sin .Net framework (Ej: Windows XP y todas sus versiones anteriores, al no existir dicha carpeta) o por ejemplo en Win XP con SP2 con .NetFW 2.0 instalado (aunque en este caso no se el motivo específico, pero a mi no me sale), así que otra alternativa más global es observando el registro de Windows ya que practicamente todo se almacena en el registro de Windows: Framework Version Registry Key 1.0 HKLM\Software\Microsoft\.NETFramework\Policy\v1.0\3705 1.1 HKLM\Software\Microsoft\NET Framework Setup\NDP\v1.1.4322\Install 2.0 HKLM\Software\Microsoft\NET Framework Setup\NDP\v2.0.50727\Install 3.0 HKLM\Software\Microsoft\NET Framework Setup\NDP\v3.0\Setup\InstallSuccess 3.5 HKLM\Software\Microsoft\NET Framework Setup\NDP\v3.5\Install Y obviamente puedes utilizar cómodas herramientas/librerías de terceros para facilitarte la tarea. ⇲Using managed code to detect what .NET Framework versions and service packs are installed(en los comentarios tienes actualizaciones del source compatible con .NetFW 4.0/4.5, yo lo uso sin problemas) + Librería de Snippets !! (Posteen aquí sus snippets)Telerik Online converter
¿Existe alguna manera de empaquetar librerías DLL externas en un ejecutable? Puedes embedir diréctamente una dll desde la IDE de VS, o puedes embedirlas usando aplicaciones d eterceros que te faciliten la tarea. Existe casi una infinidad de herramientas para dicha tarea, te recomiendo la aplicación Smartassembly de RedGate como solución profesional puesto que proporciona características únicas, pero si quieres algo más simple puedes utilizar .Net Shrink (de pago), o IlMerge + ILMerge GUI (gratis) ⇲SMartassembly.Net ShrinkILMergeILMerge GUINo te vendría mal pasarte por aquí VisualStudio 2013 U. (Instalador+Plantillas+Snippets+Libs+Controles+Tools)(aunque algunas versiones tienen ya un tiempo y siempre tengo la versión más nueva de cada aplicación, pero bueno, te servirán igualmente)
le di una aplicación en C# a una persona, y la pudo ejecutar, pero no se le cargaron algunas librerías (System.NET.http entre ellas, creo). El namespace System.NET.Http solo está disponible a partir de .NetFW 4.5, está información está incluida en uno de los enlaces que te mostré anteriormente: Networking
The .NET Framework 4.5 provides a new programming interface for HTTP applications. For more information, see the new System.Net.Http and System.Net.Http.Headers namespaces. Por lo tanto deduzco que tienes .NetFW 4.5 o superior como objetivo en tu proyecto de C#, y el usuario tiene FW 4.0 Saludos.
|
|
|
6268
|
Programación / .NET (C#, VB.NET, ASP) / Re: eliminar registros con ceros
|
en: 12 Noviembre 2014, 10:17 am
|
Intenta explicarte de forma precisa... ¿tienes una lista de números y quieres eliminar los números que contengan "0"? Dim list As New List(Of Integer) From {0, 1, 10, 100, 2, 3, 4, 5} list.RemoveAll(Function(n As Integer) CStr(n).Contains(0)) MsgBox(String.Join(", ", list))
Saludos
|
|
|
6269
|
Programación / .NET (C#, VB.NET, ASP) / Re: EJECUTAR CMD EN APLICACIÓN .NET
|
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: ... Select Case txtResults.InvokeRequired Case True txtResults.Invoke(Sub() txtResults.AppendText("" & e.Data)) txtResults.Invoke(Sub() txtResults.AppendText(Environment.NewLine)) Case Else txtResults.AppendText(e.Data) txtResults.AppendText(Environment.NewLine) End Select ...
⇲Control.InvokeRequired Property - MSDNControl.Invoke(Lambda) Method - MSDNSaludos
|
|
|
|
|
|
|