2010-07-24 24 views
5

Tengo un viejo programa basado en línea de comandos (es fortran si eso importa) que se abre desde una aplicación C# cuando un usuario hace clic en un botón. Si el programa de línea de comando se cierra mientras se ejecuta, los datos se corrompen. ¿Hay alguna manera de evitar que las personas lo cierren mientras se está ejecutando? ¿Quiere que el [x] no esté disponible o de alguna manera incruste el programa en el mío?Impedir que un usuario cierre una aplicación que se abre mediante un programa C#

System.Diagnostics.Process pname = 
System.Diagnostics.Process.Start(Path.Combine(Application.StartUpPath, 
"diag_main.exe")); 

    pname.Exited += new EventHandler(pname_Exited); 

Nota: Quiero seguir siendo capaz de ver la aplicación en ejecución y se cierra por sí solo cuando esté terminado, simplemente no puedo tener gente matando mientras está en el proceso de ejecución.

+0

¿Cómo lo está iniciando? ¿Puedes publicar el código? – Oded

Respuesta

2

Una solución que se llevará una buena cantidad de programación, pero se puede hacer:

Escribir un programa separado que intercepta la salida de la pantalla del programa y lo envía a su programa de alguna manera. Ejecute este programa en la ventana oculta, da la vuelta y ejecuta la aplicación y envía la salida a su programa.

Al menos las partes del interceptor seguramente tendrán que estar ensambladas.

Editar: Redirigir stdout no lo hará, incluso si el programa solo se escribe en él - quiere que se muestre la salida.

Hay tres cosas que podrían necesitar ser interceptado:

Int 21h sistema de archivos escribe. Estas son las cosas que podrían ser interceptadas mediante la redirección de stdout.Tenga en cuenta que algunos programas pueden escribir en un número de identificador diferente que represente el archivo stdout: busque el identificador en el que se está escribiendo en la tabla de control del programa y compárelo con la entrada stdout (IIRC, segunda entrada), si coinciden en realidad es salida de pantalla.

El segundo nivel es IIRC int 10h. Hay varias sub llamadas que deben ser interceptadas.

Finalmente, un programa puede realizar escrituras de pantalla directas. Interceptar estos sería un mayor dolor, ni siquiera consideraría probarlo (básicamente, tendría que volver a escribir el cuadro dos). En su lugar, compare frecuentemente la memoria de la pantalla con una copia guardada en busca de cambios.

En los tres casos, al menos partes de la rutina van a tener que escribirse en el ensamblaje.

He hecho la primera, jugué un poco con la segunda, pero luego descubrí que podía vivir sin hacerlo. Nunca intenté el tercero.

+1

¿Por qué no puede simplemente redirigir el STDOUT del proceso? – tster

+0

+1 Creo que este es el mejor enfoque. Realmente no creo que requiera mucho trabajo, estoy seguro de que la clase System.Diagnostics.Process tiene propiedades para redirigir tanto la entrada como la salida estándar. Luego puede insertar su aplicación en algún tipo de aplicación WPF o WinForms y luego asegurarse de que el usuario no puede matar la aplicación host. – Pandincus

+0

+1 Redireccionar stdio no es difícil en .NET. No funciona para los programas que escriben directamente en la consola, pero son raros. –

1

Lamentablemente, no. Si el otro programa tiene una IU, entonces no puede ocultarlo al usuario. Si no lo hace, puede iniciarlo sin presentar una ventana de consola utilizando la clase ProcessStartInfo. Incluso si haces eso, sin embargo, aún podrían matarlo usando el administrador de tareas.

0

Si el programa se está cargando en una ventana cmd, entonces no, no hay forma de evitar que el usuario cierre la ventana. Un mejor enfoque sería lanzar el programa en segundo plano, donde está oculto a los usuarios ocasionales. Un usuario malintencionado aún puede encontrar el proceso y matarlo, pero es probable que sea un problema menor.

Usted puede hacer esto con lo siguiente:

var psi = new ProcessStartInfo(); 
psi.CreateNoWindow = true; 
/// etc. 
1

No sé si esto se aplicará a su aplicación, pero se puede empezar el proceso con una ventana oculta - esto significaría que la aplicación está oculto y no se puede detener a través de la interfaz de usuario.

Al construir su objeto de proceso, use una sobrecarga de constructor que tome un objeto ProcessStartInfo. Establecer la propiedad WindowStyle de este a ProcessWindowStyle.Hidden y la propiedad CreateNoWindow a true:

ProcessStartInfo startInfo = new ProcessStartInfo("fortranApp.exe"); 
startInfo.WindowStyle = ProcessWindowStyle.Hidden; 
startInfo.CreateNoWindow = true; 

Process.Start(startInfo); 

Por supuesto, todavía aparecerá en la lista de procesos y puede ser muerto de esa manera, pero al menos esto evitará cualquier desconexión involuntaria.

+0

Quiero poder ver la aplicación a través de – Pieces

+0

@Pieces - siempre puede comenzar a minimizar. Aparte de eso, ahora no tengo forma de comenzar un proceso y desactivar los botones de control de la ventana, si la aplicación en sí no es compatible. – Oded

+0

¿Es posible iniciar el proceso oculto, adjuntar algo a stdout para recopilar los mensajes generados por el programa Fortran y canalizarlo a una ventana de visualización en su programa C#? –

Cuestiones relacionadas