è possibile creare un programma che funziona come applicazione console se avviato dalla console e funziona come programma Windows (con GUI) se avviato diversamente?Problema console Win32
Se è possibile, come posso farlo?
riguarda Tobias
è possibile creare un programma che funziona come applicazione console se avviato dalla console e funziona come programma Windows (con GUI) se avviato diversamente?Problema console Win32
Se è possibile, come posso farlo?
riguarda Tobias
Se è necessario il programma per agire come un'applicazione di console (ad esempio, stampare le informazioni di utilizzo sulla console) è necessario compliant come un'applicazione console. Un'applicazione Windows non avrà accesso alla console e cmd.exe non aspetterà che finisca prima di stampare il prompt e accettare il comando successivo.
La soluzione migliore è disporre di due versioni, una per la riga di comando e una per la GUI (che gli utenti di solito eseguono tramite un collegamento sul desktop o dal menu Start).
Se si insiste sull'utilizzo di un singolo binario, è necessario vivere con una finestra della console visualizzata, almeno per un breve periodo. Si può sbarazzarsi della finestra della console utilizzando
FreeConsole();
Si può dire che l'applicazione è stato eseguito dalla GUI se è l'unico processo collegato alla console. È possibile utilizzare GetConsoleProcessList
per trovare l'elenco dei processi collegati alla console.
Il programma in sé non saprà mai come è stato avviato. A meno che non si sia disposti a passare argomenti di esecuzione al programma. Ad esempio: program.exe -GUI ... è possibile acquisire i parametri passati e decidere come deve essere eseguito il programma in base ai parametri passati.
vostro programma whould essere qualcosa del tipo:
class MainClass
{
public static int Main(string[] args)
{
// Test if input arguments were supplied:
if(args[0]=="GUI")
new myGUI().show(); //runs an instance of your gui
else
//you know what should go here
}
}
si può controllare il processo genitore della shell comando per determinare se è stato avviato tramite cmd o altrimenti. Il problema principale è la finestra cmd che viene mostrata se il flag è impostato nell'intestazione pe. –
È possibile nascondere la finestra di cmd. È possibile. – deadlock
puoi controllare l'handle std con GetStartUpInfo. (http://msdn.microsoft.com/en-us/library/ms683230(v=vs.85).aspx) più la grande idea di Len's Holgate. quindi ti sbagli, ci sono modi. – Andrey
È possibile ordinare di indovinare se si sono avviati dalla console o no in questo modo:
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
fConsole = csbi.dwCursorPosition.X | csbi.dwCursorPosition.Y;
E 'una supposizione - se il vostro la posizione del cursore non è 0,0 di quella di una console e può funzionare come un'app console. Altrimenti vai e crea le tue finestre.
Un altro modo per indovinare è guardare l'albero del processo e vedere quale processo ha avviato la tua app. Se è cmd.exe vai in modalità console, altrimenti vai in modalità GUI.
Se si imposta il programma come un programma GUI, è possibile tentare di collegarlo alla console utilizzando AttachConsole(). Si collega OK, si è avviato da una console e si può procedere a reindirizzare i propri handle standard alla console appena collegata.
In questo modo è possibile avviare e vedere se si è avviato da una console a cui è possibile collegarsi e in tal caso diventare un programma di console. Se non puoi allegare puoi mostrare una GUI.
Ho avuto un po 'di successo con questo, il problema principale che ho è la visualizzazione del prompt della finestra di comando quando il mio programma si chiude (che è come funzionano i normali programmi della console), ma mi aspetto che tu possa fare qualcosa di intelligente (leggi la console buffer all'avvio e trovare la richiesta di rivisualizzare quando si esce?) se si voleva davvero ...
Utilizzare invece AllocConsole(). –
Ma non creerai una nuova finestra console invece di connetterti al prompt dei comandi che ha lanciato la tua finestra della console? –
Sì. Non esiste alcuna restrizione documentata sulla chiamata di 'AttachConsole' da un programma della GUI; non è solo l'impostazione predefinita. – MSalters
Ne fanno un'applicazione console e mettere questo nel codice:
void ConsoleWindowVisible(bool show)
{
DWORD dummy;
if
(
!show && // Trying to hide
GetConsoleProcessList(&dummy, 1) == 1 // Have our own console window
)
ShowWindow(GetConsoleWindow, SW_HIDE); // Hide the window
else // Trying to show or use parent console window
ShowWindow(GetConsoleWindow, SW_NORMAL); // Show the window
}
int main(int argc, char** argv)
{
ConsoleWindowVisible(false);
}
Cin cin.
Questa è la risposta di Dan Tillett ed è notevolmente efficace. Niente flash, niente .com e .exe per ingannare cmd.exe. Sembra funzionare in modo impeccabile digitando il comando, in un file .bat, con lo stato attivo, senza messa a fuoco e come applicazione con doppio clic sull'interfaccia grafica.
Sono le api le ginocchia!
Questa è la pagina web che la descrive, ma l'ho postata qui perché se quella pagina diventasse 404 il mese prossimo o 2 anni da oggi, la soluzione eccellente e "più completa" che ho visto sarebbe "fuori dalla rete" ".
#define WINVER 0x0501 // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#pragma comment(lib, "User32.lib")
// Attach output of application to parent console
static BOOL attachOutputToConsole(void) {
HANDLE consoleHandleOut, consoleHandleError;
int fdOut, fdError;
FILE *fpOut, *fpError;
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
//redirect unbuffered STDOUT to the console
consoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE);
fdOut = _open_osfhandle((intptr_t)consoleHandleOut, _O_TEXT);
fpOut = _fdopen(fdOut, "w");
*stdout = *fpOut;
setvbuf(stdout, NULL, _IONBF, 0);
//redirect unbuffered STDERR to the console
consoleHandleError = GetStdHandle(STD_ERROR_HANDLE);
fdError = _open_osfhandle((intptr_t)consoleHandleError, _O_TEXT);
fpError = _fdopen(fdError, "w");
*stderr = *fpError;
setvbuf(stderr, NULL, _IONBF, 0);
return TRUE;
}
//Not a console application
return FALSE;
}
//Send the "enter" to the console to release the command prompt on the parent console
static void sendEnterKey(void) {
INPUT ip;
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
//Send the "Enter" key
ip.ki.wVk = 0x0D; // virtual-key code for the "Enter" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release the "Enter" key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) {
int argc = __argc;
char **argv = __argv;
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
BOOL console;
int i;
//Is the program running as console or GUI application
console = attachOutputToConsole();
if (console) {
//Print to stdout
printf("Program running as console application\n");
for (i = 0; i < argc; i++) {
printf("argv[%d] %s\n", i, argv[i]);
}
//Print to stderr
fprintf(stderr, "Output to stderr\n");
}
else {
MessageBox(NULL, "Program running as windows gui application",
"Windows GUI Application", MB_OK | MB_SETFOREGROUND);
}
//Send "enter" to release application from the console
//This is a hack, but if not used the console doesn't know the application has returned
//"enter" only sent if the console window is in focus
if (console && GetConsoleWindow() == GetForegroundWindow()){
sendEnterKey();
}
return 0;
}
bella idea. Grazie. –