This tip guides Visual C++ developers on converting a Console project to hide the console screen.
This short write-up is a tip on making console program not to show console. As such, it is not eligible to participate in the CodeProject monthly article competition.
This tip is written in response to the Q&A question posted by Eduardo Quintana from Brazil. I encountered this same problem many years back when I downloaded an OpenGL tutorial that launched a console window before opening an OpenGL window. Having a console is extremely useful to log the messages to screen for troubleshooting but as a final product, only the OpenGL window should be shown to the user. In this tip, I'll show you how to convert a Visual C++ Console project not to show the console screen.
Firstly, to open Project Properties dialog, right-click on the project in the Solution Explorer and select Properties at the bottom of the pop-up menu or you can type Alt+Enter key. Select the Linker->System on the tree on the left panel. Then, change the Configuration dropdown to All Configurations and Platform dropdown to All Platforms. Finally, change the Subsystem from Console (/SUBSYSTEM:CONSOLE)
to Windows (/SUBSYSTEM:WINDOWS)
as shown on the screenshot.
- Configuration: All Configurations
- Platform: All Platforms
- Subsystem: Windows (/SUBSYSTEM:WINDOWS)
Then, you can rebuild the project, but you will encounter this linker error.
error LNK2019: unresolved external symbol WinMain referenced in function
"int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)
The solution is to add WinMain
function and include Windows.h. Console program starts from main
while Windows program begins from WinMain
. You can call your original main
from WinMain
.
#include <Windows.h>
int main()
{
return 0;
}
int __stdcall WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
OutputDebugStringA("Hello World!\n");
return main(); }
If you do not wish to include the heavy duty Window.h to bring in the WinMain
, you can declare WinMain
as such. I cannot do it here as I need the OutputDebugStringA
from that header.
#define HINSTANCE void*
#define LPSTR const char*
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd);
Rebuild your project. It should run without a console window. If you need to forward lpCmdLine
to your main
, you can use ParseCmdlineA
for ASCII or ParseCmdlineW
for Unicode version. Both take care of command argument specified in quotes. Unfortunately, lpCmdLine
does not contain the path of executable which I have to separately retrieve using GetModuleFileNameA
. This feature is suggested by Richard Chambers to make the solution complete.
void ParseCmdlineW(const wchar_t* cmdLine,
std::vector<wchar_t*>& vecArgs, std::wstring& holder)
{
}
void ParseCmdlineA(const char* cmdLine,
std::vector<char*>& vecArgs, std::string& holder)
{
}
#ifdef UNICODE
#define ParseCmdlineT ParseCmdlineW
#else
#define ParseCmdlineT ParseCmdlineA
#endif
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
OutputDebugStringA(argv[i]);
OutputDebugStringA("\n");
}
return 0;
}
int __stdcall WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
std::vector<char*> vecArgs;
std::string holder;
char executablePath[MAX_PATH];
DWORD res = GetModuleFileNameA(
NULL,
executablePath,
MAX_PATH
);
if (res != 0)
{
vecArgs.push_back(executablePath);
ParseCmdlineA(lpCmdLine, vecArgs, holder);
}
return main((int)vecArgs.size(), vecArgs.data());
}
Alternate Solutions: Hide the Console or Make a Window Service
In the article comment section, Stacy Dudovitz gives two solutions: either move the console window offscreen and hide it or make your application a Windows service. Marius Bancila has written an excellent Windows service article: Interact with Windows Services in C++; You can use it as a guide to write your service.
#include <Windows.h>
int main()
{
HWND hwnd = ::GetConsoleWindow();
::SetWindowPos(hwnd, NULL, 5000, 5000, 0, 0, 0);
::ShowWindow(hwnd, SW_HIDE);
return 0;
}
History
- 19th February, 2024: Added solution if user does not want to include Windows.h for
WinMain
- 7th February, 2024: Added alternate solutions by Stacy Dudovitz. Added
HideConsole
project download - 30th January, 2024: First release