Creating a new console.

Hello, I came across this topic

http://www.cplusplus.com/forum/lounge/17371/

But I'm having problem implementing it. The new console disappears as soon as it is created. Can anybody explain why?? And also can anyone post a good example illustrating the creation and use of new console using that code.
I failed to mention it back then, but the code expects the client to be named "console.exe". That could be the problem.
@helios
Hi there, thanks for the reply. I changed the exe name to console. Here's the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//SERVER CODE

#include <windows.h>
#include <string>
#include <assert.h>
#include <cstdio>
typedef unsigned long ulong;
class VirtualConsole{
	HANDLE near_end, //Our end of the pipe, where we'll write.
		far_end, //The other end.
		process; //The client.
public:
	bool good;
	VirtualConsole(const std::string &name,ulong color);
	~VirtualConsole();
	void put(const char *str,size_t size=0);
	void put(const std::string &str){
		this->put(str.c_str(),str.size());
	}
};

VirtualConsole::VirtualConsole(const std::string &name,ulong color){
	this->good=0;
	SECURITY_ATTRIBUTES sa;
	sa.nLength=sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle=1;
	sa.lpSecurityDescriptor=0;
	if (!CreatePipe(&this->far_end,&this->near_end,&sa,0)){
		assert(this->near_end==INVALID_HANDLE_VALUE);
		return;
	}
	SetHandleInformation(this->near_end,HANDLE_FLAG_INHERIT,0);
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	ZeroMemory(&pi,sizeof(pi));
	ZeroMemory(&si,sizeof(si));


	si.cb=sizeof(STARTUPINFO);
	si.hStdInput=this->far_end;
	si.dwFlags|=STARTF_USESTDHANDLES;
	si.lpTitle = (CHAR*)name.c_str();

	TCHAR program[]=TEXT("console.exe");
	TCHAR arguments[100];
#ifndef UNICODE
	sprintf(arguments,"%d",color);
#else
	swprintf(arguments,L"0 %d",color);
#endif
arguments[2] = '\0';
	CreateProcess(program,arguments,0,0,1,CREATE_NEW_CONSOLE|CREATE_UNICODE_ENVIRONMENT,0,0,&si,&pi);
	int Err = GetLastError();
	if (Err != ERROR_SUCCESS) return;

	this->process=pi.hProcess;
	CloseHandle(pi.hThread);
	this->good=1;

	this->put(name);
	this->put("\n",1);
}

VirtualConsole::~VirtualConsole(){
	if (this->near_end!=INVALID_HANDLE_VALUE){
		if (this->process!=INVALID_HANDLE_VALUE){
			TerminateProcess(this->process,0);
			CloseHandle(this->process);
		}
		CloseHandle(this->near_end);
		CloseHandle(this->far_end);
	}
}

void VirtualConsole::put(const char *str,size_t size){
	if (!this->good)
		return;
	if (!size)
		size=strlen(str);
	DWORD l;
	WriteFile(this->near_end,str,size,&l,0);
}


//CLIENT CODE

#define BUFSIZE 4096

int main(int argc,char **argv){
	CHAR chBuf[BUFSIZE];
	DWORD dwRead;
	HANDLE hStdin;
	BOOL fSuccess;
    VirtualConsole VC("some",0);

	hStdin = GetStdHandle(STD_INPUT_HANDLE);
	if (hStdin == INVALID_HANDLE_VALUE)
		ExitProcess(1);

	HANDLE out=CreateFile(TEXT("CONOUT$"),GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
	if (out==INVALID_HANDLE_VALUE)
		return 1;
	if (argc>1){
		WORD color=atoi(argv[1]);
		SetConsoleTextAttribute(out,color);
	}

	while (1){
		fSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);
		if (!fSuccess || !dwRead)
			break;
		WriteFile(out,chBuf,dwRead,&dwRead,0);
	}
	getchar();
}



As you can clearly see, I've put both the server and client code in a same program. And it doesn't work. I mean it does work but it keeps on creating a new console.exe. I know why it happens. The program creates a new console.exe which in turn creates another console.exe and so on. Actually, I'm having problem in the implementation of your code. Are server and client meant to be different applications? If yes (and that's what my guess is) how are we supposed to use it. This is so confusing.
So, I would be extremely glad if you were to provide full code of an extremely simple implementation.
Are server and client meant to be different applications?
Yes.

how are we supposed to use it
The code that was labeled "server" in my original post goes in your main program (the one you want to spawn more consoles). The "client" goes in a program of its own whose only purpose is to receive messages from the server and print them on its console. The client should be in the working directory, or the system should be able to find it in PATH.
Last edited on
thanks!!!
Topic archived. No new replies allowed.