Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Eleкtro

#1361
Cita de: Devilkeeper en  8 Enero 2018, 21:35 PMNo sé si es una manera correcta de trabajar, o es mejor cargar los Puestos y según necesite ir cargando y descargando las listas. Si quisiera cargar todos los puestos, tendría en memoría muchísimos datos, y no sé si eso está bien.

Es precisamente por esa necesidad que existe la interfáz IEnumerable<T> (o IEnumerable(Of T) en VB.NET) de evaluación vaga y el tipo Lazy<T> (o Lazy(Of T) en VB.NET) para la inicialización/instanciación vaga de objetos.

La interfáz IEnumerable, o colección enumerable, provee lo que se conoce como un enumerador, que es un mecanismo para obtener el elemento actual en la colección enumerable, mover al siguiente elemento, y reiniciar. El enumerador solamente debe preocuparse por saber como obtener el siguiente elemento en la colección enumerable, por lo que no es necesario que la colección entera esté alojada en memoria ni saber cuantos elementos hay en total; este comportamiento o implementación se traduce en una optimización de varios aspectos, empezando por el más obvio: el consumo de memoria.

Practicamente todas las colecciones disponibles en los espacios de nombre de la librería de .NET Framework implementan la la interfáz IEnumerable, como los tipos List, Dictionary, Array, Stack, Collection y etcétera, pero ojo, eso no quiere decir que todos los tipos de colecciones sean de evaluación vaga, cada tipo tiene una implementación distinta para servir a un propósito específico, así que si quieres asegurarte de beneficiarte de la evaluación vaga entonces usa directamente la interfáz IEnumerable.

El tipo Lazy<T>, por lo general lo usarías en escenarios de programación asincrónica y para prevenir la inicialización de una instancia que sea bastante pesada... hasta que realmente necesites acceder/leer ese objeto.

Te recomiendo unas lecturas importantes para comprender los conceptos básicos:

CitarLazy initialization of an object means that its creation is deferred until it is first used. (For this topic, the terms lazy initialization and lazy instantiation are synonymous.) Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirements.

CitarBy initializing objects in a lazy manner, you can avoid having to create them at all if they are never needed, or you can postpone their initialization until they are first accessed




Bien, ahora que ya he explicado que es cada cosa, te mostraré como puedes reproducir las diferencias a través de varios ejemplos (básicos) basados en el escenario o problema que propones...

Primero de todo, para estos ejemplos crearemos un tipo como éste para representar la información básica de un cliente:

Código (vbnet) [Seleccionar]
Public NotInheritable Class Customer

   Public Property Name As String
   Public Property Surname As String
   Public Property Buffer As Byte()

   Public ReadOnly Property InstanceId As Guid
       Get
           If (Me.instanceIdB = Guid.Empty) Then
               Me.instanceIdB = Guid.NewGuid()
           End If
           Return Me.instanceIdB
       End Get
   End Property
   Private instanceIdB As Guid

   Private Sub New()
   End Sub

   Public Sub New(name As String, surname As String)
       Me.Name = name
       Me.Surname = surname
       Me.Buffer = New Byte(4096) {}
   End Sub

   Public Overrides Function ToString() As String
       Return Me.InstanceId.ToString()
   End Function

End Class


...es solo un ejemplo cualquiera, mi intención al escribir este ejemplo ha sido que una instancia del tipo Customer ocupe bastantes bytes.




Bien, por lo general, podriamos decidir crear una colección genérica de tipo List<T> (o List(Of T) en VB.NET) para almacenar varias instancias de la clase Customer, e iterar la colección para mostrar cualquier tipo de información de cada Customer, quedando algo parecido a esto:

Código (vbnet) [Seleccionar]
Imports System
Imports System.Collections.Generic
Imports System.Threading

Public Module Module1

   Private customers As List(Of Customer)
   Private customerCount As Integer

   Private Sub BuildCustomers(ByRef collection As List(Of Customer), ByVal amount As Integer)
       If (collection Is Nothing) Then
           collection = New List(Of Customer)
       ElseIf (collection.Any) Then
           collection.Clear()
       End If

       For i As Integer = 0 To (amount - 1)
           collection.Add(New Customer(String.Empty, String.Empty))
       Next i
   End Sub

   Public Sub Main()
       ' Construimos la lista de clientes.
       Module1.BuildCustomers(Module1.customers, 100000)
       ' En este punto, la instanciación de todos los objetos en la colección
       ' habrá alcanzado un consumo de memoria sobre los 500 megabytes aprox.

       ' Mostramos la cantidad de elementos en la lista
       ' (la propiedad Count debe realizar una iteración completa, así que puede tardar unos segundos).
       Console.WriteLine(String.Format("Customers Count: {0}", Module1.customers.Count))

       ' Iteramos cada elemento en la lista.
       For Each c As Customer In Module1.customers
           Console.WriteLine(String.Format("Customer {0}; Unique Id: {1}",
                                           Interlocked.Increment(Module1.customerCount), c.ToString()))
       Next c

       ' Ya no necesitamos la lista, así que liberarariamos recursos administrados innecesarios,
       ' y forzamos una recolección del GarbageCollector para un efecto inmediato.
       Module1.customers.Clear()
       Module1.customers = Nothing
       GC.Collect()
       GC.WaitForPendingFinalizers()
       GC.WaitForFullGCApproach()
       GC.WaitForFullGCComplete()
       ' En este punto, la carga de objetos en memoria se reduce al máximo posible,
       ' en mi caso el consumo total es de 80 mb aprox.

       Console.WriteLine("Press any key to exit...")
       Console.ReadKey(intercept:=True)
       Environment.Exit(0)
   End Sub

End Module


¿Qué ocurre con esto?, pues que todos los elementos de la colección se inicializan, se asigna un espacio en el bloque de memoria para cada elemento de la colección, y evidentemente si tenemos en cuenta el tamaño en bytes de una única instancia de la classe Customer pues... 100.000 instancias simultaneas resultan en un gran consumo de memoria...






Cuando un elemento Customer ha sido inicializado y ya hemos trabajado con él, no necesitamos que siga albergando espacio en memoria, queremos desechar ese consumo adicional que ya no necesitamos para nada, y aquí es donde .NET Framework nos ofrece la solución al problema: IEnumerable<T>.

Este código de aquí abajo es practicamente lo mismo que el anterior con el uso de List<T>, solo que ha sido adaptado para el uso de IEnumerable<T> mediante una función iteradora y así demostrar el beneficio que nos interesa obtener...

Código (vbnet) [Seleccionar]
Imports System
Imports System.Collections.Generic
Imports System.Threading

Public Module Module1

   Private customers As IEnumerable(Of Customer)
   Private customerCount As Integer

   Private Iterator Function BuildCustomers(ByVal amount As Integer) As IEnumerable(Of Customer)
       For i As Integer = 0 To amount
           Yield New Customer(String.Empty, String.Empty)
       Next i
   End Function

   Public Sub Main()
       ' Construimos la colección de clientes.
       Module1.customers = Module1.BuildCustomers(100000)
       ' En este punto, el consumo de memoria es mínimo, alcanzando los 12 mb aprox.

       ' Mostramos la cantidad de elementos en la colección
       Console.WriteLine(String.Format("Customers Count: {0}", Module1.customers.Count))

       ' Iteramos cada elemento en la colección.
       For Each c As Customer In Module1.customers
           Console.WriteLine(String.Format("Customer {0}; Unique Id: {1}",
                                           Interlocked.Increment(Module1.customerCount), c.ToString()))
       Next c
       ' En este punto, el consumo de memoria es mínimo, sin cambios, puesto que al iterar, los elementos se han evaluado de forma vaga.

       Module1.customers = Nothing
       Console.WriteLine("Press any key to exit...")
       Console.ReadKey(intercept:=True)
       Environment.Exit(0)
   End Sub

End Module


El beneficio en la optimización del consumo de memoria queda bastante claro:






Te muestro un ejemplo para el uso del tipo Lazy:

Código (vbnet) [Seleccionar]
Imports System
Imports System.Collections.Generic
Imports System.Threading

Public Module Module1

   Private lazyCustomers As List(Of Lazy(Of Customer))
   Private customerCount As Integer

   Private Function BuildCustomers(ByVal amount As Integer) As List(Of Lazy(Of Customer))
       Dim collection As New List(Of Lazy(Of Customer))
       For i As Integer = 0 To amount
           collection.Add(New Lazy(Of Customer)(
                          Function() As Customer
                              Return New Customer(String.Empty, String.Empty)
                          End Function))
       Next i
       Return collection
   End Function

   Public Sub Main()
       ' Construimos la instancia de inicialización vaga con la colección de clientes.
       Module1.lazyCustomers = Module1.BuildCustomers(100000)
       ' En este punto, el consumo de memoria es mínimo, alcanzando los 12 mb aprox,
       ' puesto que todavía NO hemos inicializado ningún elemento de la colección.

       Console.WriteLine(String.Format("Lazy Customers Count: {0}", Module1.lazyCustomers.Count))

       For Each lz As Lazy(Of Customer) In Module1.lazyCustomers
           Console.WriteLine(String.Format("Customer {0}; Unique Id: {1}",
                                           Interlocked.Increment(Module1.customerCount), lz.Value.ToString()))
       Next lz
       ' Cuando accedemos a la propiedad 'Lazy(Of T).Value' es cuando inicializamos el objecto de inicialización vaga,
       ' así que al terminar la iteración hemos inicializaco todos los elementos, por lo que en este punto el consumo de memoria rondará los 500 megabytes aprox, como en el primer ejemplo.

       ' Ya no necesitamos la colección, así que liberarariamos recursos administrados innecesarios,
       ' y forzamos una recolección del GarbageCollector para un efecto inmediato.
       Module1.lazyCustomers.Clear()
       Module1.lazyCustomers = Nothing
       GC.Collect()
       GC.WaitForPendingFinalizers()
       GC.WaitForFullGCApproach()
       GC.WaitForFullGCComplete()
       ' En este punto, la carga de objetos en memoria se reduce al máximo posible,
       ' en mi caso el consumo total es de 20 mb aprox.

       Console.WriteLine("Press any key to exit...")
       Console.ReadKey(intercept:=True)
       Environment.Exit(0)
   End Sub

End Module





Por supuesto podemos combinar el tipo Lazy<T> e IEnumerable<T>:

Código (vbnet) [Seleccionar]
Imports System
Imports System.Collections.Generic
Imports System.Threading

Public Module Module1

   Private lazyCustomers As IEnumerable(Of Lazy(Of Customer))
   Private customerCount As Integer

   Private Iterator Function BuildCustomers(ByVal amount As Integer) As IEnumerable(Of Lazy(Of Customer))
       For i As Integer = 0 To amount
           Yield New Lazy(Of Customer)(
                          Function() As Customer
                              Return New Customer(String.Empty, String.Empty)
                          End Function)
       Next i
   End Function

   Public Sub Main()
       ' Construimos la instancia de inicialización vaga con la colección de clientes.
       Module1.lazyCustomers = Module1.BuildCustomers(100000)
       ' En este punto, el consumo de memoria es mínimo, alcanzando los 12 mb aprox,
       ' puesto que todavía NO hemos inicializado ningún elemento de la colección.

       Console.WriteLine(String.Format("Lazy Customers Count: {0}", Module1.lazyCustomers.Count))

       For Each lz As Lazy(Of Customer) In Module1.lazyCustomers
           Console.WriteLine(String.Format("Customer {0}; Unique Id: {1}",
                                           Interlocked.Increment(Module1.customerCount), lz.Value.ToString()))
           ' Cuando accedemos a la propiedad 'Lazy(Of T).Value' es cuando inicializamos el objecto de inicialización vaga.
       Next lz
       ' Al terminar la iteración, en este punto no hay cambios en el consumo de memoria,
       ' puesto que hemos utilizado una colección enumerable.

       Module1.lazyCustomers = Nothing
       Console.WriteLine("Press any key to exit...")
       Console.ReadKey(intercept:=True)
       Environment.Exit(0)
   End Sub

End Module





IEnumerable y Lazy son dos propuestas para fines distintos, aunque combinables para un mismo fin, y yo solo te he mostado ejemplos básicos de su utilización en escenarios sincrónicos; al final la solución más óptima y adecuada a tu problema siempre dependerá de lo que realmente quieras hacer y como sea realmente necesario hacerlo...

Espero que esto haya servido de ayuda, al menos.

Saludos.
#1362
Ya pueden meterle al Chomefox este todos los ajustes personalizables de seguridad y privacidad que quieran hasta llegar a la versión 60, 70, 80, 90 y 100, que mientras sus desarrolladores no se dignen a implementar una API para la creación de toolbars como reclama toda la comunidad de desarrolladores de extensiones de Firefox para soportar la extensión Tabs Mix Plus (y cualquier otra extensión de personalización), le van a dar por culo a este navegador y a su tecnología web-extensions...


Saludos.
#1363
Curioso nombre, ¿se supone que "nomo" viene del latín como suelen hacer los científicos al ponerle nombre a las fobias y demás?, por que yo no le encuentro relación alguna entre "nomo" y teléfono móvil...

A ver si algún experto nos ilustra de donde viene eso de "nomo", creo que nisiquiera en la wikipedia hacen referencia a ello...

EDITO: pues si, si que lo explica en la wikipedia, y sabiendo ahora el significado, me parece una soberana gilipollez usar lo de "nomo" para describir una adicción de cualquier tipo...

CitarThe latter derives from the Greek nomos (a law, rule or regulation) seen in such other words as astronomy (rules about the stars), gastronomy (rules about food and eating), autonomy (ruling oneself), economy (rules governing the finances of the state or household), antinomy (a law contrary to another law), metronome (a device to regulate metre or beat), nomocracy (the rule of law in society), nomography (the law in written form), nomology (the study or science of law), nomothete (a lawgiver), and the archaic anomy (lawlessness). The neologistic meaning referred to in this article, relating to mobile phones, seems to have been adopted by the younger generations, and by those without a deeper understanding of the Oxford guidelines on word construction, in which typically Greek words are attached to Greek words (and Latin to Latin, etc.).

Saludos
#1364
. . .

¿Tan siquiera has probado a hacer doble click sobre un archivo de código fuente de C# antes de invertir tu tiempo en formular este tipo de pregunta?, es obvio que no. Abrirlo y editarlo lo vas a poder hacer, por supuesto, ahora, otra cosa muy distinta sería que la sintaxis de C# empleada para el desarrollo de dicho código fuente sea o no sea compatible con tu versión de Visual Studio.

Con respecto al archivo de configuración de proyecto de C# (archivo.csproj), si es de una versión anterior de Visual Studio entonces tendrás que actualizarlo (el procedimiento será automático y por lo general con un resultado satisfactorio), pero si es de una versión más reciente de Visual Studio entonces en el "peor" de los casos tendrás que actualizar tu versión de Visual Studio para asegurar la compatibilidad, o realizar una edición manualmente en el archivo para arreglar/eliminar las propiedades de la configuración que no sean soportadas por tu versión actual de Visual Studio, o diréctamente volver a generar el archivo usando tu versión de Visual Studio.

No te conviene nada seguir estancado en una versión de software e IDE tan antigua.

Saludos!
#1365
Cita de: Ikillnukes en  5 Enero 2018, 14:00 PMOtro año y yo sigo leyendo igual de mal tus comentarios. Tienes que cambiarlo:

Pues si, no hay remedio, yo tengo que usar unas gafas especiales y además calibrar el color y el brillo de mi monitor cada vez que quiero leer un comentario de @El_Andaluz xD...

#1366
Cita de: eleze en  5 Enero 2018, 10:23 AM
El caso es que me di a la tarea y ya tengo algunos codigos de ejemplos sobre la lista de procesos y como matarlos en VB.NET como me sugirió (jeje le escribo como si me hubieran retado).

Pues para no saber practiamente nada, con una simple recomendación (o "reto" xD) ya has hecho mucho más de lo que otros han hecho en tu misma situación... ¡se nota que te esfuerzas en resolver las cosas!... y con las cosas que vayas aprendiendo poco a poco haciendo eso. EDITO: pero si veo que incluso estás usando el framework de DotNetBar, ¿seguro que nunca antes habias programado en VB.NET? xD.

Cita de: eleze en  5 Enero 2018, 10:23 AMno sabria como pegar los codigos de forma correcta y fucionarlos con su ejemplo de arriba

Bueno, eso depende del objetivo que tengas en mente... debes adaptar el ejemplo que te mostré, a tus necesidades.

He escrito este otro ejemplo algo más extenso por si te sirve de mejor ayuda, aunque no se si te voy a conseguir ayudar o por lo contrario voy a conseguir confundirte...puesto que en el código hago uso de técnicas de programación asincrónica mediante la aplicación del paralelismo para acelerar el procedimiento de ejecución (puesto que la función GetProcessCPUPercentUsage necesariamente es una llamada bloqueante de 500-1000 ms, y no queremos tener que esperar 500-1000 ms por cada proceso que haya...¿verdad que no?, jeje).  

...nótese que declaré una variable en la que especifico que el máximo válido de porcentaje de CPU para un proceso es 6.0%; si el límite se sobrepasa, se intenta matar al proceso.

Código (vbnet) [Seleccionar]
Imports System
Imports System.Collections.Concurrent
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks

Public Module Module1

   Public Sub Main()
       Dim maxCpuUsage As Double = 6.0R '%

       ' White-listed process names.
       Dim whlNames As IEnumerable(Of String) =
           {
             "csrss", "dwm", "fontdrvhost", "idle", "lsass", "runtimebroker",
             "services", "sihost", "smss", "svchost", "System", "taskhostw",
             "wininit", "winlogon"
           }

       ' Current processes sequence.
       Dim prcsQuery As ParallelQuery(Of Process) =
           (From prc As Process In Process.GetProcesses()
            Where Not whlNames.Contains(prc.ProcessName, StringComparer.OrdinalIgnoreCase)
           ).AsParallel().AsUnordered()

       Dim action As New Action(Of Process)(
           Sub(prc As Process)
               If (prc Is Nothing) Then
                   Exit Sub
               End If

               Dim cpuPercent As Double = GetProcessCPUPercentUsage(prc)
               Dim pName As String = prc.ProcessName
               Dim pid As Integer = prc.Id

               If (cpuUsage < maxCpuUsage) Then
                   Console.WriteLine(String.Format("[ GOOD ] Name: {0}; PID: {1}; CPU: {2}%", pName, pid, cpuPercent))

               Else
                   Console.WriteLine(String.Format("[ BAD  ] Name: {0}; PID: {1}; CPU: {2}%", pName, pid, cpuPercent))
                   Console.WriteLine(String.Format("[ ...  ] Attempting to kill process '{0}' with PID '{1}'...", pName, pid))

                   Try
                       If Not (prc.HasExited) Then
                           prc.Kill()
                       End If
                       Console.WriteLine("[ ...  ] Process was killed successfuly.")

                   Catch ex As Exception
                       Console.WriteLine("[ ...  ] Error trying to kill process...")
                       Throw

                   End Try
               End If

           End Sub)

       Parallel.ForEach(Of Process)(prcsQuery, New ParallelOptions(), action)
   End Sub

   Friend Function GetProcessCPUPercentUsage(ByVal p As Process) As Double
       Using perf As New PerformanceCounter("Process", "% Processor Time", p.ProcessName, True)
           perf.NextValue()
           Thread.Sleep(TimeSpan.FromMilliseconds(500)) ' Recommended value: 1 second
           Return (Math.Round(perf.NextValue() / Environment.ProcessorCount, 1))
       End Using
   End Function

End Module


Resultado de ejecución:
...

[ GOOD ] Name: GameOverlayUI; PID: 7404; CPU: 0,2%
[ GOOD ] Name: sidebar; PID: 4836; CPU: 0,3%
[ GOOD ] Name: ScriptedSandbox64; PID: 9552; CPU: 0,3%
[ GOOD ] Name: BEService; PID: 10952; CPU: 0,4%
[ BAD  ] Name: ShooterGame; PID: 5136; CPU: 6,3%
[ ...  ] Attempting to kill process 'ShooterGame' with PID '5136'...
[ ...  ] Process was killed successfuly.
[ GOOD ] Name: Start10_64; PID: 2576; CPU: 0%
[ GOOD ] Name: CTAudSvc; PID: 1916; CPU: 0,1%
[ GOOD ] Name: NVDisplay.Container; PID: 1184; CPU: 0%

...


PD: si quieres ordenar las lineas de salida por el nombre del proceso... es algo que requeriría modificar casi por completo el código del ejemplo, en cuyo caso no debes intentar ordenar la secuencia paralela, en su lugar declara una clase o estructura para representar la información necesaria de un proceso (el nombre, PID, y porcentaje de cpu) a la que podriamos llamar "ProcessInfo", entonces creas una nueva colección genérica de tipo List(Of ProcessInfo) (o bien un SortedSet(Of ProcessInfo) pasándole un IComparer(Of ProcessInfo), primero deberías crear el comparer), y el bloque del Parallel.ForEach( ... ) (el método declarado en la variable "action") lo usarías solamente para obtener el porcentaje de cpu e ir añadiendo elementos "ProcessInfo" a la lista, ordenarla, y por último ya podrías iterar la lista de forma ordenada. Se que sin mostrar un ejemplo de código, estas explicaciones no serán muy fáciles de entender o de aplicar, pero tampoco se lo que quieres hacer exactamente, ni si necesitas mosrar los resultados en consola, ni si necesitas hacerlo de forma ordenada, y ponerme a escribir variaciones de un mismo código sin saber cual te va a servir... es tontería hacerlo xD.

Saludos!
#1367
Como obtener el uso de porcentaje de CPU de un proceso

Código (vbnet) [Seleccionar]

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Gets the CPU percentage usage for the specified <see cref="Process"/>.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <returns>
   ''' The resulting CPU percentage usage for the specified <see cref="Process"/>.
   ''' </returns>
   ''' ----------------------------------------------------------------------------------------------------
   <DebuggerStepThrough>
   Public Shared Function GetProcessCPUPercentUsage(ByVal p As Process) As Double

       Using perf As New PerformanceCounter("Process", "% Processor Time", p.ProcessName, True)
           perf.NextValue()
           Thread.Sleep(TimeSpan.FromMilliseconds(250)) ' Recommended value: 1 second
           Return (Math.Round(perf.NextValue() / Environment.ProcessorCount, 1))
       End Using

   End Function


primero hay que activar el uso de los contadores de rendimiento en el archivo de manifiesto de nuestra aplicación:
Código (xml,5,6,7,8,9) [Seleccionar]
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
...

 <system.net>
   <settings>
     <performanceCounters enabled="true"/>
   </settings>
 </system.net>

...
</configuration>


Modo de empleo:
Código (vbnet) [Seleccionar]
Do While True

   Using p As Process = Process.GetProcessesByName("NOMBRE DEL PROCESO").SingleOrDefault()
       Dim str As String =
           String.Format("Process Name: {0}; CPU Usage: {1}%",
                         p.ProcessName, GetProcessCPUPercentUsage(p))

       Console.WriteLine(str)
   End Using

Loop

#1368
Cita de: NEBIRE en  5 Enero 2018, 06:24 AMPura especulación...

No es especulación, te acaban de mostrar los precios que demuestran los planes de las empresas...

Recomiendo ver este video donde explican más a fondo las razones del elevado precio:
[youtube=640,360]https://www.youtube.com/watch?v=90OtmBKaVv8[/youtube]
...en teoría, si lo que dice este chico es cierto (pocas o ninguna vez le he visto equivocarse en sus augurios), no veremos ninguna bajada de precio hasta el año 2020 como mínimo xD.

Saludos
#1369
Scripting / Re: Ejecutar un exe a un bat
5 Enero 2018, 03:07 AM
Cita de: Ryui en  5 Enero 2018, 02:53 AMes posible que un archivo exe, pueda llamar a un bat para que esta se ejecute automáticamente(con solo ejecutar el exe,  se tiene que ejucutar el bat)

No entiendo muy bien el problema que planteas, si tienes el código fuente de ese executable que has compilado entonces le añades una instrucción para ejecutar el archivo.bat y listo.

Si por otro lado te refieres a un executable que no has compilado tú, pretender que al iniciar un executable cualquiera se inicie adicionálmente otro archivo... entonces mejor olvídate de hacer eso (a menos que domines a un nivel avanzado varios conceptos de programación para llevar a cabo un api hook).

EDITO: bueno, una solución alternativa a la programación sería utilizar cualquier software de tipo "file binder" ( https://en.wikipedia.org/wiki/File_binder ) para empacar o "juntar" el archivo.exe y el archivo.bat en un nuevo executable; ese nuevo executable sería un simple "loader" que extraería e iniciaría los archivos que le hayas añadido (el archivo.exe original y el archivo.bat). Con herramientas de compresión tipo WinRAR lo puedes hacer también, puedes crear un archivo autoextraible (SFX) que contenga los archivos que tu quieras e iniciar aquellos archivos que desees iniciar al mismo tiempo.

Saludos!
#1370
Así no estás comprobando la disponibilidad de conexión red, lo que estás haciendo es comprobar que el servidor de la DNS de Google 8.8.8.8 no está caida... pero bueh, en una herramienta tan limitada como Batch no se le puede pedir mucho más.

Prueba así:

Código (dos) [Seleccionar]
@Echo OFF

REM Set "isHostAvailable=True"

:DoPing
ECHO VERIFICANDO SI HAY INTERNET
(Ping.exe 8.8.8.8)1>NUL && (
   Echo.Consulta Ping exitosa.
   REM Set "isHostAvailable=True"
   Start /B "AIMP" "%ProgramFiles(x86)%\AIMP\AIMP.exe" "D:\Chismoso de Internet\No hay Internet.wav")

) || (
   Echo.Consulta Ping fallida.
   REM Set "isHostAvailable=False"
   Start /B "AIMP" "%ProgramFiles(x86)%\AIMP\AIMP.exe" "D:\Chismoso de Internet\Hay Internet.wav")

)
CLS

Pause&Exit


Adapta el código a tus necesidades (ej. hacer un búcle infinito).

Saludos.