2010-03-06 53 views
8

He leído algunos temas sobre programas que combinan Windows Forms y aplicaciones de consola, pero parece que mi pregunta no se ha resuelto aún. ¿Es posible ejecutar un programa desde cmd-line y poder controlar la aplicación a través de formularios y mediante comandos de línea de cmd? Significa:Comandos de Windows Forms + desde la consola en C#

  • para los usuarios normales de la aplicación para el control de la aplicación a través de (Windows Forms) formas,
  • para la depuración y usuarios avanzados para el control de la aplicación a través de la consola (y, opcionalmente, ver lo que está sucediendo en Windows Forms))

Sé que lo que quiero es bastante importante, y probablemente signifique mucho trabajo, pero aún así me gustaría saber cómo hacerlo correctamente.

+0

¿Está previendo una sola aplicación, que presenta una interfaz de usuario de formas y también una consola que se puede "apareció" en la demanda? ¿O está imaginando una aplicación de formularios que se puede controlar desde otras aplicaciones arbitrarias a través de alguna interfaz accesible por programa? – Cheeso

+0

La primera opción –

Respuesta

5

No es difícil, solo P/Invoque la función de la API AllocConsole() para crear su propia consola. Por ejemplo, hacer que su archivo de código fuente Program.cs aspecto:

static class Program { 
    [STAThread] 
    static void Main() { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
#if DEBUG 
     CreateConsole(); 
#endif 
     Application.Run(new Form1()); 
    } 

    static void CreateConsole() { 
     var t = new System.Threading.Thread(() => { 
     AllocConsole(); 
     for (; ;) { 
      var cmd = Console.ReadLine(); 
      if (cmd.ToLower() == "quit") break; 
      // Etc... 
     } 
     FreeConsole(); 
     }); 
     t.IsBackground = true; 
     t.Start(); 
    } 
    [System.Runtime.InteropServices.DllImport("kernel32.dll")] 
    private static extern bool AllocConsole(); 
    [System.Runtime.InteropServices.DllImport("kernel32.dll")] 
    private static extern bool FreeConsole(); 
    } 
+0

No entiendo cómo un desarrollador se ejecuta en la API nativa tan rápido mientras trabaja en código administrado ... primero busca en el framework, realmente hay muy pocas necesidades de acceso nativo a la API ... –

+0

@BeowulfOF: muéstranos cómo usted crea una ventana de consola a pedido. –

+0

¿Por qué deberías?Simplemente permita que su aplicación Winforms-App se inicie de nuevo, y en lugar de activar el conducto principal, el parámetro de la línea de comandos para la aplicación que ya se está ejecutando, existen formas más que suficientes, todas posibles. –

0

Recuerdo haber visto IronPython siendo utilizado en una demostración que controlaba Windows Forms desde la interfaz de línea de comandos de Python (IDLE).

Edit: No pude encontrar el video original pero este debería mostrar lo que es posible sin demasiado esfuerzo. See this video y salta a las 19:00.

+0

¡Es interesante, gracias! Pero estoy buscando una solución que no use ninguna herramienta nueva. –

+0

Agregó un enlace de video para publicar. Antes de descartar la idea debido a las nuevas herramientas, eche un vistazo que podría ahorrarle mucho tiempo y proporcionar una infraestructura poderosa para hacer lo que quiera. Alternativamente, es posible que desee ver PowerShell en lugar de IronPython si se siente más cerca de casa. –

0

Esto sería posible. Tendrá que buscar en la forma de Windows Forms, posiblemente con el uso de un application domain por separado dentro del mismo proceso. Puede buscar crear un objeto proxy (un tipo de clase de mensaje que hereda MarshalByRefObject).

1

Solo necesita iniciar su aplicación Windows Forms con un ApplicationContext en lugar de un formulario en sí. Entonces no depende del formulario principal que se mostrará y puede actuar como una aplicación de consola.

También puede crear un ejecutable de línea de comandos y vincularlo con las bibliotecas de Windows Forms para usarlas.

Otra forma sería usar algún tipo de iniciador, que active la aplicación Windows Forms y una herramienta de línea de comandos que se comunique con la aplicación Windows Forms a través de redes locales o alguna otra comunicación entre procesos D-Bus o similar sistemas - many ways lead to Rome ...

0

Normalmente, cuando mira su aplicación, tiene una capa UI y una capa empresarial (y una capa de datos, y quién sabe muchas más capas). Puede pensar en el cliente de consola como una capa UI (con entradas de comando simples) y el cliente Windows Forms como otro.

Simplemente verifique al inicio de la aplicación los argumentos de la línea de comandos. Si hay argumentos especificados, crear instancias de las clases de consola simples, de lo contrario instanciar las (probablemente más complejas) clases de Windows Forms.

Si desea que sus cambios reflejen en la aplicación de Windows Forms (mientras la controla desde la aplicación de la consola) configure sus aplicaciones tanto como pueda con databinding. Deje que su capa de negocios refleje lo que realmente está sucediendo en su aplicación.

1

Sí, lo que quiere es muy posible. Tienes opciones. Algunos se me ocurre ...:

  1. uso de UI Automation para escribir una aplicación de controlador que puede conectarse a la aplicación de Windows Forms y controlarlo. Esto es nuevo en Windows   Vista.Hay clases administradas empaquetadas en el espacio de nombres System.Windows.Automation, que se envió por primera vez en WPF, que llegó a .NET 3.0. (Ahora que lo pienso, no estoy seguro de que "nuevo en Windows   Vista" sea cierto. Puede ser "nuevo en .NET 3.0", lo que implica que también funciona en Windows   XP. Hmmm ....) UI La automatización no requiere ningún cambio de código en la aplicación Windows Forms, pero puede ser de bajo nivel, ya que necesita programar cada clic del mouse o cortar/pegar. Ver the answer to Stack Overflow question Is there a way to control a third-party EXE file from VB.NET?.

  2. Modifique su aplicación Windows Forms para exponer su función a través de una interfaz WM_COPYDATA. Entonces su aplicación cliente puede comunicarse con ella. Nuevamente, el modelo aquí es dos aplicaciones distintas, una de las cuales puede controlar o interrogar a la otra. El .NET Reflector tool es un buen ejemplo de este enfoque. Hay un ReflectorController, disponible como parte de the ReflectorAddins project on CodePlex. El controlador es una herramienta de línea de comandos que puede enviar mensajes WM_COPYDATA a Reflector, para indicarle que abra un nuevo conjunto, navegue a una clase particular, y así sucesivamente.

    El código para el controlador: http://reflectoraddins.codeplex.com/sourcecontrol/network/Show?projectName=reflectoraddins&changeSetId=29526#19979

    Este enfoque funcionará para cualquier aplicación de Windows Forms. Deberá anular el método WndProc. Para ver cómo, marque The Code Project artículo Use WM_COPYDATA to send data to/from C++ and C# Windows processes.

    También utilicé este enfoque para construir un monitor de progreso basado en Windows Forms que pueda mostrar visualmente el progreso de las pruebas de larga duración.

  3. Dentro de su aplicación, exponga un objeto de servidor COM que se puede programar. Así es exactamente como Microsoft expone la función Office a las aplicaciones. Office Automation permite que cualquier programa compatible con COM (C#, VBScript, PowerShell, Perl, PHP, etc.) "conduzca" aplicaciones de Office. La aplicación de Office es visible mientras eso está sucediendo. Este enfoque también requeriría código adicional en su aplicación Windows Forms; específicamente, debe alojar un objeto COM y conectarlo a su capa UI. Esto puede ser preferible si desea la máxima flexibilidad para los superusuarios: pueden escribir sus propios scripts para controlar ese componente.

Estoy seguro de que hay otras opciones.

+0

+1 para el enfoque WM_COPYDATA y proporciona el enlace de muestra de complemento de reflector. –

Cuestiones relacionadas