Tipicamente quando si realizza un software standard (console), indipendentemente che se effettuti output a schermo o meno,
resta sempre aperta per tutta l'esecuzione del programma la tipica finestra nera in vecchio stile promt dei comandi.
Questa finestra può però risultare scomoda in molti casi:
Si pensi a un programma che resta in continua esecuzione sul pc (mi viene in mente un mio vecchio programmino che, restando sulla tray,
rilevava il traffico in/out della connessione internet), o a un software che sposta o pulisce file sull'hd e visualizza un messaggio solo alla
conclusione del lavoro.. in questi esempi come si intuisce facilmente sarebbe tanto scomodo quanto inutile (e a rischio di non voluta terminazione)
mantenere aperta la console durante l'esecuzione del programma.
Risulta quindi molto utile in certi casi poter nascondere questa fastidiosa finestra in determinate circostanze e questo è possibile in C
tramite pochissime righe di codice! Vediamo come:
| Nascondere la finestra di console: 1 metodo: | |
Il primo metodo per nascondere la finestra utilizza due semplici API fornite dal sistema operativo:
Mediante la combinazione di queste due funzioni si ricava l'handle della finestra attiva del nostro
programma e la si nasconde, settandola a SW_HIDE. Vediamo un esempio di utilizzo di queste funzioni per lo scopo
appena descritto:
/* hide1.c - Nascondere la finestra del programma */ #include <windows.h> #include <stdio.h> int main() { BOOL Success; /* Variabile di controllo */ HWND WinhWnd; /* Indirizzo finestra */ WinhWnd = GetConsoleWindow(); /* Ricavo l'handle della finestra */ Success = ShowWindow(GetConsoleWindow(),SW_HIDE); /* Nascondo */ if (!Success){ printf("Errore: La finestra e' ancora visibile"); } ... ... ... return 0; }
|
Vantaggi: Semplicità
Svantaggi: La finestra del programma parte visibile e si nasconde solamente dopo l'esecuzione della funzione ShowWindow).
| Nascondere la finestra di console: 2 metodo: | |
Questo secondo metodo consiste semplicemente nel cambiare le impostazioni generali del progetto, portandolo da progetto console a progetto Win32,
in modo tale che la console del programma sia già hiddata di default.
Questa procedura varia da compilatore a compilatore; in questo esempio mi riferiro al compilatore Microsoft Visual C++ 6.0 ne per
fare questo esistono 2 modi:
1) Modifica diretta delle impostazioni del linker
Occorre andare nel menu Project -> Property e selezionare dal Linker la voce "System".
E selezionare nel menù riferito al Subsistem la voce "/SUBSYSTEM:WINDOWS".
2) Aggiunta della direttiva #pragma comment
In questo modo si può evitare di modificare direttamente le impostazioni del progetto aggiungendo unicamente una direttiva
all'inizio del codice del nostro programma:
Vediamo un esempio di programma con questo secondo metodo: /* hide2.c - Nascondere la finestra del programma */ #pragma comment(linker,"/subsystem:windows") #include <windows.h> #include <stdio.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ... ... ... return 0; }
|
Quando si utilizza questo metodo, realizzando applicazioni win32, bisogna anche cambiare l'entry point del programma da
dal classico main() a WinMain(). Vantaggi: Assoluta semplicità
Svantaggi: Nessuno.
| Nascondere l'intero processo dal Task Manager | |
Per completezza ricordo che i due procedimenti visti findo ad ora nascondono solamente
la finestra del programma alla visione dell'utente mentre il processo resta comunque visibile al task manager.
Nascondere un processo anche alla lista dei processi attivi è possibile solo nei sistemi Windows 95, Windows 98, Windows ME ma non successivi.
Per effettuare questa operazione occorre registrare il proprio processo al sistema come un processo di sistema.
Riporto di seguito un veloce esempio di questa obsoleta tecnica importando la funzione di regitrazione dalla libreria di sistema kernel32.dll: /* win98hide.c - Nascondere il programma al task manager */ #include <windows.h> #include <stdio.h> /* Definisco la procedura da importare */ typedef DWORD (_stdcall* *pRegister)(DWORD, DWORD); int main() { /* Carico la libreria con la funzione da importare */ HMODULE hKERNEL32 = LoadLibrary("kernel32.dll"); if (hKERNEL32 == NULL) { printf("Errore nell'importazione della libreria kernel32.dll"); return 1; } /* Importo la funzione di registrazione */ pRegister = (DWORD(_stdcall*)(DWORD, DWORD)) GetProcAddress(hKERNEL32, "RegisterServiceProcess"); if (pRegister) /* La eseguo sul processo corrente */ pRegister(GetCurrentProcessId(), 1); else printf("Errore nell'importazione della procedura di registrazione"); FreeLibrary(hKERNEL32); /* Rilascio il modulo */ ... ... ... return 0; }
|
Per nascondere completamente l'esecuzione di codice proprio all'interno di una macchina occorrono procedimenti più complessi come il
code injection. Chi fosse interessato a questa interessante tecnica può trovare un'ottima guida al link:  |