Just want to write to console if run from commandline...



  • I've got a bog simple qt quick application that can be passed command line arguments - pretty standard way to manipulate your application.

    When someone misuses these command line arguments, I need to be able to indicate this on the command line without starting up the GUI.

    For some reason, this appears to be a difficult task in Qt 5.6.

    I've tried std::cout - no luck, nothing gets printed even in the debugger.
    I've tried qDebug, it gets printed in the debugger, but does not get printed when running from the command line (this is a debug build.)
    I've tried TextStream output, nothing shows in the debugger, and nothing from the command line.

    Surely I am missing something really simple, right?

    Some compile setting? Someflag? Something in the configuration?

    Thanks

    ** Update **

    I have only tested this (today) on Windows 10 - so I wonder if this is an artifact of the Windows subsystem limitations...

    I'll test on OSX tomorrow, if it's a Windows only thing, I can probably hack a solution by allocating a console.


  • Moderators

    I guess you're trying to write to console in your main.cpp?
    Can you show it?
    If you do it after starting the event loop then there will be nothing written because that code will not be executed:

    int main(int argc, char *argv[])
    {
        std::cout << "This will be printed" << std::endl;
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
        std::cout << "This will not be printed" << std::endl;
    }
    


  • Sadly, on WIndows that doesn't happen - it did turn out to be a windows subsystem issue.



  • Turns out that after figuring out that I needed to call AttachConsole, I searched the forums again and found that this question is a duplicate of the already solved question:

    Attach console to GUI application on Windows

    Thanks to @T3STY for solving this already :)

    BTW, on other operating systems you'll find that you may need to manually flush stdout at certain times in the application lifecycle.



  • BTW, in case anyone needs an example, here's mine:

    #include "ConsoleLogger_Windows.h"
    #include <windows.h>
    
    
    ConsoleLogger_Windows::ConsoleLogger_Windows( void )
    {
    	m_bConnectedToConsole = false;
    	
    	// Attach to the console if launched via command line so that we can emit messages about misused command line arguments
    	AttachToParentProcessConsole();
    }
    
    ConsoleLogger_Windows::~ConsoleLogger_Windows( void )
    {
    	// TBD: Release the console if we were launched via command line
    	DetachFromParentProcessConsole();
    }
    
    bool ConsoleLogger_Windows::AttachToParentProcessConsole( void )
    {
    	// Don't attach to more than one console
    	if( true == m_bConnectedToConsole )
    	{
    		// TBD: Logging
    		return false;
    	}
    
    	try
    	{
    		// If we were launched from the command line, we should usually be able to attach to the console
    		if( AttachConsole( ATTACH_PARENT_PROCESS ) )
    		{
    			m_bConnectedToConsole = true;
    
    			// Re-open the streams to the console
    			freopen( "CON", "w", stdout );
    			//freopen( "CON", "w", stderr );
    			//freopen( "CON", "r", stdin );
    		}
    		else
    		{
    			// We were not launched from the command line - or there's a security issue with trying to attach
    			return false;
    		}
    
    		return true;
    	}
    	catch( ... )
    	{
    		// TBD: Logging
    	}
    
    	return false;
    }
    
    
    bool ConsoleLogger_Windows::DetachFromParentProcessConsole( void )
    {
    	// Nothing to do if we're not connected to a console
    	if( false == m_bConnectedToConsole )
    	{
    		return true;
    	}
    
    	try
    	{
    		// Send an enter key as the console being freed is not enough to release it
    		HANDLE hConsoleInputHandle = GetStdHandle( STD_INPUT_HANDLE );
    		INPUT_RECORD aInputRecords[1];
    		DWORD nEventsWritten = 0;
    
    		if( NULL == hConsoleInputHandle )
    		{
    			// TBD: Logging to event viewer (are we running headless?)
    			return false;
    		}
    
    		aInputRecords[0].EventType = KEY_EVENT;
    		aInputRecords[0].Event.KeyEvent.bKeyDown = TRUE;
    		aInputRecords[0].Event.KeyEvent.uChar.UnicodeChar = VK_RETURN;
    		aInputRecords[0].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
    		aInputRecords[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey( VK_RETURN, MAPVK_VK_TO_VSC );
    		aInputRecords[0].Event.KeyEvent.wRepeatCount = 1;
    		aInputRecords[0].Event.KeyEvent.dwControlKeyState = 0;			
    			
    		WriteConsoleInput( hConsoleInputHandle, aInputRecords, 1, &nEventsWritten );
    
    		if( nEventsWritten != 1 )
    		{
    			// TBD: Logging to event viewer (are we running headless?)
    		}
    
    		if( FALSE == FreeConsole() )
    		{
    			// TBD: Logging to event viewer (are we running headless?)
    			return false;
    		}
    
    		return true;
    	}
    	catch( ... )
    	{
    		// TBD: Logging to event viewer (are we running headless?)
    	}
    	
    	return false;
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.