Preguntas más frecuentes sobre System.Diagnostics.Process
Preguntas más frecuentes sobre la clase System.Diagnostics.Process.
¿Por qué obtengo excepciones extrañas con la clase DateTime en la pila de llamadas?
¿Por qué depende la clase Process del contador de rendimiento?
¿Cómo puedo conocer el identificador del proceso principal de un proceso?
¿Cómo puedo obtener el nombre del proceso rápidamente?
¿Por qué no puedo obtener la información de inicio desde Process.StartInfo?
Al pasar a 64 bits, ¿cómo se verán afectadas las propiedades de Process, que podrían sobrepasar el intervalo máximo de un Ints?
¿Cómo se usa la clase Process con una cuenta sin derechos de administración?
¿Por qué obtengo mensajes de excepción extraños, como "Esta operación no se admite en equipos remotos", cuando intento obtener los nombres de procesos en un equipo remoto?
Nos encanta conocer sus ideas, problemas o peticiones. Quizás esté interesado en saber por qué se ha diseñado algo de una manera en particular, la mejor manera de solucionar un problema o los motivos por los que el código que ha creado no funciona como esperaba. Además, puede enviar al equipo de BCL sus sugerencias para versiones futuras de Framework, como clases adicionales que incluir (siempre es útil describir los escenarios que necesita admitir) o API nuevas para clases existentes.
Para enviar su pregunta, simplemente envíe un correo electrónico a The BCL Team (bclpub@microsoft.com).
¿Por qué obtengo excepciones extrañas con la clase DateTime en la pila de llamadas?
Algunos clientes han visto excepciones con la siguiente pila de llamadas en algunos equipos:
System. InvalidOperationException: Couldn't get process information from remote machine. ---> System.ArgumentOutOfRangeException: Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue .Ticks.
Parameter name: ticks
at System.DateTime..ctor(Int64 ticks)
at System.DateTime.Subtract(TimeSpan value)
at System.Diagnostics.NtProcessManager.GetThreadInfo( PERF_OBJECT_TYPE type, IntPtr instancePtr, PERF_COUNTER_DEFINITION[] counters)
at System.Diagnostics.NtProcessManager.GetProcessInfos(PerformanceCounterLib library, Int32 processIndex, Int32 threadIndex, IntPtr dataBlockPtr)
at System.Diagnostics.NtProcessManager.GetProcessInfos(PerformanceCounterLib library)
--- End of inner exception stack trace ---
at System.Diagnostics.NtProcessManager.GetProcessInfos(PerformanceCounterLib library)
at System.Diagnostics.NtProcessManager.GetProcessInfos(String machineName, Boolean isRemoteMachine)
at System.Diagnostics.ProcessManager.GetProcessInfos(String machineName)
at System.Diagnostics.Process.GetProcesses(String machineName)
at System. Diagnostics.Process.GetProcesses()
at Process_Reader.Module1.Main()
Esto ocurre porque la información de rendimiento de algún proceso está dañada y no se puede convertir a DateTime. Analizamos una instancia en profundidad y el problema estaba relacionado con una configuración específica en la BIOS de la SCSI de Adaptec. El problema se solucionó al restablecer la configuración predeterminada de fábrica en ambas cadenas de la BIOS de la SCSI. Sin embargo, es posible que esto no resulte satisfactorio en todos los casos. En Visual Studio 2005 (Whidbey), usamos la API de Win32 para obtener información de tiempo de procesos y subprocesos, así que no verá esta excepción en el futuro.
¿Por qué depende la clase Process del contador de rendimiento?
La clase Process expone información de rendimiento sobre procesos. Para obtener información de rendimiento sobre procesos remotos, es necesario consultar la información de rendimiento en un equipo remoto. Utilizamos el mismo código para obtener información de rendimiento sobre procesos en un equipo local en Everett. Por este motivo, la clase Process depende del contador de rendimiento. Sin embargo, este enfoque conlleva una serie de problemas:
- la información de rendimiento no está disponible para cuentas sin derechos administrativos que no forman parte del grupo de usuarios de contadores de rendimiento en Windows Server 2003. Por ello, en este caso, la clase Process no puede obtener información de rendimiento de procesos.
- La obtención de datos de rendimiento de todos los procesos en el equipo es bastante costosa. Es posible que el sistema operativo cargue muchas DLL y puede tardar unos segundos en completar el proceso. La luz de la unidad de disquete permanecerá encendida mientras el sistema operativo intenta encontrar el índice de algún contador de rendimiento.
- Si, por algún motivo, los datos del contador de rendimiento estuvieran dañados, la clase Process podría generar una excepción al tratar de convertir información de rendimiento sin procesar a DateTime.
- La clase Process no se puede usar para obtener información de procesos en equipos sin contador de rendimiento de procesos. Los contadores de rendimiento se pueden deshabilitar en Windows. Consulte el siguiente vínculo para obtener los detalles: https://www.microsoft.com/windows2000/techinfo/reskit/en-us/default.asp?url=/windows2000/techinfo/ reskit/en-us/regentry/94214.asp
La buena noticia es que hemos cambiado la implementación de la clase Process en Visual Studio 2005 (la próxima versión, cuyo nombre en código es Whidbey). La clase Process ya no depende de la información del contador de rendimiento (esto sólo sucede con procesos locales).
¿Cómo puedo conocer el identificador del proceso principal de un proceso?
Si ha observado alguna vez la información de contadores de rendimiento, habrá visto algo llamado Creating Process Id. Esta información no aparece en la clase Process (probablemente la agregaremos en el futuro.) Puede usar el código que aparece a continuación para obtener el identificador del proceso:
[ C#]using System.Diagnostics;using System;class ProcessInformation { public static void Main() { PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", " windbg"); Process p = Process.GetProcessById((int)pc.RawValue); if ( p.MainModule.ModuleName.Equals("svchost.exe")) { Console.WriteLine("Created by scheduler"); } else { Console.WriteLine("Created without schedule.") ; } }}
¿Cómo puedo obtener el nombre del proceso rápidamente?<<br />Si desea obtener Process.ProcessName, existe una alternativa:
Process.MainModule.ModuleName.
¿Por qué no puedo obtener la información de inicio desde Process.StartInfo?
Sólo usamos StartInfo para iniciar un proceso, de manera que si un proceso no se crea con la clase Process, la clase StartInfo estará vacía. Si desea conocer cómo puede obtener la información de línea de comandos, existen algunas soluciones:
- Si desea obtener la información de línea de comandos del proceso actual, use Environment.CommandLine.
- System.WMI Win32_Process incluye un campo CommandLine. Consulte la documentación de MSDN si desea obtener detalles sobre esta clase.
- Existen algunas técnicas que dependen del diseño de la estructura de procesos del sistema operativo. No se garantiza que funcionen en todas las plataformas. Consulte los siguientes artículos de MSDN Magazine: https://msdn.microsoft.com/msdnmag/issues/02/06/debug/default.aspx
Al pasar a 64 bits, ¿cómo se verán afectadas las propiedades de Process, que podrían sobrepasar el intervalo máximo de un Ints?
Existen varias API en Process que reflejan el tamaño de la memoria y devuelven un Int32. Funcionan perfectamente pero, en equipos de 64 bits, suele darse el caso de que la cantidad de memoria excede el valor máximo de un Int32. En estas situaciones, las API existentes no son adecuadas.
No es posible eliminar las API de Int32 e introducir nuevas versiones de 64 bits debido a requisitos de compatibilidad (las llamadas enlazan con esta interfaz de API sobre la base de que devuelve un Int; la devolución de un Long rompería los autores de llamadas existentes). Por este motivo, las API de Int32 existentes se están quedando obsoletas y se están introduciendo nuevas versiones de API que devuelven valores de 64 bits.
Entre las API obsoletas se incluyen:
- NonpagedSystemMemorySize
- PagedMemorySize
- PagedSystemMemorySize
- PeakPagedMemorySize
- PeakVirtualMemorySize
- PeakWorkingSet
- PrivateMemorySize
- VirtualMemorySize
- WorkingSet
¿Cómo se usa la clase Process con una cuenta sin derechos de administración?
En Windows Server 2003, recibirá una excepción si intenta obtener información de rendimiento de procesos con una cuenta sin derechos administrativos. Una solución sencilla es agregar dicha cuenta al grupo de usuarios de contadores de rendimiento.
¿Por qué obtengo mensajes de excepción extraños, como "Esta operación no se admite en equipos remotos", cuando intento obtener los nombres de procesos en un equipo remoto?
Siempre debe ser posible obtener nombres de procesos en un equipo remoto al obtener acceso a la información de rendimiento en dicho equipo. Hacemos algo especial en get_ProcessName: intentamos completar el nombre del proceso si no se presenta truncado por el sistema operativo. Intentamos obtener la información de módulo para el nombre de un proceso, que es de 15 caracteres. Esta operación no se puede llevar a cabo en equipos remotos y no se debería intentar con procesos remotos.
A continuación se ofrece una solución al problema:
[C#]try { Console.WriteLine(myProcesses[x].ProcessName);} catch ( NotSupportedException ) { Type processType = typeof(Process); FieldInfo info = processType.GetField("processInfo", BindingFlags.NonPublic| BindingFlags.IgnoreCase | BindingFlags.Instance); Object obj = info.GetValue( myProcesses[x]); Type processInfoType = obj.GetType(); FieldInfo info2 = processInfoType.GetField("processName", BindingFlags.NonPublic| BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); String name = (string)info2.GetValue( obj); Console.WriteLine( name );}
El código anterior usa información de procesos no documentada. Esta solución funciona con V1.0 y V1.1, pero no garantizamos que resulte satisfactoria en todos los casos. Por supuesto, este error quedará solucionado en la próxima versión (Visual Studio 2005).