Ссылка на исходники https://github.com/Avazart/Bicycle
Решил поделиться некоторыми своими велосипедами, подумал что возможно кому-то будет интересно взглянуть, а кто-то может еще и укажет на баги/недочеты.
Основа- классы:- Process
- SerialPort
- TcpClient
являющие собой обвертки над WinApi и Winsoсks.
Для этих классов есть специальный класс-поток TextStream позволяющий читать из объектов этих классов строки до разделителя(с буферизацией).
В нагрузку:- в паке Algorithm расположены алгоритмы для работы со строками split() и trim() (аналогичные boost/string/algorithm)
- классы TcpServer и Console
- вспомогательные классы для исключений, классы-обвертки над потоком, классы Any, Format, Library, пространство Path и прочие.
Process
Для работы класса Process в проект должны быть добавлены все файлы из папок Win/Common, Win/Process, Win/TextStream и файл Algorithm/Mismatch.h
Пример запуска системного калькулятора
C++ | 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
| #include <iostream>
#include "Win/Process/Process.h"
int main()
{
using namespace std;
using namespace Bicycle;
try
{
Process process;
process.start(L"",L"calc"); // Запускаем калькулятор
process.waitForInputIdle(); // Ждем готовности калькулятора
cout<<"Process ready."<<endl;
// Ждем 5 сек и закрываем программу
Sleep(5000);
process.closeWindows(); // Шлем WM_CLOSE окну
process.waitForFinished(); // Ждем завершения калькулятора
cout<<"Process finished with exit code #"<< process.exitCode() <<endl;
}
catch(const Exception& e)
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cerr<< e.message()<<endl;
}
getchar();
return 0;
} |
|
Пример чтения вывода утилиты ping
C++ | 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
| #include <iostream>
#include "Win/Process/Process.h"
#include "Win/Process/Pipe.h"
int main()
{
using namespace std;
using namespace Bicycle;
try
{
Process process;
process.setInheritHandle(true);
process.setSecurityInheritHandle(true);
process.usePipes(true);
process.start(L"",L"ping google.com");
ServerPipe& pipe= process.stdOut();
pipe.setTimeOut(30000);
const size_t bufferSize= 256;
char buffer[bufferSize]={'\0'};
ulong length= 0;
do
{
length= pipe.read(buffer,bufferSize);
if(length)
cout<< string(buffer,length);
}
while(length);
}
catch(const Exception& e)
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cerr<< e.message()<<endl;
}
getchar();
return 0;
} |
|
Пример с чтением и записью в пайп
C++ | 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
| #include <iostream>
#include <algorithm>
#include "Win/Process/Process.h"
#include "Win/TextStream/TextStream.h"
int main(int argc, char *argv[])
{
using namespace std;
using namespace Bicycle;
if(argc>1 && strcmp(argv[1],"-echo")==0) // эхо режим для дочернего.процесса
{
string line;
while(getline(cin,line))
{
if(line=="quit")
break;
reverse(line.begin(),line.end()); // переворачиваем строку
cout<<line<<endl;
}
}
else// главный процесс
{
try
{
Process process;
process.setInheritHandle(true);
process.setSecurityInheritHandle(true);
process.usePipes(true);
// Запускаем себя с эхо режиме
process.setCmdLine(appModuleFileName()+ L" -echo");
process.start();
TextStream inStream(&process.stdIn());
TextStream outStream(&process.stdOut());
string line;
while(getline(cin,line))
{
inStream.writeLine(line);
line= outStream.readLine();
cout<<"""<< line<<""" << endl;
}
}
catch(const Exception& e)
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cerr<< e.message()<<endl;
}
getchar();
}
return 0;
} |
|
Пример работы с окружением(переменными среды)
C++ | 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
| #include <iostream>
#include "Win/Process/Process.h"
#include "Win/Process/Environment.h"
#include "Win/TextStream/TextStream.h"
using namespace std;
using namespace Bicycle;
// --------------------------------------------------------------------------
void print(const Environment& env)
{
for (size_t i= 0; i< env.strings().size(); ++i)
wcout<< env.strings()[i]<< std::endl;
}
// --------------------------------------------------------------------------
int main(int argc, char* [])
{
setlocale(LC_ALL, "");
try
{
if(argc==1)
ProcessEnvironment::setVariable(L"MyVAR3",L"MyValue3.1");
Environment env= ProcessEnvironment::environment();
print(env);
if(argc==1)
{
Process process;
env.appendVariable(L"MyVAR1", L"MyValue1");
env.appendVariable(L"MyVAR2", L"MyValue2");
env.setVariable(L"MyVar3",env.variable(L"MyVaR3")+L";MyValue3.2");
process.setEnvironment(env);
process.setShowWindow(SW_NORMAL);
process.setCreationFlags(process.creationFlags()|CREATE_NEW_CONSOLE);
process.setCmdLine(appModuleFileName()+ L" -arg");
process.start();
wcout<< endl<< L"Create children process..."<< endl;
process.waitForFinished();
wcout<<"Children process finished with exit code: "<< process.exitCode()<<endl;
}
}
catch (const SystemException& e)
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cerr<< e.message()<< endl;
}
getchar();
return 0;
}
// -------------------------------------------------------------------------- |
|
SerialPort
Для работы класса Process в проект должны быть добавлены все файлы из папок Win/Common, Win/Serial, , Win/TextStream и файлы Algorithm/Trim.h и Algorithm/IsAnyOf.h
Пример построчного чтения из COM-порта
C++ | 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
| #include <iostream>
#include "Win/Serial/SerialPort.h"
#include "Win/TextStream/TextStream.h"
int main()
{
using namespace std;
using namespace Bicycle;
try
{
SerialPort serial;
serial.setPortName(L"COM9");
serial.setTimeOut(60000);
serial.setBaudRate(CBR_9600);
serial.open();
serial.waitEvent();
TextStream stream(&serial);
while(true)
{
string line= stream.readLine();
cout<<"""<<line<<"""<<endl;
}
}
catch(const Exception& e)
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cerr<< e.message()<<endl;
}
getchar();
return 0;
} |
|
Получение списка доступных COM-портов и информации о них
C++ | 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
| #include <iostream>
#include <vector>
#include "Win/Serial/SerialPortInfo.h"
#include "Win/Common/Exception.h"
int main()
{
using namespace std;
using namespace Bicycle;
setlocale(0,""); // Обязательно иначе будут проблемы
// с описанием устройств в кириллице
try
{
// Перечисляем доступные COM-порты и выводим информацию о них:
vector<SerialPortInfo> ports;
if(SerialPortInfo::availablePorts(ports))
{
for(size_t i=0; i<ports.size(); ++i)
{
wcout<< L"port name: " << ports[i].portName() << endl;
wcout<< L"hardware ids: "<< ports[i].hardwareIds()<< endl;
wcout<< L"vid: "<<hex << ports[i].parseId(L"vid_")<< endl;
wcout<< L"pid: "<<hex << ports[i].parseId(L"pid_")<< endl;
wcout<< L"manufacturer:" <<ports[i].manufacturer()<< endl;
wcout<< L"description: "<< ports[i].description() << endl;
wcout<< L"friendly name: "<<ports[i].friendlyName()<< endl;
wcout<< L"class guid: "<<ports[i].classGuid()<< endl;
wcout<<endl;
}
}
}
catch(const Exception& e)
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cerr<< e.message()<<endl;
}
getchar();
return 0;
} |
|
Console
Кликните здесь для просмотра всего текста
C++ | 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
| #include <iostream>
#include "Win/Console/Console.h"
using namespace std;
using namespace Bicycle;
void progress(int line,int maxCount);
int main()
{
try
{
// Меняем кодировку
Console::changeCp(1251);
// Меняем цвет текста и фона.
Console::setTextAttr(ConsoleColor::blue,ConsoleColor::red);
cout<<"Hello";
Console::setTextAttr(ConsoleColor::lime,ConsoleColor::yellow);
cout<<"world!"<<endl;
Console::setTextAttr(ConsoleColor::lime);
// Получаем/изменяем заголовок окна консоли.
wcout <<L"Title: "<<Console::title() << endl;
Console::setTitle(Console::originalTitle()+L" - Hello world!");
// Пример изменение шрифта
ConsoleFont font = Console::font();
cout <<"Font Size: "<<font.size().X<<"*"<< font.size().Y<<endl;
wcout<<"Font Name: "<<font.faceName()<<endl;
font.setSize(8,13);
font.setFaceName(L"Lucida Console");
Console::setFont(font);
// Консольный прогресс бар - пример использование передвижение курсора
Console::setTextAttr(ConsoleColor::blue);
progress(4,50);
// Очистка консоли
Console::clear();
}
catch(const SystemException& e)
{
cout<< e.message() << endl;
}
return 0;
}
void progress(int line, int maxCount)
{
cout<< "[";
Console::setCursorPos(maxCount+1,line);
cout<< "]";
Console::setCursorPos(1,line);
int a= 1;
int b= maxCount;
int k= +1;
int i= a;
for(int s=3; s>0; --s)
{
for(; i>=a && i<=b; i+=k)
{
Console::setCursorPos(i,line);
cout<< (k>0?"#":" ");
Sleep(s*100);
}
k*= -1;
i+= k;
Sleep(100);
}
} |
|
Темы:
- Окно DOS (cmd) в окне программы
- Friend и Шаблоны: найти причины возникновения ошибок в коде и исправить эти ошибки
- Получение переменных окружения
- Перенаправление вывода при запуске процесса
- Консольное приложение и GUI C++
- Нужно-ли таскать драйверы при переносе программы?
|