Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Windows Service install\unistall tool (console), Выкладываю код. 
V
    Опции темы
sOckets
Дата 23.9.2006, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ЖгуПоПонедельникам
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 24.8.2006
Где: ws2.lib

Репутация: 1
Всего: 2



Привет , вот я выкладываю код инсталлера\унинсталлера сервисов для Windows NT\XP
Просьба заценить чистоту и читабельность кода.
Ну и исправить ошибки типа "Как не стоит писать код" smile
Код

#include <windows.h>
#include <iostream.h>
#define SIZE 500
//----------------------------------------------------- ПЕРЕМЕННЫЕ
    int                i;                                    // нужный INT в работе for\if 
    SC_HANDLE        MSCH;                                // Хэндлы service control 
    SC_HANDLE        MYSH;                                // Хэндл нашего сервиса
    char            MYS_SERVICE_NAME[SIZE];                // Название сервиса
    char            MYS_SERVICE_NAME_FOR_USER[SIZE];    // Название сервиса как будет видеть юзер
    char            PATH_TO_EXE[SIZE];                    // Путь до исполняемого файла запускаемого как сервис
//------------------------------------------------------

void HELP_BANNER_FOR_USER()
{    // Выводит баннер юзеру
    cout << " ########################-> ABOUT <-######################\n";
    cout << " # SerIns - Service Installer for :\n";
    cout << " #    1) Windows \"Longhorn\".\n";
    cout << " #    2) Windows XP.\n";
    cout << " #    3) Windows 2000 Professional.\n";
    cout << " #    4) Windows NT Workstation.\n";
    cout << " #########################################################\n\n";

    cout << " ########################->  USE  <-######################\n";
    cout << " # For install service use flag '-i'\n";
    cout << " # servins.exe  -i \"file.exe\" \"service name\" \"service display name\"\n #\n";
    cout << " # For uninstall service use flag '-u'\n";
    cout << " # servins.exe  -u \"service name\" \n #\n";    
    cout << " # Example:\n #\n";
    cout << " #    servins.exe \"C:\\my folder\\file.exe\" \"MyService\" \"My Proxy Server\"\n";
    cout << " #########################################################\n";    
}

void COPY_CHAR(char* FROM,char* TO)
{    // копирование с одного массива в другой
    for (i = 0;i <= strlen(FROM)-1; i++)
    {
        TO[i] = FROM[i];
    }
}

void GET_PROGRAM_ARGV_I(char* TO_EXE,char* SV_NAME,char* DS_NAME)
{    // Получаем аргументы от юзера для установки
    if (strlen(TO_EXE) < SIZE && strlen(SV_NAME) < SIZE  && strlen(DS_NAME) < SIZE)
    {
        // Получаем путь до файла
        COPY_CHAR(TO_EXE,PATH_TO_EXE);

        // Получаем имя сервиса
        COPY_CHAR(SV_NAME,MYS_SERVICE_NAME);

        // Заменяем пробелы на "_"
        for (i = 0;i <= strlen(MYS_SERVICE_NAME)-1; i++)
        {
            if (MYS_SERVICE_NAME[i]==' ') MYS_SERVICE_NAME[i] = '_';
        }

        // Получаем название сервиса
        COPY_CHAR(DS_NAME,MYS_SERVICE_NAME_FOR_USER);
    }
}

void GET_PROGRAM_ARGV_U(char* SV_NAME)
{    // Получаем аргументы от юзера для удаления сервиса
    if (strlen(SV_NAME) < 500)
    {
        for (i = 0;i <= strlen(SV_NAME)-1; i++)
        {
            MYS_SERVICE_NAME[i] = SV_NAME[i];
        }
    }
}

int main(int argc,char* argv[])
{
    //----------------------------------------------------- START
    // Проверяем ввёл ли пользователь нормальное количество параметров
    if (argc < 2)
    {
        HELP_BANNER_FOR_USER();
        return 1;
    }
    
    // Проверяем ключ
    i = strcmp(argv[1],"-i");
    if (i == 0)
    {
        // Тут юзер выбрал создать сервис , поэтому мы должны проверить сколько он ввёл параметров , если он ввёл мало
        // то мы ему сообщим об этом
        // Проверяем ввёл ли пользователь нормальное количество параметров
        if (argc != 5)
        {
            HELP_BANNER_FOR_USER();
            return 1;
        }
        
        // Получаем параментры с командной строки и передаём их функции
        GET_PROGRAM_ARGV_I(argv[2],argv[3],argv[4]);
        
        // Стучимся в менеджер сервисов
        MSCH = OpenSCManager(NULL,NULL,0x0002);
        if (MSCH == NULL)
        {
            cout << "Error service name";
            return 1;
        }

        // Создаём сервис
        MYSH = CreateService(MSCH,MYS_SERVICE_NAME,MYS_SERVICE_NAME_FOR_USER,SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,PATH_TO_EXE,NULL,NULL,NULL,NULL,NULL);
        if (MYSH == NULL) 
        {
            cout << "Error Create of service";
            return FALSE;
        } else {
            CloseServiceHandle(MYSH); 
            cout << "Service : " << MYS_SERVICE_NAME << " installed";
            return TRUE;
        }
        return 0;
    }
    i = strcmp(argv[1],"-u");
    if (i == 0)
    {
        if (argc != 3)
        {
            cout << "<" << argv[0] << ">" << " -u \"ServiceName\"";
            return 1;
        }
        GET_PROGRAM_ARGV_U(argv[2]);
        // Стучимся в менеджер сервисов
        MSCH = OpenSCManager(NULL,NULL,0xF003F);
        if (MSCH == NULL)
        {
            cout << "Error service name";
            return 1;
        }
        // Открываем сервис
        MYSH = OpenService(MSCH,MYS_SERVICE_NAME,0xF003F);
        if (MYSH == NULL)
        {
            cout << "Error open service";
            return 1;
        }
        i = DeleteService(MYSH);
        if (i != 0)
        {
            cout << "Service removed";
            return 0;
        }
        return 0;
    }
//----------------------------------------------------- END
    return 0;
}


Скоро напишу не консольную версию

Это сообщение отредактировал(а) sOckets - 23.9.2006, 23:05


--------------------
Я Будущий сотрудник Google Inc. Юзаем Google Code Search для поиска исходников. Юзаем GMail как почту.
PM   Вверх
registered
Дата 23.9.2006, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 30.8.2006

Репутация: нет
Всего: 1



а что Вы вообще хотите - указать ошибки - или показать рабочий код ?
PM MAIL   Вверх
sOckets
Дата 23.9.2006, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ЖгуПоПонедельникам
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 24.8.2006
Где: ws2.lib

Репутация: 1
Всего: 2



Код рабочий , просто я хочю чтоб "гуру" указали мне на ошибки типо "Как не стоит писать код" =\


--------------------
Я Будущий сотрудник Google Inc. Юзаем Google Code Search для поиска исходников. Юзаем GMail как почту.
PM   Вверх
registered
Дата 24.9.2006, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 30.8.2006

Репутация: нет
Всего: 1



Цитата(sOckets @  23.9.2006,  23:47 Найти цитируемый пост)
Код рабочий , просто я хочю чтоб "гуру" указали мне на ошибки типо "Как не стоит писать код" =\ 


я конечно не гуру smile, но на первый взгляд

1. 
Цитата(sOckets @  23.9.2006,  22:43 Найти цитируемый пост)
#define SIZE 500

Код

const SIZE = 500;


2. 
Цитата(sOckets @  23.9.2006,  22:43 Найти цитируемый пост)
//----------------------------------------------------- ПЕРЕМЕННЫЕ
    int                i;                                    // нужный INT в работе for\if 
    SC_HANDLE        MSCH;                                // Хэндлы service control 
    SC_HANDLE        MYSH;                                // Хэндл нашего сервиса
    char            MYS_SERVICE_NAME[SIZE];                // Название сервиса
    char            MYS_SERVICE_NAME_FOR_USER[SIZE];    // Название сервиса как будет видеть юзер
    char            PATH_TO_EXE[SIZE];                    // Путь до исполняемого файла запускаемого как сервис
//------------------------------------------------------


глобально не есть хорошо

3. 
Цитата(sOckets @  23.9.2006,  22:43 Найти цитируемый пост)
void COPY_CHAR(char* FROM,char* TO)
{    // копирование с одного массива в другой
    for (i = 0;i <= strlen(FROM)-1; i++)
    {
        TO[i] = FROM[i];
    }
}


для этого есть strcpy, strcpy_s - но в идеале нужно конечно std::string

4. используй smart-поинтеры


ну.... далее нет смысла - лучше задавай вопросы smile

Это сообщение отредактировал(а) registered - 24.9.2006, 00:04
PM MAIL   Вверх
sOckets
Дата 24.9.2006, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ЖгуПоПонедельникам
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 24.8.2006
Где: ws2.lib

Репутация: 1
Всего: 2



Цитата
для этого есть strcpy, strcpy_s - но в идеале нужно конечно std::string


А чем эта функция не потходит ? на счёт strcpy я в курсе smile просто 

Цитата
const SIZE = 500;


Почему ?

На будущее , пожалуйста обьясняйте почему вы так думаете.


--------------------
Я Будущий сотрудник Google Inc. Юзаем Google Code Search для поиска исходников. Юзаем GMail как почту.
PM   Вверх
vinter
Дата 24.9.2006, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата

const SIZE = 500;    

Почему ?

потому что дефайны считаются плохим тоном..


--------------------
Мой блог
PM MAIL WWW   Вверх
Kuvaldis
Дата 24.9.2006, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



Цитата

const SIZE = 500;    

Почему ?

Плохо тем, что, например, в #define A B, идет механическая (!) замена A на В а тексте програмы, без проверки на соотвествие типов. => возможны неприятные ошибки


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
bel_nikita
Дата 24.9.2006, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Цитата(vinter @ 24.9.2006,  08:10)
потому что дефайны считаются плохим тоном..

хто сказал?

Добавлено @ 10:41 
Цитата(registered @ 23.9.2006,  23:04)
4. используй smart-поинтеры

зачем тут смарт-поинтеры применять?


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
sOckets
Дата 24.9.2006, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ЖгуПоПонедельникам
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 24.8.2006
Где: ws2.lib

Репутация: 1
Всего: 2



Цитата
4. используй smart-поинтеры


Понятие я имею что такое smart-поинтеры smile


--------------------
Я Будущий сотрудник Google Inc. Юзаем Google Code Search для поиска исходников. Юзаем GMail как почту.
PM   Вверх
vinter
Дата 24.9.2006, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



в книгах пишут " по возможности избегайте, define'ов "..


--------------------
Мой блог
PM MAIL WWW   Вверх
registered
Дата 24.9.2006, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 30.8.2006

Репутация: нет
Всего: 1



вообще тут напрашивается класс smile

например что-то вроде 
Код

/*-----------------------------------------------------------------------*/
class SCHandle {
private :
    boost::shared_ptr<void> m_handle;

public :
    SCHandle (SC_HANDLE handle = NULL)
        : m_handle (handle, CloseServiceHandle) {;}
    ~SCHandle() {;}

    operator SC_HANDLE () const { return (SC_HANDLE)m_handle.get(); }
};
/*-----------------------------------------------------------------------*/
class ServiceManager  {
private :
    std::string m_name;
    SCHandle m_hService;
    SERVICE_STATUS m_status;

    unsigned GetStatus (void) const;
    unsigned GetUserStatus (void) const;

public :
    explicit ServiceManager (const std::string& serviceName);
    ~ServiceManager() {;}

    bool IsExist    (void) const;
    bool IsRunning  (void) const;
    bool IsStopped  (void) const;
    bool IsPaused   (void) const;

    bool Start      (void) const;
    bool Stop       (void);
    bool Pause      (void);
    bool Continue   (void);

    bool Install    (const std::string& displayName, unsigned startType,
                     const char* services = NULL, const char* group = NULL);
    bool Uninstall  (void);

};


Код

ServiceManager::ServiceManager (const std::string& serviceName)
    : m_name (serviceName), m_hService (NULL)
{
    ZeroMemory (&m_status, sizeof (SERVICE_STATUS));

    SCHandle hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT);
    if (!hSCManager)
    {
        DebugMessage ("ServiceManager::ServiceManager (OpenSCManager)");
        throw std::exception("Ошибка открытия SCManager");
    }

    m_hService = OpenService (hSCManager, m_name.c_str(), SERVICE_ALL_ACCESS);
    if (!m_hService)
    {
        DebugMessage ("ServiceManager::ServiceManager (OpenService)");
    }

}
/* -------------------------------------------------------------------------- */
bool ServiceManager::IsExist (void) const
{
    return (m_hService != NULL);
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::IsRunning (void) const
{
    return (GetStatus() == SERVICE_RUNNING);
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::IsStopped (void) const
{
    return (GetStatus() == SERVICE_STOPPED);
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::IsPaused (void) const
{
    return (GetStatus() == SERVICE_PAUSED);
}
/* -------------------------------------------------------------------------- */
unsigned ServiceManager::GetStatus (void) const
{
    SERVICE_STATUS status = {0};
    QueryServiceStatus (m_hService, &status);
    return status.dwCurrentState;
}
/* -------------------------------------------------------------------------- */
unsigned ServiceManager::GetUserStatus (void) const
{
    SERVICE_STATUS status = {0};
    QueryServiceStatus (m_hService, &status);
    return status.dwServiceSpecificExitCode;
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::Start (void) const
{
    if (!m_hService) return false;
    if (!StartService (m_hService, 0, NULL))
    {
        DebugMessage ("ServiceManager::Start (StartService)");
        return false;
    }

    return true;
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::Stop (void)
{
    if (!m_hService) return false;
    if (!ControlService(m_hService, SERVICE_CONTROL_STOP, &m_status))
    {
        DebugMessage ("ServiceManager::Stop (ControlService)");
        return false;
    }
    return true;
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::Pause (void)
{
    if (!m_hService) return false;
    if (!ControlService (m_hService, SERVICE_CONTROL_PAUSE, &m_status))
    {
        if (GetLastError () != ERROR_SERVICE_NOT_ACTIVE)
        {
            DebugMessage ("ServiceManager::Pause (ControlService)");
            return false;
        }            
    }

    return true;
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::Continue (void)
{
    if (!m_hService) return false;
    if (!ControlService(m_hService, SERVICE_CONTROL_CONTINUE, &m_status))
    {
        DebugMessage ("ServiceManager::Continue (ControlService)");
        return false;
    }

    return true;
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::Install (const std::string& displayName, unsigned startType,
                              const char* services, const char* group)
{
    if (m_hService) return true;

    SCHandle hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    if (!hSCManager)
    {
        DebugMessage ("ServiceManager::Install (OpenSCManager)");
        return false;
    }

    m_hService = OpenService (hSCManager, m_name.c_str(), SERVICE_ALL_ACCESS);
    if (m_hService) return true;

    m_hService = CreateService (
        hSCManager, m_name.c_str(),
        displayName.c_str(), SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
        startType, SERVICE_ERROR_NORMAL, GetProcessPath (),
        group, NULL, services, NULL, NULL);

    if (!m_hService)
    {
        DebugMessage ("ServiceManager::Install (CreateService)");
        return false;
    }
    return true;
}
/* -------------------------------------------------------------------------- */
bool ServiceManager::Uninstall (void)
{
    if (!m_hService) return true;
    if (m_status.dwCurrentState != SERVICE_STOPPED)
    {
        if (!ControlService (m_hService, SERVICE_CONTROL_STOP, &m_status))
        {
            DebugMessage ("ServiceManager::Uninstall (ControlService)");
            return false;
        }
    }

    if (!DeleteService (m_hService))
    {
        DebugMessage ("ServiceManager::Uninstall (DeleteService)");
        return false;
    }
    return true;
}
/* -------------------------------------------------------------------------- */



Это сообщение отредактировал(а) registered - 24.9.2006, 10:57
PM MAIL   Вверх
sOckets
Дата 24.9.2006, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


ЖгуПоПонедельникам
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 24.8.2006
Где: ws2.lib

Репутация: 1
Всего: 2



Цитата
вообще тут напрашивается класс 

Ну программа мелочная , поэтому я думаю класс не стоит вообще юзать для таких мелочей  ,пойми если новичём будет читать тот код что у тебя и у меня ...я (как новичёк) больше пойму то что сам накалякал smile


--------------------
Я Будущий сотрудник Google Inc. Юзаем Google Code Search для поиска исходников. Юзаем GMail как почту.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0572 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.