Windows C++ CMD window switching - c++

Hello fellow programmers, I have a problem with some console applications in a C++ program, and my objective is as follows.
Create first CMD window.
Execute a command. (system("print some error text");)
Create second CMD window.
Change system(...) focus to second CMD window.
Execute a command.
Change system(...) focus to first CMD window.
Execute a command.
The end goal of all this is to create a function that will be executed by a CMD application that will spawn another CMD window, execute a command on it, and then return focus to the original CMD window to continue executing other code. I do not need to keep track of the window, or be able to return to it. Just create new window, switch focus to it, execute a command, return focus to original window.
The first CMD window is created when the application is started.
Executing a command to this window with system(...); works fine.
I create a second CMD window with
HWND new_hWnd = NULL;
ShellExecute(new_hWnd, "open", "cmd.exe", NULL, NULL, SW_SHOW);
This is where I have problems, I have not been able to redirect system(...) to a different CMD window, and this is the part I need help with because if I can figure this out, then steps 5, 6 and 7 will be easy to complete.
I've tried researching this online and have come across some different examples using "pipes" but have not been able to recreate them, or understand them. Also, I noticed there is a
GetConsoleWindow();
function that returns a handle to the current CMD window, which to me kinda signals that there should be a way to switch between CMD windows by using handles, but since I have not switched focus to the other CMD window I can not call that function to get it's handle.
So, how do I make system(...) target different CMD windows with handles? If that is not possible, how can I implement this "pipe" system.
If the solution is the latter, please try to be as detailed and simple as possible with it because every example of it I have found online is really large and hard to read/understand.
If there is no easy way to implement "pipes" then please post or point me to the best(something that will help me understand how pipes work) example you can find and I will keep working with it till I figure it out. Thank you in advance!

You can create a new console for the new process by specifying the dwCreationFlags value CREATE_NEW_CONSOLE when calling CreateProcess.
See the documentation:
Process Creation Flags: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
CreateProcess function: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

Related

How to run a command in C++ without a CMD window showing up?

So, to be more specific, I want to make a C++ program (Windows) that can execute a command without anything being displayed to the user.
No CMD window, No Command Output.
I would show my previous attempts, but it's not really anything useful, I just used the system() function to execute a command. I need to do the same, but without a popup window.
system() uses CreateProcess() to run cmd.exe /C <command>. You have no control over the console window that may be created.
Use CreateProcess() directly instead, so you can specify the CREATE_NO_WINDOW flag, and/or set its input STARTUPINFO::wShowWindow field to SW_HIDE.

C++ program to bring a process to foreground if already running otherwise create a new process

I am trying to learn windows programming. I would like to launch an executable program.exe (say) from c++ code. I am able to achieve this by using CreateProcess() method in windows. However, my problem is if the process is already created and running in the background then the windows for program.exe should come to foreground otherwise a new process should be created and brought to the foreground. Any help will be appreciated.
Look at Win32 API functions such as the following:
to discover if a given process is running, you can use:
CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS) with Process32First() and Process32Next(). See Taking a Snapshot and Viewing Processes.
or
EnumProcesses with OpenProcess() and GetModuleBaseName()/GetProcessImageFileName()/QueryFullProcessImageName(). See Enumerating All Processes.
to find an existing window, you can use:
FindWindow() or FindWindowEx(), if you know the window's class name or title text ahead of time.
or
EnumWindows() with GetClassName() and/or GetWindowText(), if the window's class name or title text are dynamic but follow a pattern you can look for.
to restore a window if it is minimized, you can use IsIconic() with SetWindowPos(SW_RESTORE).
to bring a window into the foreground, you can use BringWindowToTop() and/or SetForegroundWindow().
Is that program.exe written by you? This functionality is better handled there: on start you check if there is already an instance running and if there is - activate it.
Otherwise - what do you do if there are multiple instances of program.exe already running?

Creating a command interpreter process and writing to it

I have been trying to create a cmd.exe from a c++-program and then being able to execute commands from the program inside the cmd.exe, so I can view the results of the operation in the cmd.exe. CreateProcessA() is the function I used:
_STARTUPINFOA CMD_StartupInfo = {};
CMD_StartupInfo.cb = sizeof(_STARTUPINFOA);
_PROCESS_INFORMATION CMD_ProcessInfo = {};
CreateProcessA("C:\\Windows\\System32\\cmd.exe",
0,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&CMD_StartupInfo,
&CMD_ProcessInfo);
The cmd.exe opened and it looked to be working. Then I thought I'd use PostMessage() to pass WM_KEYDOWN messages to the cmd.exe to execute a command. For this function I needed a window handle and it turns out that the process of getting a window handle from a process/thread ID which is obtained from the CreateProcessA() is f***ing complicated. You have to loop through all active windows with EnumWindows() that requires a callback function which needs to check whether or not the process ID of the current window is the same as the process ID of the process I created.
I did that and it turned out that none of the windows the function iterated over were my window.
So I presume that means that the thread of this process which I created has no windows but I can see a beautiful-looking cmd.exe right there. What is going on? Is this not considered a window? If not, how do I pass messages to the cmd.exe and if yes, how do I get the window handle?
Any help is appreciated (also ideas to do the entire cmd-thing differently).

Win32 application with console output and without new window

I'd like to create a tool that can either act as command line (display some console output based on input parameters), or display a window, based on input parameters.
I'm using MSV2012 with C++, and it seems you have to 'choose' between console and window app.
I know the net is filled with samples which use AllocConsole() and redirect std::out, but it doesn't make it feel like a command line application : calling the exe from the windows console will open a new window with the console output...
Is there a way to have it use the current console window instead of allocating a new one?
If not possible, I'll make 2 applications instead, but that's a pity..
Someone else may have a more authoritative answer, but I don't believe it's supported.
The usual workaround is to create a Windows app, but have a command-line wrapper that launches it from the CLI (and provides a channel for communicating with the original console).
It's not technically supported but I found a good solution by getting a snapshot for the current process, finding the parent process, attaching to it's console if it's a console app or creating one with AllocConsole, redirecting the output, getting the thread of the parent process if it's cmd.exe and suspending it, resuming it just before I exit my app

How can I hide the command prompt of an application after it has started?

How do I go about suppressing the command prompt of a c++ application using the mingw compiler AFTER the program has started.. -mwindows works great in the linker settings but I want to be able to toggle it whilst the program is running, is this possible at all?
I am using a text editor and command line so no IDE related answers please.
As far as I know: no, at least not with a single executable. When you open an application in a Windows based console, it will start an instance of conhost.exe in order to provide an environment to your command line application. The console host will run as long as your applications hasn't exited.
It's hard to determine in which circumstances you'll need this behavior. But you could create two application - one which is a simple command line application, and one which has been compiled with -mwindows. The latter could call the first. After the first has exited the second will continue executing.
Note that this will leave the user bewildered, as it seems to him your application has stopped (as the console window has been closed) and a -mwindow compiled application doesn't create any GUI elements.
You can use WinAPI function ShowWindow to hide and show any window. There is a quirk, however - this function accepts an HWND handle as its argument and there is no obviuos way to obtain console HWND. Following is pretty convoluted way to get it:
HWND GetConsoleHwnd(void)
{
#define MY_BUFSIZE 1024 // Buffer size for console window titles.
HWND hwndFound; // This is what is returned to the caller.
TCHAR pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
// WindowTitle.
TCHAR pszOldWindowTitle[MY_BUFSIZE]; // Contains original
// WindowTitle.
// Fetch current window title.
GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
// Format a "unique" NewWindowTitle.
TCHAR * format=_TEXT("%d/%d");
wsprintf(pszNewWindowTitle,format,
GetTickCount(),
GetCurrentProcessId());
// Change current window title.
SetConsoleTitle(pszNewWindowTitle);
// Ensure window title has been updated.
Sleep(40);
// Look for NewWindowTitle.
hwndFound=FindWindow(NULL, pszNewWindowTitle);
// Restore original window title.
SetConsoleTitle(pszOldWindowTitle);
return(hwndFound);
}
Forgive me for this dirty trick, but it works perfectly in my code and is an official way of getting console HWND.
Some programs have to be of a console type. Like Emacs where the same executable can be launched to operate in console (with -nw option) and in GUI.
To hide that console there are lots of methods (including esoteric WSH scripts, or 3rd party utils, like nircmd exec hide notepad.exe) but there is a simple modern portable way:
powershell -c Start-Process -WindowStyle Hidden -FilePath notepad.exe
You can wrap that ugly command into .bat script alias.
PS Use Task Manager to kill hidden Notepad ))