studio programacion para móviles libros gratis español edición desarrollo curso aplicaciones .net windows console console-application

.net - para - manual programacion android español pdf



¿Es posible crear una aplicación de consola que no muestre una ventana de consola cuando se hace doble clic? (5)

Relacionado:
¿Debo incluir un modo de línea de comandos en mis aplicaciones?
¿Cómo agarrar la salida estándar del proceso padre?
¿Puede una aplicación de consola detectar si se ha ejecutado desde Explorer?

Quiero crear una aplicación de consola, que normalmente se ejecuta desde la línea de comandos.

Pero, cuando se hace doble clic desde el Explorador (en lugar de ejecutarse desde un indicador de cmd.exe), me gustaría que el programa NO muestre una ventana de consola.

Quiero evitar esto:

texto alt http://i36.tinypic.com/1088p5s.jpg

¿Es posible?

EDITAR Supongo que otra forma de preguntarlo es si es posible que un programa sepa cómo se invocó, ya sea haciendo doble clic o mediante la línea de comandos .

Estoy trabajando en .NET, en Windows.

EDITAR 2: De esta publicación del blog Old New Thing aprendí algunas cosas buenas. Esto es lo que sé ahora ...

En Windows, los archivos EXE están marcados como GUI o no GUI. Con csc.exe, esto se selecciona con /target:winexe o /target:exe . Antes de que se ejecute la primera instrucción en el proceso, el kernel de Windows configura el entorno de ejecución. En ese momento, si el EXE está marcado como GUI, el kernel establece el stdin / stdout para el proceso en NULL, y si no es GUI (línea de comando), el kernel crea una consola y establece el stdin / stdout para el proceso. consola.

Al iniciar el proceso, si no hay un stdin / stdout (== /target:winexe ), la llamada regresa inmediatamente. Por lo tanto, al iniciar una aplicación de GUI desde un cmd.exe, inmediatamente volverá a recibir su solicitud de cmd. Si hay un stdin / stdout, y si se ejecuta desde cmd.exe, entonces el cmd.exe principal espera la salida del proceso.

El "retorno inmediato" es importante porque si codifica una aplicación GUI para adjuntarla a la consola de su padre, podrá hacer console.writeline, etc. Pero el indicador de cmd.exe está activo. El usuario puede escribir nuevos comandos, iniciar un nuevo proceso, etc. En otras palabras, desde un winexe, simplemente unirlo a la consola principal con AttachConsole(-1) no lo "convertirá" en una aplicación de consola.

En este punto, creo que la única forma de permitir que una aplicación use la consola si se invoca desde cmd.exe, y NO la use si se hace doble clic, es definir el exe como un exe de consola normal ( /target:exe ), y ocultar la ventana en el inicio si es apropiado. Aún aparece una ventana de consola que aparece brevemente.

Todavía no he pensado cómo saber si se inició desde explorer o cmd.exe, pero me estoy acercando ...

RESPUESTAS

No es posible crear una aplicación de consola que no muestre una ventana de consola.

Es posible crear una aplicación de consola que oculte su ventana muy rápidamente, pero no tan rápido como si la ventana nunca apareciera.

Ahora, para determinar si una aplicación de consola se lanzó desde el explorador, algunos han sugerido mirar la consola en la que se está ejecutando.
(De la respuesta de mgb , y del artículo 99115 de KB ):

int left = Console.CursorLeft; int top = Console.CursorTop; bool ProcessWasRunFromExplorer = (left==0 && top==0);

Esto le indica si el proceso se inició en su propia consola, pero no si fue explorador. Un doble clic en el explorador haría esto, pero también un Start.Process () desde dentro de una aplicación haría lo mismo.

Si desea tratar esas situaciones de manera diferente, use esto para aprender el nombre del proceso principal:

System.Console.WriteLine("Process id: {0}", Process.GetCurrentProcess().Id); string name = Process.GetCurrentProcess().ProcessName ; System.Console.WriteLine("Process name: {0}", name); PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", name); Process p = Process.GetProcessById((int)pc.RawValue); System.Console.WriteLine("Parent Process id: {0}", p.Id); System.Console.WriteLine("Parent Process name: {0}", p.ProcessName); // p.ProcessName == "cmd" or "Explorer" etc

Para ocultar la ventana rápidamente después de iniciar el proceso, use esto:

private static readonly int SW_HIDE= 0; [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow); .... { IntPtr myHandle = Process.GetCurrentProcess().MainWindowHandle; ShowWindow(myHandle, SW_HIDE); }

Si produce un winexe (una aplicación WinForms) y, opcionalmente, adjunta a la consola principal cuando sea apropiado con AttachConsole(-1) , no obtiene el equivalente de una aplicación de consola normal. Para un winexe, el proceso principal (como cmd.exe) regresará al símbolo del sistema inmediatamente después de iniciar una aplicación GUI. En otras palabras, el símbolo del sistema está activo y listo para la entrada, mientras que el proceso recién iniciado puede emitir una salida. Esto es confuso y probablemente sea útil solo para la depuración de aplicaciones winforms.

Esto funcionó para mí.


¿Sería esto más como un servicio entonces?

O

¿Qué pasa con una aplicación de Windows Forms que no tiene un formulario visible? Todavía aparecería en la lista de Procesos del Administrador de Tareas.



No lo he leído todo, pero hice esto (hace poco, se necesitan más pruebas):

DWORD proc[2],procsfound=GetConsoleProcessList(proc,ELEMS(proc)); if (procsfound>1) // I''m started as a command in cmd.exe else // started from explorer or other non-console parent

IFF hay más de un proceso adjunto, necesito restaurar la consola que manipulé, de lo contrario no. Puede ser útil, al menos es la simplicidad misma. Iniciar el código desde VS generará un único proceso adjunto, ejecutarlo desde commandprompt activó la rama para limpiar mi desorden. Por cierto, ¿una consola lanzada desde el explorador u otra aplicación que no sea de consola tendrá un título de longitud cero?


Por lo tanto, he escrito herramientas con una GUI y una CLI. Lo difícil fue averiguar cuál abrir: en nuestro caso, sin embargo, la versión CLI tenía parámetros necesarios, por lo que simplemente abrí la GUI si no había ningún parámetro. Luego, si querían una consola, llame a una función que se parece a algo como:

private const int ATTACH_PARENT_PROCESS = -1; private const int ERROR_INVALID_HANDLE = 6; [DllImport("kernel32.dll", SetLastError = true)] static extern bool AttachConsole(int dwProcessId); [DllImport("kernel32.dll")] static extern bool AllocConsole(); [DllImport("kernel32.dll")] static extern bool FreeConsole(); private static bool StartConsole() { if (!AttachConsole(ATTACH_PARENT_PROCESS)) // try connecting to an existing console { if (Marshal.GetLastWin32Error() == ERROR_INVALID_HANDLE) // we don''t have a console yet { if (!AllocConsole()) // couldn''t create a new console, either return false; } else return false; // some other error } return true; }

Devuelve si la consola fue creada. ¡No te olvides de FreeConsole () cuando hayas terminado!

En nuestro caso, por supuesto, si no creamos una consola, creamos una GUI. Sin embargo, sería igual de fácil crear una consola o una interfaz de usuario.

EDIT: Eso no contestó totalmente la pregunta en la edición que no estaba allí cuando comencé a escribir eso, por supuesto. Aparte de eso, nuestro hack solo estaba comprobando si se llamaba con parámetros de línea de comandos o no.


Simplemente compílelo como una aplicación de Windows Forms, pero no le dé una GUI. Lamentablemente, entonces tampoco obtendrá ninguna salida de consola cuando se ejecute desde la línea de comandos ... ¿eso es un problema?