how to issue command to cmd prompt using WriteConsoleOutputCharacter() console function c++ - c++

i want to issue commands to cmd prompt through WriteConsoleOutputCharacter(), i have tried the following code but did not respond any result just it write "Dir" at x y cord..
I don't know whether it is possible or not, if answer is not then suggest any other solution same like this. This program is a bit part of my application.
int main()
{
HANDLE hStdout;
processHandler* process = new processHandler();
process->start("cmd.exe");
AttachConsole(process->getPID());
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coordScreen = { 0, 0 };
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
coordScreen.X=csbi.dwCursorPosition.X;
coordScreen.Y=csbi.dwCursorPosition.Y;
WriteConsoleOutputCharacter( hConsole,"dir",3,coordScreen,&cCharsWritten );
coordScreen.X+=3;
SetConsoleCursorPosition(hConsole,coordScreen);
getch();
}

Related

How to get the contents of the console window, if FarManager is running in it

I have an application that use a CreateProcess() function and create a new console window with FarManager run inside. The FarManager is installed on the computer and registered in the environment variable. The application itself is a server and accepts commands from the client. I have already implemented on the client the reading of pressed buttons and their transfer to the server. Pressing these buttons is simulated on the server and they are successfully executed in a window with an open FarManager. But now I need to get what is displayed in this window and somehow transfer it back to the client. At the same time, the manager is not installed on the client.
I don't understand how to do it. I would be grateful for any ideas and advices.
CreateProcess function:
TCHAR szCmdline[] = TEXT("C:\\Windows\\System32\\cmd.exe");
TCHAR prog[] = TEXT("D:\\Program Files\\Far Manager x86\\Far.exe");
// Create the child process.
bSuccess = CreateProcess(
prog, // far
szCmdline, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
CREATE_NEW_CONSOLE, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&si, // STARTUPINFO pointer
&pi); // receives PROCESS_INFORMATION
Execute command in FarManager function
//nVirtKey - code of virtual key to run in far
void ProcessInfo::RunFar(int nVirtKey){
//Create structure with buttons and their state
INPUT inputs[2] = {};
ZeroMemory(inputs, sizeof(inputs));
//Set key, that must be "pressed"
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = static_cast<WORD>(nVirtKey);
//Set state of key
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = static_cast<WORD>(nVirtKey);
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
//Set position of window with FarManger to the foreground (by the handle of window)
SetForegroundWindow(hwnd);
//Send key structure to window
UINT uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
}
Finction, that I used to find hwnd of window with FarManager by id of process (it's a little weird but works great)
//Find handle of far windows
HWND ProcessInfo::GetLastWindowsFromProcessID(){
HWND vhWnds = 0;
// find all hWnds (vhWnds) associated with a process id (dwProcessID)
HWND hCurWnd = NULL;
do
{
hCurWnd = FindWindowEx(NULL, hCurWnd, NULL, NULL);
DWORD dwProcID = 0;
GetWindowThreadProcessId(hCurWnd, &dwProcID);
if (dwProcID == pi.dwProcessId)
{
vhWnds = hCurWnd; // add the found hCurWnd
}
} while (hCurWnd != NULL);
return vhWnds;
}
Thanks in advance for any help!

Problem with the SetConsoleCursorPosition() function

I need a hand because I can't get the SetConsoleCursorPosition () function to work, I made a dll project and then I allocated the console with its main functions (cout and cin), but I don't know how to make that function work as well , in the sense that I do not go to the line that I have set, as the code ignored that instruction
void consolerefresh()
{
static const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord = { (SHORT)0, (SHORT)10 };
SetConsoleCursorPosition(hConsole, coord);
for (int i = 0; i < (sizeof(last) / sizeof(last[0])); i++)
{
if (last[i] != 2) {
cout << last[i] << endl;
}
}
}
My allocConsole code:
void createconsole()
{
AllocConsole();
FILE* fDummy;
freopen_s(&fDummy, "CONOUT$", "w", stdout);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONIN$", "r", stdin);
std::cout.clear();
std::clog.clear();
std::cerr.clear();
std::cin.clear();
}
EDIT: I fixed the error in the code but it still doesn't work.
Per SetConsoleCursorPosition, the first argument must be "a handle to the console screen buffer". Per GetStdHandle, the handle to the active console screen buffer is returned by STD_OUTPUT_HANDLE, not STD_INPUT_HANDLE which is the handle to the console input buffer.
Using the correct handle will get SetConsoleCursorPosition to work as expected.
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // instead of STD_INPUT_HANDLE
[ EDIT ]   The following was verified to work in VS 2019 using a default wizard-generated Win app with the following code added around wWinMain.
//... wizard generated code
#include <stdio.h>
#include <iostream>
void consolerefresh()
{
static const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord = { 5, 5 };
SetConsoleCursorPosition(hConsole, coord);
std::cout << "at (5, 5)" << std::endl;
}
void createconsole()
{
AllocConsole();
FILE* fDummy;
freopen_s(&fDummy, "CONOUT$", "w", stdout);
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
createconsole();
consolerefresh();
UNREFERENCED_PARAMETER(hPrevInstance);
//... rest of wizard generated code
Running the program creates a console window and displays the following.

Pasting data into any applications input field without simulating Ctrl+V. Windows c++

As my title states, I am trying to move data from a C++ application I am writing and input it into a field (specifically username and password fields) on any desktop application in windows. It needs to work for all applications.
Now I have already written a small program which copies data to the clipboard, and then simulates a Ctrl+V keyboard press to paste the data in. This however, feels like a terribly ugly way to do this. My question is, is there a better way?
Ps. From the research I have done everything seems to require that you modify the receiving application in some way. This option is unfortunately unavailable to me. So any solutions involving tweaking the receiving application won't be helpful.
Thank you for your help!
Sending keystrokes to another application is not a good solution. There are many potential problems, such as in C# sendkeys to other application to particular textfield. A better solution is to interface with the other program more directly. It requires a bit more technical understanding of how Windows works however. One of many advantages is that you can read text in the other application as easily as write it.
See my Clicking a Button in Another Application for a sample, but that is in C#. I hope the explanation at least is helpful. The same technique can be used to put data into a text box or text boxes then click a button. The WM_SETTEXT message would be used to put data into a textbox in another application. The following is a sample console program that puts text into Notepad.
#include "stdafx.h"
struct pidandhwnd {
DWORD dwProcessId;
HWND hwnd;
};
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
pidandhwnd *ppnh = (pidandhwnd *)lParam;
DWORD dwProcessId;
GetWindowThreadProcessId(hwnd, &dwProcessId);
if (ppnh->dwProcessId == dwProcessId)
{
ppnh->hwnd = hwnd;
return FALSE;
}
return TRUE;
}
int main()
{
TCHAR szCmdline[] = TEXT("Notepad.exe");
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bSuccess = FALSE;
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = NULL;
siStartInfo.hStdOutput = NULL;
siStartInfo.hStdInput = NULL;
LPARAM lParam = NULL;
pidandhwnd pnh;
const int ControlId = 15; // Edit control in Notepad
HWND hEditWnd;
bSuccess = CreateProcess(NULL,
szCmdline, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
if (!bSuccess) {
std::cout << "Process not started\n";
return 0;
}
std::cout << piProcInfo.dwProcessId << " Notepad Process Id\n";
WaitForInputIdle(piProcInfo.hProcess, 1000);
pnh.dwProcessId = piProcInfo.dwProcessId;
pnh.hwnd = NULL;
EnumDesktopWindows(NULL, EnumWindowsProc, (LPARAM)&pnh);
if (pnh.hwnd == NULL)
{
std::cout << "Notepad not found\n";
return 0;
}
//std::cout << "Notepad found\n";
// Get the edit box on Notepad
hEditWnd = GetDlgItem(pnh.hwnd, ControlId);
// Send the text
SendMessage(hEditWnd, WM_SETTEXT, NULL, (LPARAM)_T("This is from somewhere else."));
return 0;
}

How can I prevent my program from closing when a open console window is closed?

I am trying to open the console from my main program (Win32). I found some code, and it works, but I don't understand it. The problem I'm happening is that when I click X on the console, it closes the program as well.
Roughly I have this:
int APIENTRY WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) {
// create the main program window, classes registered, etc...
hwnd = CreateWindowEx(0, csClassName, "theNewTimer", WS_POPUP | WS_CLIPCHILDREN, 300, 0, WINDOW_WIDTH, WINDOW_HEIGHT, HWND_DESKTOP, NULL, hThisInstance, NULL);
ShowWindow (hwnd, nFunsterStil);
// and now the console
AllocConsole();
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
FILE* hf_out = _fdopen(hCrt, "w");
setvbuf(hf_out, NULL, _IONBF, 1);
*stdout = *hf_out;
HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
FILE* hf_in = _fdopen(hCrt, "r");
setvbuf(hf_in, NULL, _IONBF, 128);
*stdin = *hf_in;
// and then the message loop concluding
I googled some of it, but had no idea of what I was reading.
One thing you can do is disable the close button on the console window:
HWND hwnd = ::GetConsoleWindow();
if (hwnd != NULL)
{
HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
if (hMenu != NULL) DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
}
I do not think this is possible. From the MSDN documentation for a HandlerRoutine, there's this sentence.
The CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals give the process an opportunity to clean up before termination.
I read this as saying that CTRL_CLOSE_EVENT is advisory, and that the process is going to exit regardless. My guess is that when the system sends CTRL_CLOSE_EVENT, it starts a timer. The process is allowed to keep running for a little bit of time, but eventually, the OS will just kill the process unilaterally.
Here's the handler that I registered
BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) {
switch (dwCtrlType) {
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
return TRUE; // breakpoint set here
default:
return FALSE;
}
}
Here's how I registered the handler, after my call to AllocConsole:
BOOL result = SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE /* Add */);
assert(result);
I set a breakpoint on the line marked //breakpoint set here. Then, I ran the process under the Visual Studio debugger. When the console window was focused, I pressed Ctrl+C. My breakpoint got hit, and I was able to step through my handler and back into KernelBase.dll!CtrlRoutine and so on. The process kept running when I let the process resume normal execution.
However, when I closed the console window, my handler did get called, but I was unable to trace its execution very far. I was able to single step execution a few times, but then the process simply exited. Visual Studio reported "The program '[10644] Win32Project.exe' has exited with code -1073741510 (0xc000013a)."
0xc000013a is STATUS_CONTROL_C_EXIT:
c:\Tools\ERR>Err.exe 0xc000013a
# for hex 0xc000013a / decimal -1073741510 :
STATUS_CONTROL_C_EXIT ntstatus.h
# {Application Exit by CTRL+C}
# The application terminated as a result of a CTRL+C.
# 1 matches found for "0xc000013a"

Setting the Cursor Position in a Win32 Console Application

How can I set the cursor position in a Win32 Console application? Preferably, I would like to avoid making a handle and using the Windows Console Functions. (I spent all morning running down that dark alley; it creates more problems than it solves.) I seem to recall doing this relatively simply when I was in college using stdio, but I can't find any examples of how to do it now. Any thoughts or suggestions would be greatly appreciated. Thanks.
Additional Details
Here is what I am now trying to do:
COORD pos = {x, y};
HANDLE hConsole_c = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL );
char * str = "Some Text\r\n";
DWDORD len = strlen(str);
SetConsoleCursorPosition(hConsole_c, pos);
WriteConsole(hConsole_c, str, len, &dwBytesWritten, NULL);
CloseHandle(hConsole_c)
The text string str is never sent to the screen. Is there something else that I should be doing? Thanks.
Using the console functions, you'd use SetConsoleCursorPosition. Without them (or at least not using them directly), you could use something like gotoxy in the ncurses library.
Edit: a wrapper for it is pretty trivial:
// Untested, but simple enough it should at least be close to reality...
void gotoxy(int x, int y) {
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
See SetConsoleCursorPosition API
Edit:
Use WriteConsoleOutputCharacter() which takes the handle to your active buffer in console and also lets you set its position.
int x = 5; int y = 6;
COORD pos = {x, y};
HANDLE hConsole_c = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole_c);
char *str = "Some Text\r\n";
DWORD len = strlen(str);
DWORD dwBytesWritten = 0;
WriteConsoleOutputCharacter(hConsole_c, str, len, pos, &dwBytesWritten);
CloseHandle(hConsole_c);
Yeah, you forgot to call SetConsoleActiveScreenBuffer. What exactly was the point of creating your own? Use GetStdHandle(STD_OUTPUT_HANDLE) to get a handle to the existing console.
You were probably using ANSI excape code sequences, which do not work with Windows 32-bit console applications.
#include <windows.h>
#include <iostream.h>
using namespace std;
int main(int argc, char *argv[])
{
int x,y;
cin>>x>>y;
SetCursorPos(x,y); //set your co-ordinate
Sleep(500);
mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0); // moving cursor leftdown
mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0); // moving cursor leftup //for accessing your required co-ordinate
system("pause");
return EXIT_SUCCESS;
}