MesageBox из сервиса

Discussion in 'WASM.BEGINNERS' started by bug1z, Jan 24, 2012.

  1. bug1z

    bug1z New Member

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

    Нагуглил такой код:
    Code (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 Павел

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

    bug1z New Member

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

    _DEN_ DEN

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

    bug1z New Member

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

    valterg Active Member

    Blog Posts:
    0
    UPS...
     
  7. _Juicy

    _Juicy Active Member

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

    bug1z New Member

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

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

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

    Partner Павел

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

    Ursus Member

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

    Partner Павел

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