2009-11-23 17 views
8

Tengo una aplicación simple que me gustaría automatizar mediante conmutadores. Pero cuando lo ejecuto a través de los conmutadores, realmente no quiero que se muestre una interfaz de usuario. Solo quiero que se ejecute, haga su trabajo, imprima cosas en la consola y salga. Por otro lado, si no lo ejecuto con ningún conmutador, quiero que aparezca la interfaz de usuario. Y en este caso, realmente no quiero una ventana de consola dando vueltas en el fondo.C#: ¿Es posible que una sola aplicación se comporte como consola o aplicación de Windows según los switches?

¿Hay alguna manera de hacerlo, o tengo que crear dos proyectos separados, una aplicación de consola y una aplicación para Windows?

+0

¿Has intentado simplemente insertar tu código en la función Main() que se genera cuando creas una aplicación de winforms? En lugar de llamar a Application.Run()? –

+0

Algo relacionado, especialmente si desea escribir en la consola desde una aplicación de Windows: http://stackoverflow.com/questions/666823/writing-to-the-command-line-in-a-windowed-app –

Respuesta

11

Si bien no es exactamente lo que ha preguntado, he logrado el apariencia de este comportamiento en el pasado mediante el uso de FreeConsole pInvoke para eliminar la ventana de la consola.

se establece el tipo de salida del proyecto para ser una aplicación de consola.A continuación se define la llamada extern a FreeConsole:

[DllImport("kernel32.dll", SetLastError=true)] 
private static extern int FreeConsole(); 

Luego, en que Main método que cambia en función de sus condiciones. Si desea una IU, llame al FreeConsole antes de abrir el formulario para borrar la ventana de la consola.

if (asWinForms) 
{ 
    FreeConsole();  
    Application.Run(new MainForm()); 
} 
else 
{ 
    // console logic here 
} 

Una ventana de consola aparece brevemente al inicio, pero en mi caso fue aceptable.

Esto es un poco hackeo y tiene un mal olor, por lo que consideraría seriamente si desea seguir esta ruta.

+0

Este es un enfoque muy bueno para esta situación. También puede AllocConsole (mi publicación eliminada mostró esto), pero luego su consola se separa del shell que realiza la llamada, si se llama desde un shell. –

+0

No funcionará bien bajo Mono más entonces, ¿o sí? – Svish

+0

Esto no funcionará en todos los casos, porque el ejecutable tendrá el mismo encabezado PE que le dice al sistema si es consola o no. Ver http://stackoverflow.com/questions/7613880/difference-between-console-and-winforms-applications-when-running-from-cmd – qub1n

6

Claro, simplemente ponga una instrucción switch (o si no otra construcción) en el main estático (string [] args), basado en argumentos pasados ​​en la línea de comando. También hago esto para cambiar entre ejecutar como un servicio o como una consola ...

NOTA: Establecer el tipo de proyecto como consola App

[DllImport("kernel32.dll", SetLastError=true)] 
private static extern int FreeConsole();  
[STAThread] 
static void Main(string[] args) 
     { 
      if (args.Length == 0 && args[0] == "C") // Console 
      {      
       // Run as console code 
       Console.WriteLine("Running as Console App"); 
       Console.WriteLine("Hit any Key to exit"); 
       Console.ReadLine(); 
      } 
      else 
      { 
       //Console.SetWindowSize(1,1); 
       //string procName = Assembly.GetExecutingAssembly().FullName; 
       //ProcessStartInfo info = new ProcessStartInfo(procName); 
       //info.WindowStyle = ProcessWindowStyle.Minimized; 

       // EDIT: Thanks to Adrian Bank's answer - 
       // a better approach is to use FreeConsole() 
       FreeConsole(); 
       Application.Run(new MyForm()); 
      } 
     } 

EDIT: Gracias a la respuesta del Banco Adrian, FreeConsole() es mucho mejor enfoque de "dispensación" con la ventana de la consola de sólo minimizarla ...

+0

¿Cómo funciona? usted propone implementar eso exactamente? –

+0

Creo que las "Run as Console" y "Run as winforms" son los puntos interesantes aquí. El OP podría haber adivinado esto. –

+0

+1: No veo por qué esto habría sido downvoted ... es bastante simple y eficaz. Si cada tipo de UI (formularios frente a consola) es su propio ensamblaje, entonces el conmutador/if cargará el ensamblaje apropiado y lo ejecutará. –

2

Ellos son dos paradigmas diferentes, no creo que el uso de un modificador de línea de comandos como esta es una buena idea. ¿Por qué no construir la lógica del núcleo en una aplicación de consola y luego llamarla desde la GUI cuando sea necesario? Esto separaría muy bien la interfaz de usuario de la implementación, pero aún así proporcionaría una manera de usar la aplicación de la consola por sí sola cuando sea necesario.

+0

Aunque estoy de acuerdo con esto, es a veces es útil tener una sola aplicación que funcione como consola o GUI - Visual Studio es un ejemplo común de esto ... –

+0

Punto justo, no había pensado en eso. Asumiría que es algo bastante raro de necesitar. –

+0

Estoy pensando en crear dos UI, una consola y una gráfica, pero sí. La mejor solución es tenerlas en una. De esta forma, puedes usarla como una aplicación normal y usarla en un script, por ejemplo. – Svish

1

Creo que la respuesta es no, o fue la última vez que examiné este problema.

El ejecutable está marcado como una aplicación con ventana o una aplicación de consola. Puede ver esto en las propiedades para su proyecto en Visual Studio, bajo aplicación, Tipo de salida

Puede simular el comportamiento teniendo dos aplicaciones, una aplicación de consola que si se ejecuta sin argumentos, inicia la aplicación GUI. Es posible que aparezca una ventana de la consola flash, a menos que se haya ejecutado desde una consola ya abierta.

+1

Visual Studio hace ese truco, hay una aplicación de Windows 'devenv.exe' y una aplicación de consola' devenv.com'. –

8

De 'The Old New Thing'

¿Cómo se escribe un programa que se puede ejecutar ya sea como una consola o una aplicación de interfaz gráfica de usuario?

No puede.

(Voy a dejar que se hace clic en el artículo para los detalles de cómo fingir)

+0

¿Qué pasa con los 2 downvotes drive-by? – Aaron

+1

+1 para la referencia de Raymond Chen. –

0

Sin implementar su propia versión de una ventana de la consola la respuesta es no. Cuando Windows carga que ejecutable que decide si o no para darle una ventana de la consola basada en los datos de la cabecera PE. Por lo tanto, puede hacer que una aplicación con ventana no tenga una ventana, pero no puede hacer que una aplicación en pantalla tenga una consola.

+0

Esta es la respuesta correcta. – qub1n

0

Puede, pero con algunos inconvenientes:

Puede evitar tener esta ventana negro en el arranque si se compila para el subsistema de Windows.

pero luego se va a unir el proceso para la consola de llamada (cmd.exe) de forma manual a través de AttachConsole (-1) http://msdn.microsoft.com/en-us/library/windows/desktop/ms681952%28v=vs.85%29.aspx

Esto por sí solo no hace el trabajo. También hay que redirigir las tres corrientes std a la consola a través de estas llamadas:

// redirect unbuffered STDOUT to the console 
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); 
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 

fp = _fdopen(hConHandle, "w"); 
*stdout = *fp; 
setvbuf(stdout, NULL, _IONBF, 0); 

fp = _fdopen(hConHandle, "r"); 
*stdin = *fp; 
setvbuf(stdin, NULL, _IONBF, 0); 

// redirect unbuffered STDERR to the console 
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); 
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 

fp = _fdopen(hConHandle, "w"); 
*stderr = *fp; 
setvbuf(stderr, NULL, _IONBF, 0); 

// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog 
// point to console as well 
ios::sync_with_stdio(); 

Muestra de: http://cygwin.com/ml/cygwin/2004-05/msg00215.html

El problema con su llamada WinMain es que las ventanas ya ha bifurcada a cabo el proceso de manera que los cmd de llamadas .exe console ya habrá regresado de su .exe y continúe con el siguiente comando. Para evitar que pueda llamar a su exe con start /wait myexe.exe De esta manera también obtiene el valor de retorno de su aplicación y puede verificarlo con% errorlevel% como de costumbre.

Si hay una forma de evitar que se bifurque el proceso con las ventanas del subsistema, por favor avíseme.

Espero que esto ayude.

Cuestiones relacionadas