Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.09.2021, 15:57   #1
druidvic
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 45
По умолчанию как обратиться к нескольким службам

Приветствую уважаемые. Подскажите пжл., как вынести выделенный красным код в отдельную функцию, чтобы можно было в main () ее вызвать с разным аргументом lpServiceName.
Код:
#include <windows.h>
#include <stdio.h>
#include <locale>
using namespace std;


int main()
{
setlocale(LC_CTYPE, "");//локаль по умолчанию
SC_HANDLE  schSCManager, schService; //инициализация указателей на базу данных служб и на службу
LPCSTR    lpServiceName="SharedAccess";//Общий доступ к подключению к Интернету (ICS) отключена
//LPCSTR    lpServiceName="RemoteRegistry";
//LPCSTR    lpServiceName="SCardSvr";//5-доступ запрещен

//подключение к базе служб
 schSCManager=OpenSCManager(
        NULL,//локальная машина
        NULL,//активная база данных сервисов
        SC_MANAGER_CONNECT//соединение с менеджером
        );
    if (schSCManager==NULL)
    {
        printf("Ошибка подключения к менеджеру служб(%ld)\n Код ошибки: ", GetLastError());
        return 0;
    }

    printf("Менеджер служб подключен.\n");


    //подключение к службе
schService=OpenService(
    schSCManager,
    lpServiceName,
    GENERIC_ALL); //полный доступ

    //проверка подключения
    if (schService==NULL)
    {
        printf("Ошибка в службе (%ld)\n", GetLastError());
        CloseServiceHandle(schSCManager); //закрыть дескритор
    printf ("\n Дескриптор закрыт.");
        return 0;
    }
printf ("Подключена (%s)", lpServiceName);


    // закрываем дескриптор менеджера сервисов
    CloseServiceHandle(schSCManager);
    printf ("\nДескриптор закрыт.");
    return 0;

}
Не копировать же для каждой службы такую длинную "портянку" кода.

P.S. После действия со службой (каждой) ее дескриптор закрывать? или при закрытии дескриптора менеджера ранее открытые дескрипторы служб закроются автоматом?
druidvic вне форума Ответить с цитированием
Старый 20.09.2021, 08:44   #2
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 960
По умолчанию

Цитата:
Сообщение от druidvic Посмотреть сообщение
После действия со службой (каждой) ее дескриптор закрывать?
в документации нужно уточнять для каждой функции

для обеих функций написано, что
Цитата:
It can be closed by calling the CloseServiceHandle function.
то есть, как бы нет принуждения, но можно вот именно так закрыть, когда нужно. Думаю, лучше закрывать

для этого удобнее всего сделать класс-обёртку над хендлом, где в деструкторе будет произведено закрытие

Цитата:
Сообщение от druidvic Посмотреть сообщение
как вынести выделенный красным код в отдельную функцию
также, как это делается обычно. Делаешь функцию, тащишь туда код. Внимательно осматриваешь, что должно было придти через аргументы, а что должно вернуться. Затем компилятор подскажет, чего не хватает. Затем тестируешь.
А возвращать нужно будет экземпляр обёртки над хендлом

Последний раз редактировалось Алексей1153; 20.09.2021 в 11:21.
Алексей1153 вне форума Ответить с цитированием
Старый 20.09.2021, 09:00   #3
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 960
По умолчанию

что-то вроде (но не тестировал)

Код:
#include <windows.h>
#include <winsvc.h>
#include <stdio.h>
#include <locale>

struct s_SC_HANDLE_wrapper
{
	SC_HANDLE handle{};

	s_SC_HANDLE_wrapper()=default;
	s_SC_HANDLE_wrapper(const s_SC_HANDLE_wrapper&)=delete;
	s_SC_HANDLE_wrapper(s_SC_HANDLE_wrapper&&)=delete;
	s_SC_HANDLE_wrapper& operator=(const s_SC_HANDLE_wrapper&)=delete;
	s_SC_HANDLE_wrapper& operator=(s_SC_HANDLE_wrapper&&)=delete;

	//подключение к базе служб
	bool OpenSCManager()
	{
		Close();
		handle=::OpenSCManager(
			{},//локальная машина
			{},//активная база данных сервисов
			SC_MANAGER_CONNECT//соединение с менеджером
		);

		if(!handle)
		{
			printf("Ошибка подключения к менеджеру служб(%ld)\n Код ошибки: ", GetLastError());
			return false;
		}

		printf("Менеджер служб подключен.\n");
		return true;
	}

	//подключение к службе
	bool OpenService(const s_SC_HANDLE_wrapper& schSCManager,LPCSTR lpServiceName)
	{
		Close();
		if(!lpServiceName)return false;
		if(!schSCManager)return false;
		handle=::OpenService
		(
			schSCManager.handle,
			lpServiceName,
			GENERIC_ALL //полный доступ
		);

		//проверка подключения
		if(!handle)
		{
			printf("Ошибка в службе (%ld)\n", GetLastError());
			return false;
		}
		printf ("Подключена (%s)", lpServiceName);

		return true;
	}

	void Close()
	{
		if(handle)
		{
			::CloseServiceHandle(handle);
		}
		handle={};
	}

	constexpr operator bool()const noexcept
	{
		return !!handle;
	}

	~s_SC_HANDLE_wrapper()
	{
		Close();
	}
};

int main()
{
	setlocale(LC_CTYPE, "");//локаль по умолчанию

	LPCSTR    lpServiceName="SharedAccess";//Общий доступ к подключению к Интернету (ICS) отключена
	//LPCSTR    lpServiceName="RemoteRegistry";
	//LPCSTR    lpServiceName="SCardSvr";//5-доступ запрещен

	//подключение к базе служб
	s_SC_HANDLE_wrapper schSCManager;
	if(!schSCManager.OpenSCManager())
	{
		return 0;
	}

	//подключение к службе
	s_SC_HANDLE_wrapper schService;
	if(!schService.OpenService(schSCManager,lpServiceName))
	{
		return 0;
	}

	return 0;
}

Последний раз редактировалось Алексей1153; 20.09.2021 в 09:03.
Алексей1153 вне форума Ответить с цитированием
Старый 20.09.2021, 11:19   #4
druidvic
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 45
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
что-то вроде (но не тестировал)
Спасибо что откликнулись. Буду пробовать разобраться.
P.S. Блин, как все непривычно и сложно
В Basic call ... return и все
P.S.S. Ассемблер легче давался.
druidvic вне форума Ответить с цитированием
Старый 20.09.2021, 11:23   #5
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 960
По умолчанию

Цитата:
Сообщение от druidvic Посмотреть сообщение
как все непривычно и сложно
классы - это самые-самые основы C++. Если сложно - нужно не полениться, взять любую книжку для чайников по C++11 (или более старшие стандарты) и после первых глав всё станет понятно по этой теме
Алексей1153 вне форума Ответить с цитированием
Старый 20.09.2021, 18:58   #6
druidvic
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 45
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
классы - это самые-самые основы C++. Если сложно - нужно не полениться, взять любую книжку для чайников по C++11 (или более старшие стандарты) и после первых глав всё станет понятно по этой теме
Читаю
Р. ЛАФОРЕ ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++
4-Е ИЗДАНИЕ 2004 г.
Александр Побегайло Системное программирование в Windows 2006 г.
Системное программирование В среде Windows Третье издание Джонсон М. Харт 2005 г.
Когда читаю все понятно и на основе примеров все коды работают.

Ваш код сработал без ошибок компиляции, как есть. Респект, "снимаю шляпу"
Я наверное "коряво" объяснил, Но я хотел сделать другое:
Переопределить значение переменной lpServiceName - имя запускаемой службы и запустить другую службу (с другим именем) этой же функцией. В пределах одной функции значение этой же переменной, как я понял 2-ой раз задавать нельзя. Можно только сделать ее внешней, но вот как сделать 3 (три) внешних переменных с одним именем, но с разными значениями. Вот в это и уперся.

P.S. опять "коряво" объяснил. Если не сложно попробуйте этим кодом обратиться к 2-м, 3-м службам. Сразу все станет понятно.

Дополню.
Задаем переменной lpServiceName имя "SharedAccess" запускаем,
меняем lpServiceName на "RemoteRegistry" запускаем,
меняем lpServiceName на "SCardSvr" запускаем.

Последний раз редактировалось druidvic; 20.09.2021 в 19:11.
druidvic вне форума Ответить с цитированием
Старый 20.09.2021, 19:25   #7
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Так? (не запускал)
Код:
//подключение к базе служб
s_SC_HANDLE_wrapper schSCManager;
if (!schSCManager.OpenSCManager())
{
    return 0;
}

LPCSTR lpServiceName = "SharedAccess"; // Общий доступ к подключению к Интернету (ICS) отключена

//подключение к службе
s_SC_HANDLE_wrapper schService1;
if (!schService1.OpenService(schSCManager, lpServiceName))
{
    return 0;
}

lpServiceName = "RemoteRegistry";

//подключение к службе
s_SC_HANDLE_wrapper schService2;
if (!schService2.OpenService(schSCManager, lpServiceName))
{
    return 0;
}

lpServiceName = "SCardSvr"; // 5-доступ запрещен

//подключение к службе
s_SC_HANDLE_wrapper schService3;
if (!schService3.OpenService(schSCManager, lpServiceName))
{
    return 0;
}
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 20.09.2021, 21:05   #8
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 960
По умолчанию

druidvic,
Цитата:
Сообщение от BDA Посмотреть сообщение
PCSTR lpServiceName
данная переменная даже не нужна:


Код:
//подключение к базе служб
s_SC_HANDLE_wrapper schSCManager;
if (!schSCManager.OpenSCManager())return 0;

//подключение к службе
s_SC_HANDLE_wrapper schService1;
if (!schService1.OpenService(schSCManager, "SharedAccess"))return 0;

//подключение к службе
s_SC_HANDLE_wrapper schService2;
if (!schService2.OpenService(schSCManager, "RemoteRegistry"))return 0;

//подключение к службе
s_SC_HANDLE_wrapper schService3;
if (!schService3.OpenService(schSCManager, "SCardSvr"))return 0;
Алексей1153 вне форума Ответить с цитированием
Старый 21.09.2021, 12:06   #9
druidvic
Пользователь
 
Регистрация: 05.06.2016
Сообщений: 45
По умолчанию

Спасибо. Очень помогли. Все работает. Буду разбираться.

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
данная переменная даже не нужна:
Спс.
druidvic вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как обратиться к массиву аннет1502 Помощь студентам 6 09.11.2018 08:11
как обратиться к браузеру? gazellea Помощь студентам 0 26.06.2012 20:26
как отключить проверку подлинности на уровне сети для подключений к службам удаленных рабочих столов win 7 СУПЕР ЧАЙНИК Свободное общение 0 07.07.2011 11:57
Как обратиться к ячейке? baddog БД в Delphi 2 30.04.2010 15:43
Диспетчер задач с переходим от процессов к службам и назад Altera Свободное общение 5 07.08.2009 05:59