2011-12-08 22 views
7

Quiero manejar esto de manera diferente, es decir. determinar si tengo acceso o no.Process.MainModule -> "Acceso denegado"

¿Es posible ver si tiene acceso al módulo principal o no?

foreach (Process p in Process.GetProcesses()) 
     { 
      try 
      { 
       //This throws error for some processes. 
       if (p.MainModule.FileName.ToLower().EndsWith(ExeName, StringComparison.CurrentCultureIgnoreCase)) 
      { 
       //Do some stuff 
      } 

      } 
      catch (Exception) 
      { 
       //Acess denied 
      } 
     } 
+2

Aquí vamos de nuevo. Eche un vistazo @ http://stackoverflow.com/questions/2774527/access-denied-while-using-system-diagnostics-process – leppie

Respuesta

3

Veo dos posibles causas de excepción:

  1. Puede ser que su proceso es x86 y el proceso que se consulta es de 64 bits o viceversa.
  2. Cada proceso tiene una llamada ACL (Lista de control de acceso) que describe quién puede interactuar con ella, los procesos con los que tiene problemas tienen por razones de seguridad una ACL vacía, por lo que incluso como administrador no puede meterse con ellos. Por ejemplo, hay un puñado de procesos (audiodg, System e Idle desde la parte superior de mi cabeza) que lanzan una excepción debido a los derechos de acceso.

Simplemente use un try/catch en su bucle para manejar esos procesos.

1
[Flags] 
    private enum ProcessAccessFlags : uint 
    { 
     QueryLimitedInformation = 0x00001000 
    } 

    private static extern bool QueryFullProcessImageName(
     [In] IntPtr hProcess, 
     [In] int dwFlags, 
     [Out] StringBuilder lpExeName, 
     ref int lpdwSize); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    private static extern IntPtr OpenProcess(
    ProcessAccessFlags processAccess, 
    bool bInheritHandle, 
    int processId); 

String GetProcessFilename(Process p) 
{ 
int capacity = 2000; 
StringBuilder builder = new StringBuilder(capacity); 
IntPtr ptr = OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, p.Id); 
if (!QueryFullProcessImageName(ptr, 0, builder, ref capacity)) 
{ 
    return String.Empty; 
} 

return builder.ToString(); 
} 

Uso PInvoke con ProcessAccessFlags.QueryLimitedInformation. Esto le permitirá tomar el nombre de archivo del proceso sin tener privilegios de administrador especiales y funciona en los procesos x32 y x64.