Задать вопрос

Почему не создается канал в си?

Хочу опробовать пример из книги Хармса, где реализована связь по анонимным каналам, однако при создании канал в северной части 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;
}
  • Вопрос задан
  • 358 просмотров
Подписаться 5 Средний 10 комментариев
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы