Хочу опробовать пример из книги Хармса, где реализована связь по анонимным каналам, однако при создании канал в северной части CreateProcess возвращает NULL. Предполагаю, что ошибка может быть при записи аргумента командной строки в lpszComLine или из-за кодировки текста. Подскажите, в чем может быть дело?
Процесс-клиент:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
HANDLE hWritePipe;
// преобразуем символьное представление дескриптора в число
hWritePipe = (HANDLE)atoi(argv[1]);
// ждем команды о начале записи в анонимный канал
printf("Press any key to start communication.\n");
system("pause");
// пишем в анонимный канал
for (int i = 0; i < 10; i++) {
DWORD dwBytesWritten;
if (!WriteFile(hWritePipe, &i, sizeof(i), &dwBytesWritten, NULL))
{
printf("Write to file failed.\n");
printf("Press any key to finish.\n");
system("pause");
return GetLastError();
}
printf("%d is written to the pipe.\n", i);
Sleep(500);
}
// закрываем дескриптор канала
CloseHandle(hWritePipe);
printf("The process finished writing to the pipe.\n");
printf("Press any key to exit.\n");
system("pause");
return 0;
}
Процесс-сервер:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
char lpszComLine[200]; // для командной строки
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE hWritePipe, hReadPipe, hInheritWritePipe;
// создаем анонимный канал
if (!CreatePipe(
&hReadPipe, // дескриптор для чтения
&hWritePipe, // дескриптор для записи
NULL, // атрибуты защиты по умолчанию, в этом случае
// дескрипторы hReadPipe и hWritePipe ненаследуемые
0)) // размер буфера по умолчанию
{
printf("Create pipe failed.\n");
printf("Press any key to finish.\n");
system("pause");
return GetLastError();
}
// делаем наследуемый дубликат дескриптора hWritePipe
if (!DuplicateHandle(
GetCurrentProcess(), // дескриптор текущего процесса
hWritePipe, // исходный дескриптор канала
GetCurrentProcess(), // дескриптор текущего процесса
&hInheritWritePipe, // новый дескриптор канала
0, // этот параметр игнорируется
TRUE, // новый дескриптор наследуемый
DUPLICATE_SAME_ACCESS)) // доступ не изменяем {
printf("Duplicate handle failed.\n");
printf("Press any key to finish.\n");
system("pause");
return GetLastError();
}
// закрываем ненужный дескриптор
CloseHandle(hWritePipe);
// устанавливаем атрибуты нового процесса
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
// формируем командную строку
printf(lpszComLine, "C:\\Users\\nbori\\Desktop\\Client\\x64\\Debug\\Client.exe %d", (int)hInheritWritePipe);
// запускаем новый консольный процесс
if (!CreateProcess(NULL, // имя процесса
lpszComLine, // командная строка
NULL, // атрибуты защиты процесса по умолчанию
NULL, // атрибуты защиты первичного потока по умолчанию
TRUE, // наследуемые дескрипторы текущего процесса
// наследуются новым процессом
CREATE_NEW_CONSOLE, // новая консоль
NULL, // используем среду окружения процесса-предка
NULL, // текущий диск и каталог, как и в процессе- предке
&si, // вид главного окна - по умолчанию
&pi // здесь будут дескрипторы и идентификаторы
// нового процесса и его первичного потока ))
{
printf("Create process failed.\n");
printf("Press any key to finish.\n");
system("pause");
return GetLastError();
}
// закрываем дескрипторы нового процесса
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
// закрываем ненужный дескриптор канала
CloseHandle(hInheritWritePipe);
// читаем из анонимного канала
for (int i = 0; i < 10; i++) {
int nData;
DWORD dwBytesRead;
if (!ReadFile(hReadPipe, &nData, sizeof(nData),
&dwBytesRead, NULL)) {
printf("Read from the pipe failed.\n");
printf("Press any key to finish.\n");
system("pause");
return GetLastError();
}
printf("The number %d is read from the pipe.\n", nData);
}
// закрываем дескриптор канала
CloseHandle(hReadPipe);
printf("The process finished reading from the pipe.\n");
printf("Press any key to exit.\n");
system("pause");
return 0;
}