Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сервис с иконкой в трее, Проблема управления сервисом 
:(
    Опции темы
Разгильдяй
Дата 25.4.2008, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Есть сервис. К нему надо приделать управление. Добавил вывод иконки в трей, она выводится, меняет состояние при изменении состояния службы. Но не выводит меню на иконке. В режиме приложения все работает... 

Вот вырезки кода...

Код

...
    MyServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; // интерактивный
...
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
    switch(Opcode) 
    {
    case SERVICE_CONTROL_STOP:
    case SERVICE_CONTROL_SHUTDOWN:
.....
        return;
    case SERVICE_CONTROL_CONTINUE:
        MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
        break;
.....
    };

    SetServiceStatus (MyServiceStatusHandle,  &MyServiceStatus);
    SetState();
}

HMENU GetMenu()
{
    HMENU hRes = NULL;
    mKey hKey;
    HKEY hMainKey = HKEY_LOCAL_MACHINE;
    switch (state)
    {
    case S_RUNNING:
        hRes = LoadMenu(hInstance, MAKEINTRESOURCE(1));
        HMENU hSub = GetSubMenu(hRes, 0);
...
        break;
    case S_STOPPED:
        hRes = LoadMenu(hInstance, MAKEINTRESOURCE(2));
        HMENU hSub = GetSubMenu(hRes, 0);
...
        break;
    }
    return hRes;
}

void SetState()
{
    int newState = state;
    if (scService || isService ){
        SC_HANDLE tmpSM;
        SC_HANDLE tmpSC = scService;
        if ( !scService )
        {
            tmpSM = scService ? scService : OpenSCManager(h.host, NULL, GENERIC_READ | GENERIC_EXECUTE);
            tmpSC = OpenService(tmpSM, SERVICE_NAME, GENERIC_EXECUTE | GENERIC_READ);
        }
        SERVICE_STATUS ss;
        if (QueryServiceStatus(tmpSC, &ss)){
            switch (ss.dwCurrentState)
            {
            case SERVICE_STOPPED:
                newState = S_STOPPED;
                break;
            case SERVICE_START_PENDING:
                newState = S_START_PENDING;
                break;
            case SERVICE_STOP_PENDING:
                newState = S_STOP_PENDING;
                break;
            case SERVICE_RUNNING:
                newState = S_RUNNING;
                break;
            }
        }
        if ( !scService )
        {
            CloseServiceHandle(tmpSC);
            CloseServiceHandle(tmpSM);
        }
    }else{
        newState = runState;
    }
    if (wantError && (newState == S_RUNNING)) wantError = FALSE;
    state = newState;
    if (_Shell_NotifyIcon){  // блок отрабатывает, проверял!!!
        ShowWindow(hWnd, SW_HIDE);
        NOTIFYICONDATA nf;
        nf.cbSize = sizeof(nf);
        nf.hWnd   = hWnd;
        nf.uID    = TRAYICON_ID;
        nf.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
        nf.uCallbackMessage = WM_USER;
        nf.hIcon = (state == S_RUNNING) ? IconRun : IconStop;
        char *s = StateText();
        lstrcpyn(nf.szTip, s, sizeof(nf.szTip));
        _Shell_NotifyIcon(NIM_MODIFY, &nf);
    }
    if (!fastTimer && ((state == S_START_PENDING) || (state == S_STOP_PENDING))){
        KillTimer(hWnd, 1);
        SetTimer(hWnd, 1, 100, NULL);
        fastTimer = TRUE;
    }
}

LRESULT CALLBACK WndProc(HWND hwnd,    UINT  uMsg,    WPARAM  wParam,    LPARAM  lParam)
{
    switch (uMsg)
    {
.....
    case WM_USER: 
        {
            UINT uID       = (UINT)wParam;
            UINT uMouseMsg = (UINT)lParam;
            if (uID != TRAYICON_ID) break;
            switch (uMouseMsg)
            {
            case WM_LBUTTONDBLCLK:
                if (hMenu){
                    DestroyMenu(hMenu);
                    hMenu = NULL;
                }
                hMenu = GetMenu();
                if (hMenu)
                    PostMessage(hwnd, WM_COMMAND, state ? ID_HOME : ID_START, 0);
                break;
            case WM_RBUTTONUP:
                {
                    if (hMenu){
                        DestroyMenu(hMenu);
                        hMenu = NULL;
                    }
                    hMenu = GetMenu();
                    if (hMenu){
                        SetActiveWindow(hwnd);
                        SetForegroundWindow(hwnd);
                        POINT pt;
                        GetCursorPos(&pt);
                        TrackPopupMenu(GetSubMenu(hMenu, 0), TPM_RIGHTBUTTON, pt.x,    pt.y,    0, hwnd, NULL);
                        PostMessage(hwnd, WM_USER, 0, 0);
                    }
                    break;
                }
            }
            return TRUE;
....
        }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

void InitWindow()
{
    WNDCLASS wc;
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = 0;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = NULL;
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = WND_CLASS;
    if (!RegisterClass(&wc)) return;

    hWnd = CreateWindow(WND_CLASS, WND_CLASS, WS_CHILD,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, GetDesktopWindow(), NULL, hInstance, NULL);
    if (hWnd == NULL) return;

         InitIcons();
        if (_Shell_NotifyIcon){
            ShowWindow(hWnd, SW_HIDE);
            NOTIFYICONDATA nf;
            nf.cbSize = sizeof(nf);
            nf.hWnd   = hWnd;
            nf.uID    = TRAYICON_ID;
            nf.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
            nf.uCallbackMessage = WM_USER;
            nf.hIcon = IconStop;
            char *s = StateText();
            lstrcpyn(nf.szTip, s, sizeof(nf.szTip));
            _Shell_NotifyIcon(NIM_ADD, &nf);
        }else{
            SetWindowText(hWnd, StateText());
            ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
        }
}

int WINAPI WinMain(HINSTANCE  _hInstance, HINSTANCE, LPSTR cmdLine, int)
{
    hInstance = _hInstance;
    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
...
    SERVICE_TABLE_ENTRY srvTbl[2];
    srvTbl[0].lpServiceName = SERVICE_NAME;
    srvTbl[0].lpServiceProc = ServiceMain;
    srvTbl[1].lpServiceName = NULL;
    srvTbl[1].lpServiceProc = NULL;
...
    SC_HANDLE scManager = NULL;
    HINSTANCE hShell = LoadLibrary("SHELL32.DLL");
    if (hShell) *((FARPROC*)(&_Shell_NotifyIcon)) = GetProcAddress(hShell, "Shell_NotifyIconA");
    HINSTANCE hUser  = LoadLibrary("USER32.DLL");
    if (hUser) *((FARPROC*)(&_SetMenuDefaultItem)) = GetProcAddress(hUser, "SetMenuDefaultItem");
    InitWindow();
...
    if (checkService){
        isService = TRUE;
        if (StartServiceCtrlDispatcher(srvTbl)) return TRUE;
        int err = GetLastError() & 0xFFFF;
        if ((err != ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) &&
            (err != ERROR_CALL_NOT_IMPLEMENTED)) return TRUE;
        isService = FALSE;
    }
    if (asService){
        scManager = OpenSCManager(h.host, NULL, GENERIC_READ | GENERIC_EXECUTE);
        if (scManager == NULL){
            if (GetLastError() == ERROR_ACCESS_DENIED){
                CloseWindow(hWnd);
                return FALSE;
            }
        }
    }
    if (scManager)
        scService = OpenService(scManager, SERVICE_NAME, GENERIC_EXECUTE | GENERIC_READ);
    
......
    return FALSE;
}



Скрытое окно создается, иконка меняется, меню не вызывается...  smile 
Может кто с этим сталкивался?
Подскажите.

Это сообщение отредактировал(а) Разгильдяй - 25.4.2008, 11:24
PM MAIL   Вверх
Pulse69
Дата 25.4.2008, 15:17 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 28.4.2006
Где: Хабаровск

Репутация: 8
Всего: 10



Плохая идея - создавать элементы GUI прямо из сервиса. Лучше сделать дополнительное приложение, которое будет запрашивать у службы статус и, соответственно, каким-нибудь образом ей управлять.
Для того, чтобы GUI-элементы работали корректно, служба должна быть интерактивной (В свойствах службы на вкладке "Вход в систему" поставить переключатель на "С системной учётной записью" и поставить флажок "Разрешить взаимодействие с рабочим столом". Возможно, это не сделано, и возникают ошибки.

--------------------
Ctrl+Alt+Reset 
PM MAIL   Вверх
Rififi
Дата 25.4.2008, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Pulse69 @  25.4.2008,  15:17 Найти цитируемый пост)
"Разрешить взаимодействие с рабочим столом"

В Висте этот способ уже отключили, так шта...
PM MAIL   Вверх
Разгильдяй
Дата 28.4.2008, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Pulse69 @  25.4.2008,  15:17 Найти цитируемый пост)
Для того, чтобы GUI-элементы работали корректно, служба должна быть интерактивной (В свойствах службы на вкладке "Вход в систему" поставить переключатель на "С системной учётной записью" и поставить флажок "Разрешить взаимодействие с рабочим столом". Возможно, это не сделано, и возникают ошибки.


Все выполнено

Код

    MyServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; // интерактивный


Эта строка все делает....

Цитата(Rififi @  25.4.2008,  18:07 Найти цитируемый пост)
В Висте этот способ уже отключили, так шта... 


Специально проверил в Висте, ничего не отключили, в настройках все оК!!!!
И системная запись, и интерактивность присутствуют....

Это сообщение отредактировал(а) Разгильдяй - 28.4.2008, 16:34
PM MAIL   Вверх
Rififi
Дата 29.4.2008, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Interactive Services
Impact of Session 0 Isolation on Services and Drivers in Windows Vista

в Висте для обеспечения совместимости с кривыми сервисами написан специальный костыль.
если интересно, гуглить "Interactive Services Detection"

PM MAIL   Вверх
Разгильдяй
Дата 14.5.2008, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Сорри за задержку...
По поводу Висты я читал.
Но у меня и под XP popupmenu не работает.
Иконка появляется, в зависимости от состояния службы меняется, описание появляется, а меню по правой кнопке не вызывается.
Но ведь аналогично работает Windows Audio [AudioSrv]. По левой окошко регулятора громкости, по правой меню... Значит можно...
Но КАК????

Это сообщение отредактировал(а) Разгильдяй - 14.5.2008, 15:51
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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