[Solucionado] Obtener la ruta de todos los procesos en ejecución

Iniciado por Segurida, 8 Mayo 2011, 22:49 PM

0 Miembros y 1 Visitante están viendo este tema.

Krähne

Cita de: Segurida en 26 Mayo 2011, 00:22 AM
el TuneUp (sin ejecutar como administrador) me da la ruta de cada proceso ejecutado, incluidos de sistema y antivirus, por eso pregunté como poder hacerlo, porque se que se puede, ¿sabes utilizar AdjustTokenPrivileges? si sabes y me puedes decir cómo utilizarlo, te los agradezco mucho, no se cómo utilizarla.
saludos

Antes que nada, se me viene una duda muy grande a al cabeza, y es... ¿Cuál es la ruta de los procesos "System", "System Idle Process" y "winlogon.exe"?.

Luego que me respondas esto, te digo cómo he logrado obtener la ruta de todos los demás procesos. Exceptuando esos que te nombro, se me hace imposible conseguirla.
Yo soy más sabio que este hombre; es posible que ninguno de los dos sepamos cosa que valga la pena, pero él cree que sabe algo, pese a no saberlo, mientras que yo, así como no sé nada, tampoco creo saberlo. Yo no tengo conciencia de saber nada.

Segurida

Lo de System e Idle, no se a qué proceso te refieres, si te instalas TuneUp 2011, hay una parte que se llama TuneUp Process Manager, ahí te da el nombre, ruta, nombre de archivo, etc... el unico que encuentro en winlogon.exe, esta en c:\windows\system32 en esto del tuneup se llama "aplicación de inicio de sesion de windows", le das un clic y abajo te pone el resto y si le das dos clics te da más info :) de verdad, que se puede sacar la ruta de todos los rocesos, pero yo no se cómo hacerlo, si no me crees, instalate el tuneup, y lo compruebas por ti mismo.
saludos.

Krähne

#12
Cita de: Segurida en 26 Mayo 2011, 10:43 AM
Lo de System e Idle, no se a qué proceso te refieres, si te instalas TuneUp 2011, hay una parte que se llama TuneUp Process Manager, ahí te da el nombre, ruta, nombre de archivo, etc... el unico que encuentro en winlogon.exe, esta en c:\windows\system32 en esto del tuneup se llama "aplicación de inicio de sesion de windows", le das un clic y abajo te pone el resto y si le das dos clics te da más info :) de verdad, que se puede sacar la ruta de todos los rocesos, pero yo no se cómo hacerlo, si no me crees, instalate el tuneup, y lo compruebas por ti mismo.
saludos.

Bueno... luego de pensarlo bien, he terminado por bajarme el TuneUP (Vaya que lo detesto) para nada.

Al abrir el TuneUP y llegar a donde me dices, me encuentro con que el cutre software tampoco logra obtener la ruta de los procesos que te dije, exceptuando winlogon.exe (proceso del cual ya logré obtener su ruta).

Los procesos son llamados así en el administrador de tareas:

System
Proceso inactivo del sistema


Y en el TuneUP tan sólo les cambian el nombre a:

System -> Proceso del sistema
Proceso inactivo del sistema -> El mismo nombre


Estos tienen por ID:

System -> 4
Proceso inactivo del sistema -> 0


Y son procesos con archivos cuya locación no existe, no sé el porqué, a lo mejor son creados por el kernel virtualmente, lo único que sé es que System inicia el Proceso inactivo del sistema (He allí el porqué de sus IDs tan bajos) y en adelante se cargará el resto, luego explorer.exe hace lo demás supongo...

Finalmente he logrado obtener la ruta de todos los procesos, con excepción de esos 2, al igual que el TuneUP, así que... por mi lado no obtendrás más ayuda que ésta, y sinceramente dudo que encuentres otro tipo de ayuda ya que, ni si quiera el "grandioso" TuneUP logra obtener esas rutas.

La manera en que obtuve la ruta de cada proceso, no fue elevando mis privilegios, fue con el uso de APIS, dejándo de lado las clases Process, y demás que tiene la plataforma .NET, sin embargo y en contraposición con lo que acabé de decir, usé la clase Process para obtener cada ID de proceso y su nombre, para así mediante APIS obtener sus directorios.

El código es el siguiente:

Código (vbnet) [Seleccionar]
Imports System.Text 'Importación necesaria para el StringBuilder.
Imports System.Diagnostics 'Importacion obligatoria para obtener los IDs y Nombres de cada proceso.
Imports System.Runtime.InteropServices 'Importación más que obligatoria para poder declarar las APIS a usar.

Public Class Formulario

   <DllImport("kernel32.dll")> _
   Private Shared Function OpenProcess(ByVal dwDesiredAccess As Integer, <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As IntPtr
   End Function 'Declaramos la API OpenProcess para abrir el handle del proceso al que queremos obtener su directorio, le pasamos como primer parámetro el número de acceso correspondiente al procedimiento a realizar, con ésto ya nos evitamos el hecho de "elevar" privilegios.

   <DllImport("psapi.dll")> _
   Public Shared Function GetModuleFileNameEx(ByVal hProcess As IntPtr, ByVal hModule As IntPtr, <Out()> ByVal lpBaseName As StringBuilder, <[In]()> <MarshalAs(UnmanagedType.U4)> ByVal nSize As Integer) As UInteger
   End Function 'Declaramos la API GetModuleFileNameEx para obtener el directorio del módulo que se le pase como parámetro, pero... como no pasarémos ningún parámetro al momento de elegir un módulo, el elegirá el primer módulo del proceso, justo lo que necesitamos.

   <DllImport("kernel32.dll", SetLastError:=True)> _
   Public Shared Function CloseHandle(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
   End Function 'Finalmente se declara la API CloseHandle para cerrar el handle abierto por OpenProcess.

   Private Sub ObtenerDatos_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
       ObtenerDatosProcesos() 'Realizamos el proceso para la obtención de datos de cada proceso.
   End Sub

   Public Sub ObtenerDatosProcesos() 'Creamos la función que no devuelve datos para agregar la información al ListView.
       Dim DirectorioActual As New StringBuilder(1024) 'Declaramos el StringBuilder de tamaño 1024 que nos pide como tercer parámetro GetModuleFileNameEx para guardar allí la ruta del proceso.
       Dim Procesos As Process() = Process.GetProcesses() 'Enlistamos los procesos en ejecución.
       ListaProcesos.Items.Clear() 'Eliminamos todos los items para agregar los nuevos.

       For i As Integer = 0 To Procesos.Length - 1 'Iniciamos un búcle para pasear por cada proceso eligiéndo su ID y Nombre de la clase Process.
           Dim hProceso As IntPtr = OpenProcess(1048, False, Procesos(i).Id) 'Declaramos una variable de tipo puntero para almacenar el handle obtenido por OpenProcess al cual le pasamos como parámetros el tipo de acceso, el cual en este caso es 1048 para poder leer la ubicación del módulo base, segundo parámetro False ya que no deseamos heredar el handle, y finalmente el ID del proceso actual.
           GetModuleFileNameEx(hProceso, IntPtr.Zero, DirectorioActual, 1024) 'Finalmente obtenemos la ruta del proceso actual, los parámetros dados son el handle del proceos, IntPtr.Zero para que elija el módulo base, y 1024 como máximo para el tamaño de la ruta (texto).
           Dim Datos As String() = {Procesos(i).ProcessName, String.Format("{0:D5}", Procesos(i).Id), DirectorioActual.ToString()} 'Creamos una matriz para insertar los datos que vamos a agregar luego a el ListView, como notas son: El nombre del proceso, el ID en un formato decimal de 5 dígitos y el directorio del proceso.
           Dim Item As ListViewItem = New ListViewItem(Datos) 'Creamos un Item para el ListView y le agregamos los datos obtenidos en la matriz.
           ListaProcesos.Items.Add(Item) 'Finalmente agregamos el Item creado al ListView.
           CloseHandle(hProceso) 'Y cerramos el handle del proceso actual
       Next 'Vamos al siguiente proceso, y así hasta finalizar.

   End Sub

End Class


Como notas, obtiene el nombre del proceso, el ID y la ruta; Los agrega a un ListView que me tocó aplicar a un formulario, quedando de ésta manera:



A clara vista, no puede obtener la ruta de los procesos nombrados arriba por motivos que desconozco, o tal vez ya dejé claros. El código está bien explicado en comentarios, espero te haya servido mi respuesta, cualquier duda posteala que con gusto se te ayudará.
Yo soy más sabio que este hombre; es posible que ninguno de los dos sepamos cosa que valga la pena, pero él cree que sabe algo, pese a no saberlo, mientras que yo, así como no sé nada, tampoco creo saberlo. Yo no tengo conciencia de saber nada.

Segurida

Me sirve, muchas gracias, eres un crack :)
muchisimas gracias, saludos.

seba123neo

#14
es que "el proceso inactivo del sistema" no es un proceso en si, es un simple hilo del kernel que calcula el uso de la cpu, para que quede claro aca te dejo una explicación de internet:

Citar
(System Idle Process). En sistemas operativos basados en Windows NT, el Proceso inactivo de sistema, es un hilo de ejecución del kernel que mide cuanta capacidad de la CPU está sin uso en un determinado período de tiempo.

El Proceso inactivo del sistema siempre se ejecuta de fondo en Windows NT, Windows XP y Vista y se encuentra bajo ese nombre o bajo el nombre de SYSTEM en el Administrador de Tareas de Windows. Es una tarea que no puede ser terminada.

Funcionamiento del proceso inactivo del sistema

Por ejemplo, en general, si dice 95 en la columna CPU del Administrador de Tareas de Windows, significa que hay un 5% de la CPU que está en uso en ese instante y el restante sin uso. Esos ciclos de CPU sin uso son tomados por el Proceso inactivo del sistema.

Por lo tanto es normal, cuando en la computadora no estamos haciendo nada importante, que esta tarea tome del 95% al 99% del CPU.

El Proceso inactivo del sistema es utilizado en Windows para ahorar energía del CPU. El ahorro de energía depende de las características del hardware y del firmware del sistema. Por ejemplo, en los procesadores x86, este proceso ejecutará un búcle de comandos HLT (un comando de lenguaje asembler), que causa que la CPU apague muchos componentes internos y espere hasta que arribe un IRQ.

El Proceso inactivo del sistema mide la utilización del CPU en el sistema, lo cual puede ser visto a través del Administrador de Tareas de Windows en la solapa Procesos. De todas maneras es más fácil de entenderlo desde la solapa Rendimiento (Performance) en la misma herramienta, donde se muestra gráficamente el uso del CPU en todo momento, el uso histórico del CPU, entre otros datos.

Hay que destacar, de todas maneras, que esa información que se muestra no es calculada a través del Proceso inactivo del sistema, sino que se toma de contadores de rendimiento globales del sistema.

PD:yo no usaria apis en .NET, lo podes hacer con la clase Process o hasta con WMI muy facilmente sin recurrir a las apis para obtener el path.
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

Krähne

Cita de: seba123neo en 27 Mayo 2011, 01:58 AM
es que "el proceso inactivo del sistema" no es un proceso en si, es un simple hilo del kernel que calcula el uso de la cpu, para que quede claro aca te dejo una explicación de internet:

PD:yo no usaria apis en .NET, lo podes hacer con la clase Process o hasta con WMI muy facilmente sin recurrir a las apis para obtener el path.

Interesante, no se me había dado por buscarle en google. Gracias por esa información.

Y... ¿Cómo lo harías sin el uso de APIS obteniéndo los mismos resultados que yo con el uso de las mismas?.

De todos modos, creo que la ayuda quedó solventada ya hace 2 respuestas.
Yo soy más sabio que este hombre; es posible que ninguno de los dos sepamos cosa que valga la pena, pero él cree que sabe algo, pese a no saberlo, mientras que yo, así como no sé nada, tampoco creo saberlo. Yo no tengo conciencia de saber nada.

seba123neo

aca te paso 2 formas, una con Process y la otra con WMI:

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

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Call ObtenerProcesos1()
        Call ObtenerProcesos2()
    End Sub

    Private Sub ObtenerProcesos1()
        Dim machineName As String = "localhost"
        Dim myQuery As String = "select * from win32_process"
        Dim mScope As New ManagementScope(String.Format("\\{0}\root\cimv2", machineName), Nothing)
        mScope.Connect()

        If mScope.IsConnected Then
            Dim objQuery As New ObjectQuery(myQuery)
            Using objSearcher As New ManagementObjectSearcher(mScope, objQuery)
                Using result As ManagementObjectCollection = objSearcher.Get

                    For Each item As ManagementObject In result
                        Debug.WriteLine(String.Format("---->> Nombre Proceso: {0}. ID Proceso: {1}. Path: {2}.", item("Name"), item("ProcessId"), item("ExecutablePath")))
                    Next
                End Using
            End Using
        End If
    End Sub

    Private Sub ObtenerProcesos2()
        For Each p As Process In Process.GetProcesses()
            Try
                Debug.WriteLine(p.Modules(0).FileName)
            Catch ex As Exception

            End Try
        Next
    End Sub
End Class


saludos.
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

Krähne

@seba123neo: Hola... he revisado tus ejemplos y me he tomado la libertad de depurarlos para saber cómo funcionaban, y como lo supuse habrían más limitaciones que con el uso de APIS.

Si bien tus códigos aprovechan lo que la plataforma .NET nos ofrece, pero... resulta que dicha plataforma no es tan "potente" como quisiéramos, por tal tenemos limitaciones al momento de realizar operaciones como las que hemos estado tratando en el tema, de lo cual ya debes estar al tanto.

Como te puedes dar cuenta, con tu ejemplo tenemos limitaciones en más de 2 procesos al momento de obtener su ruta, esto con WMI, ahora al momento de hacerlo con Process es aún peor, las limitaciones son mayores ya que no se puede tener acceso a los módulos de algunos procesos, sí... ya veo el Try-Catch pero de nada sirve porque no nos devuelve entonces las rutas de "Todos los procesos" como dice el enunciado de la pregunta original.

Un ejemplo de lo que te digo con WMI es el siguiente:



Como notas la ruta de los procesos nombrados, más uno además del ya nombrado no son obtenidos. Una pena eh, parece que el uso de APIS nos da un poco más de ventajas.

Por supuesto, yo tampoco logré obtener la ruta de esos dos procesos, pero como has traído la información podemos entender que System es un hilo del kernel así que ubicación física no existe, ya el System Idle Process sí se le puede obtener su ruta (creo) ya que revisando algunas aplicaciones por allí en C veo que obtienen esa ruta sin problemas algunos y si mi memoria no falla, es un archivo en C:\WINDOWS\System32.

De todos modos no estamos aquí para probar quién ha hecho el mejor código, tan sólo estamos para dar ayuda y claro, explorar otras soluciones, por ahora sigo firme en mi opinión que el uso de APIS para puntos como los tratados, es mejor en .NET.

Gruß.
Yo soy más sabio que este hombre; es posible que ninguno de los dos sepamos cosa que valga la pena, pero él cree que sabe algo, pese a no saberlo, mientras que yo, así como no sé nada, tampoco creo saberlo. Yo no tengo conciencia de saber nada.

[D4N93R]

"resulta que dicha plataforma no es tan "potente" como quisiéramos" Demuéstralo..

Cualquier lenguaje puede usar APIs. Y cuando cambias del lenguaje no cambias de API por lo que no cambia en nada el comportamiento de la llamada.

Todo acá (en entornos administrados) es cuestión de permisologías. Y esa es la verdadera potencia que nos ofrece la plataforma..

Un saludo :)

Krähne

#19
Cita de: [D4N93R] en 28 Mayo 2011, 20:57 PM
"resulta que dicha plataforma no es tan "potente" como quisiéramos" Demuéstralo..

Cualquier lenguaje puede usar APIs. Y cuando cambias del lenguaje no cambias de API por lo que no cambia en nada el comportamiento de la llamada.

Todo acá (en entornos administrados) es cuestión de permisologías. Y esa es la verdadera potencia que nos ofrece la plataforma..

Un saludo :)

Venga, estás haciéndome un especie de reto en base a lo que he demostrado. ¿Qué pasa [D4N93R] me vas a trollear ahora?. Ostia que me gusta C# tanto como a ti, pero no hay que negar sus defectos.

Tu mismo te contradices porque, en contraposición con lo que he dicho SÍ tenemos limitaciones de privilegios, y esas limitaciones nos las da misma .NET, ¿¡¡¡QUÉ!!!? ¿¡¡¡CÓMO!!!?... Venga calma, revisa con APIS lo que he hecho y luego con las clases de .NET y verás que tenemos más privilegios o acceso (Debe ser por haber abierto el handle del proceso con permisos específicos, no con los que .NET debe darles para las clases que usa) al momento de usar APIS como he dicho anteriormente, con la clase Process no podemos acceder a los módulos de X Procesos, como svchost.exe (Específicamente uno de todos los svchost.exe), entre otros procesos como winlogon.exe, etc. Con WMI también tenemos limitaciones, y aunque prefiero usar WMI antes que Process, el uso de APIS va a ser un tema indiscutible, siempre tendríamos que trabajar sobre código administrado, seguiré firme en mi opinión sobre el uso de APIS nativas para obtener informaciones de esta talla.

No busco pelear contigo, vamos que hasta te respeto por ser programador de esta plataforma, pero tampoco pienso rebajarme sólo porque no te gustó una crítica que ni si quiera a ti mismo hice; Si gustas comprueba por ti mismo, depura los códigos, prueba paso a paso lo que he dicho.

Eso sí, espero haber entendido lo que me dijiste en tal respuesta, porque... si no ya me extendí en vano :laugh:.

Gruß.
Yo soy más sabio que este hombre; es posible que ninguno de los dos sepamos cosa que valga la pena, pero él cree que sabe algo, pese a no saberlo, mientras que yo, así como no sé nada, tampoco creo saberlo. Yo no tengo conciencia de saber nada.