2010-10-29 20 views
5

Estoy intentando iniciar una aplicación (desde el sistema operativo, mi aplicación y la aplicación que deseo iniciar son todos los 32 bits) desde .NET 3.51.Problema al iniciar un System.Diagnostics.Process en Windows 7

El código que inicia el Proceso se usa para otras aplicaciones, pero hay uno que nos causa dolor de cabeza. Si hacemos "doble clic" en el ícono de la aplicación, funciona como se espera, lo que significa que funciona bien como una aplicación en la computadora. Hacer doble clic directamente en .exe también funciona.

El sistema operativo es Windows 7 32Bits (Hogar y/o Profesional).

Nuestra aplicación .NET está compilada con x86 para evitar problemas. El código que inicia "Procesos" se encuentra dentro de una DLL (también 32 bits) hecha por nosotros, básicamente es una DLL simple que contiene un "Código común" en general, métodos comunes, funciones y cosas que usamos a lo largo de todo el documento. nuestro código Uno de esos métodos se parecen a esto:

public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, 
     ProcessWindowStyle windowStyle, string arguments) 
    { 
     if (process != null) 
     { 
      try 
      { 
       process.StartInfo.FileName = @path; 
       if (arguments != null) 
       { 
        if (arguments != String.Empty) 
        { 
         process.StartInfo.Arguments = arguments; 
        } 
       } 
       process.StartInfo.WindowStyle = windowStyle; 
       process.EnableRaisingEvents = enableRaisingEvents; 
       process.Start(); 
      } 
      catch 
      { 
       try 
       { 
        process.Kill(); 
       } 
       catch (InvalidOperationException) 
       { 
       } // The process is not even created 

       return false; 
      } 
     } 
     else 
     { 
      return false; 
     } 
     return true; 
    } 

no sé que escribió este método, pero se ha estado trabajando durante aproximadamente seis años con diferentes aplicaciones, por lo tanto, supongo que es “ok”. Sin embargo, tenemos un cliente con un software que no se ejecutará cuando pase por ese argumento.

Los argumentos son:

  1. proceso es un System.Diagnostics.Process creado con un simple "nuevo Proceso();”
  2. camino es una ruta completa al. exe. “c: /path/to/my.exe”
  3. EnableRaisingEvents es falsa
  4. windowStyle está maximizado (pero lo han intentado otros).

Da un mensaje de caja de mierda ... que felizmente he inmortalizado. Está en español, pero la traducción debería ser fácil:

alt text

Dice:

Error de aplicación ha producido una excepción inesperada para el programa (0x0eedfade) a las ...

buscar en Google que 0x0eedfade arroja resultados extraños que dan miedo, pero la verdad es que si voy al archivo .exe que intento abrir y hago doble clic en él, funciona perfectamente.

For The Record: Si yo intento poner en marcha otras cosas (es decir .: Notepad.exe, Adobe Acrobat Reader) funciona, pero Firefox no se abre y no muestra un error.

Este comportamiento de "algo de trabajo, algunos no" me lleva a pensar que puede haber un problema con un mecanismo de seguridad de Windows 7 o similar que no conozco.

¿Qué me falta o hacer mal?

ACTUALIZACIÓN: Ok; Obtuve una copia del software. Es un software sucio pero funciona. Ahora que puedo depurar, veo que el programa da un error cuando se inicia con mi método FireUpProcess.

Como sugirió he añadido el código WorkingDirectory, pero aquí está el código:

public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, ProcessWindowStyle windowStyle) 
    { 
     if (process != null) 
     { 
      try 
      { 
       if (!String.IsNullOrEmpty(@path)) 
       { 
        process.StartInfo.FileName = @path; 
        process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(@path); 
        process.StartInfo.WindowStyle = windowStyle; 
        // Suscribe to the exit notification 
        process.EnableRaisingEvents = enableRaisingEvents; 
        // Disable to prevent multiple launchs 
        Framework.Check.LogWarning("LAUNCHING EXTERNAL DEVICE WITH PATH: " + path); 
        process.Start(); // HERE The program reports the following: 

alt text

Eso significa, “El programa no pudo iniciarse debido ddip.dll falta ... intente volver a instalar bla bla ".

La cosa es, si ejecuto el mismo @path desde la línea de comandos, el programa abre la perfección:

alt text

que abre el programa. Y lo mismo ocurre si hago clic en el "acceso directo" que se encuentra en el menú "programas". No hay ningún parámetro en ese acceso directo, es una simple llamada al archivo ejecutable.

Así que la pregunta es ahora: ¿Cuál es la diferencia entre mi código y los otros métodos?

Tiene que haber algo diferente que hace que mi proceso no comience.

¿Alguna idea?

ACTUALIZACIÓN Y SOLUCIÓN

Hice que funcione mediante el uso de una de las respuestas proporcionadas a continuación. Resulta que ninguno me indicó directamente la solución, pero todos me dieron buenas ideas aquí y allá.

Agregué un manifiesto de aplicación a nuestra aplicación (debería haberlo tenido desde la edad de vista, no sé por qué no estaba allí en el 1er lugar). El manifiesto de la aplicación que agregué al usar VStudio 2008 agrega el archivo -> manifiesto de la aplicación.

En él, se aseguró de que tenemos esto:

<requestedExecutionLevel level=“asInvoker” uiAccess=“false” /> 

No necesitamos administrador o algo por el estilo, pero al parecer Vista/7 necesidad de conocerla.

Después de eso, el proceso se inició correctamente.

nota: UseShellExecute es cierto por defecto (como se sugiere por algunos), usted tiene que convertir explícitamente en false si eso es lo que quiere.

+0

lo sé, eso no es la cuestión, pero se puede simplificar el '' if' a if (! String.IsNullOrEmpty (argumentos)) '. SCNR – Bobby

+0

¿Qué es 'DBSWIN.EXE'? Según muchos sitios podría ser un problema con una extensión de terceros para IE ... ¿podría la PC estar infectada? – Bobby

+0

@Bobby DBSWIN.EXE es parte del software utilizan estos tipos: http://www.duerrdental.de/en/home-dd/ (en realidad es la siguiente: http://www.duerrdental.de/en/products/ Imaging/dbswin-image-software /) –

Respuesta

5

Si el exe tiene un manifiesto, debe establecer UseShellExecute en verdadero en el objeto de proceso antes de llamar a Inicio. No es una mala idea en ningún caso.

+0

@Kate ¿podría indicarme una explicación más "expandida" sobre eso? Gracias. –

+0

Las respuestas a http://stackoverflow.com/questions/3224804/ son un comienzo ... Gracias –

+0

@Kate mucho. –

8

No está configurando la propiedad process.StartInfo.WorkingDirectory. Hay un montón de software mal escrito que supone que el directorio de trabajo será el directorio en el que se almacena el EXE.Al menos agregue esta línea:

process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(@path); 

La excepción es, sin embargo, bastante extraño. Definitivamente le recomendaría que le dijera al cliente que actualice sus herramientas antimalware.

+0

gracias, intentaré esto. –

+0

lamentablemente esto no cambió nada (pero lo dejaré en el código de todos modos). Estamos descargando la última versión del software para ver si sucede allí también. –

+0

Hmya, concéntrese en el último párrafo de mi respuesta. Has visto los éxitos de google. –

1

He tenido problemas similares en el pasado. Resolví que mediante la ejecución de la aplicación cmd como sigue:

public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, ProcessWindowStyle windowStyle) 
{ 
    //if path contains " ", surround it with quotes. 
    //add /c and the path as parameters to the cmd process. 
    //Any other parameters can be added after the path. 

    ProcessStartInfo psi = new ProcessStartInfo("cmd", "/c" + path));    
    psi.WorkingDirectory = System.IO.Path.GetDirectoryName(@path);   
    psi.WindowStyle = windowStyle;   
    // Suscribe to the exit notification   
    process.EnableRaisingEvents = enableRaisingEvents;   
    // Disable to prevent multiple launchs   
    Framework.Check.LogWarning("LAUNCHING EXTERNAL DEVICE WITH PATH: " + path);   
    process.Start(); ...} 
+1

No estoy seguro de cómo esto te ayuda a solucionar problemas, pero necesitas añadir un espacio después de "/ c". También es necesario asignar el objeto psi para procesar el objeto para que tenga algún efecto. –

1

Si es posible me gustaría tratar de utilizar Process Monitor de Sysinternals. Cuando lo inicie, puede anular la selección de Registro y Actividad de red en la barra de herramientas (los 5 iconos en el lado derecho). Entonces solo ves la actividad Proceso y Disco. Dado que parece un problema de archivo no encontrado, debe usar el cuadro de diálogo Filtro (icono 6. de la izquierda) seleccionar Nombre del proceso en la lista desplegable (la Arquitectura es el valor predeterminado) e ingresar el nombre ejecutable que falla. Esto limitará en gran medida la salida capturada para que pueda ver lo que está sucediendo. A continuación, inicie el ejercicio y marque la columna Resultado para el resultado NOMBRE NO ENCONTRADO. Estas son las ubicaciones donde se buscó un archivo pero no se encontró. Si conoce el nombre dll ofensor, puede buscarlo con Ctrl + F, como de costumbre, para desenterrarlo. Luego puede comparar las diferentes rutas de búsqueda de su aplicación en funcionamiento y cuándo se inició desde su aplicación.

¿Podría ser que la variable de entorno PATH tenga un valor diferente dentro de su proceso? Podría ser eso agregar. (el directorio actual) ayuda a arreglar la ruta de búsqueda dll. ¿O la aplicación se inició desde una cuenta de usuario diferente? También podría ser la nueva característica que cuando una aplicación está instalando cosas en Archivos de Programa, pero no tiene derechos (solo el administrador puede hacer esto), Windows redirigirá las escrituras en el perfil del usuario. Esta es una forma segura y transparente de obtener más seguridad. Pero esto podría causar, p. durante el primer inicio de la aplicación, p. ej. archivo de configuración que se implementará en el perfil de administradores cuando ejecuta la aplicación sin el consentimiento del diálogo de UAC. Luego, otros usuarios también pueden iniciar la aplicación pero fallan porque el archivo de configuración adicional está ubicado en el perfil Administradores y no en Archivos de programa como se espera para todos.

3

Como señaló Kate Gregory, si desea "emular" al usuario haciendo doble clic en el icono, usted tiene para establecer UseShellExecute en verdadero. Establecer estos indicadores hace que el código use una ruta totalmente diferente, usando la función subyacente de Windows ShellExecute.

Ahora, voy a añadir a esto, que si se está ejecutando en un equipo con Windows equipado con UAC (Vista, 7, 2008, ...) que puede que también debe tratar de utilizar las runas verbo como se explica here y here.

Con .NET, que sería:

if (System.Environment.OSVersion.Version.Major >= 6) // UAC's around... 
{ 
    processStartInfo.Verb = "runas"; 
} 
+0

gracias por la información, seguramente lo tendrá a mano. Tenga en cuenta que, según MSDN, UseShellExecute es verdadero de manera predeterminada. –

0

creo Hans Passant está en el camino correcto. Además de lo que dijo, asegúrese de que ddip.dll y el exe estén en el mismo directorio. Este no es siempre el caso ya que hay other ways para unir ensamblajes fuera del contenedor. A saber, el evento GAC y AssemblyResolve. Considerando su situación, no veo ninguna razón por la cual el GAC esté involucrado. Compruebe el código del archivo ejecutable para cualquier gancho en el evento AssemblyResolve. Si está enganchado, es posible que deba actualizar la implementación para permitir que otro proceso la ejecute.

Debido a que obtiene una excepción en relación con un archivo DLL que falta, que tienen poca confianza en las respuestas relativas a cuestiones camino delimitadoras. No obstante, tiene el código de la aplicación, por lo tanto, verifique que haga referencia a ddip.dll. Esto le dará una buena dosis de confianza de que de hecho está haciendo referencia al .exe correcto y, por lo tanto, no es solo un problema de delimitación de ruta con el símbolo del sistema (E.G.espacios mal interpretados).

Cuestiones relacionadas