MesageBox из сервиса

Тема в разделе "WASM.BEGINNERS", создана пользователем bug1z, 24 янв 2012.

  1. bug1z

    bug1z New Member

    Публикаций:
    0
    Вечер добрый.
    Подскажите пожалуйста, как ввести меседжбокс из сервиса?

    Нагуглил такой код:
    Код (Text):
    1. DWORD dwGuiThreadId = 0;
    2. int UserMessageBox(RPC_BINDING_HANDLE h, LPSTR lpszWindowStation, LPSTR lpszDesktop, LPSTR lpszText, LPSTR lpszTitle, UINT fuStyle)
    3. {
    4.     DWORD dwThreadId;
    5.     HWINSTA hwinstaSave;
    6.     HDESK hdeskSave;
    7.     HWINSTA hwinstaUser;
    8.     HDESK hdeskUser;
    9.     int result;
    10.  
    11. // Ensure connection to service window station and desktop, and
    12. // save their handles.
    13.  
    14.     GetDesktopWindow();
    15.     hwinstaSave = GetProcessWindowStation();
    16.     dwThreadId = GetCurrentThreadId();
    17.     hdeskSave = GetThreadDesktop(dwThreadId);
    18.  
    19. // Impersonate the client and connect to the User's
    20. // window station and desktop.
    21.  
    22.     RpcImpersonateClient(h);
    23.     hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
    24.     if (hwinstaUser == NULL)
    25.     {
    26.         RpcRevertToSelf();
    27.         return 0;
    28.     }
    29.  
    30.     SetProcessWindowStation(hwinstaUser);
    31.     hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
    32.     RpcRevertToSelf();
    33.     if (hdeskUser == NULL)
    34.     {
    35.         SetProcessWindowStation(hwinstaSave);
    36.         CloseWindowStation(hwinstaUser);
    37.         return 0;
    38.     }
    39.     SetThreadDesktop(hdeskUser);
    40.  
    41. // Display message box.
    42.  
    43.     dwGuiThreadId = dwThreadId;
    44.     result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
    45.     dwGuiThreadId = 0;
    46.  
    47. // Restore window station and desktop.
    48.  
    49.     SetThreadDesktop(hdeskSave);
    50.     SetProcessWindowStation(hwinstaSave);
    51.     CloseDesktop(hdeskUser);
    52.     CloseWindowStation(hwinstaUser);
    53.  
    54.     return result;
    55. }
    Но какие параметры ему передавать - не знаю.

    Заранее благодарен.
     
  2. Partner

    Partner Павел

    Публикаций:
    0
    Начиная с Vista сервис запускается в отдельной сессии с отдельным десктопом. Так что твой MessageBox никто не увидит.
     
  3. bug1z

    bug1z New Member

    Публикаций:
    0
    А как вывести меседжбокс на десктоп залогиненого пользователя тогда?
     
  4. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    bug1z
    Вроде ж все делают отдельное приложение для показывания юзеру гуя, которое общается с сервисом?
     
  5. bug1z

    bug1z New Member

    Публикаций:
    0
    То есть из сервиса вызывать CreateProcessAsUser() с правами обычного пользователя и в потоке этого процесса выполнять мой код?
     
  6. valterg

    valterg Active Member

    Публикаций:
    0
  7. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Есть такой вариант
    Не знаю, какого года оно и под что может работать...
     
  8. bug1z

    bug1z New Member

    Публикаций:
    0
    Не подойдет, поскольку там может быть не только месдж бокс. нужен именно десктоп залогиненого пользователя.

    А как создавать процесс из под сервиса так, чтобы он располагал десктопом залогиненого пользователя?

    Ипользовал CreateProcessAsUser(), но все равно на десктопе пользователя ничего не выводилось.
     
  9. Partner

    Partner Павел

    Публикаций:
    0
    Получить токен залогиненого пользователя и CreateProcessAsUser()
     
  10. Ursus

    Ursus Member

    Публикаций:
    0
    Не надо извращений. Что, например, будет делать сервис, если залогиненных юзеров несколько? Или ни одного?
    Нормальные люди делают еще одно обычное десктопное приложение, которое сидит на десктопе юзера (неважно, загружается ли оно через HKCU\...\Run, или юзер запускает его самостоятельно) и ждет, пока сервис не отправит ему команду вывести мессаджбокс.
     
  11. Partner

    Partner Павел

    Публикаций:
    0
    WTSQueryUserToken отдаст токен того юзера, который в данный момент поключен к физической консоли(клаве и дисплею), а не просто залогинен.