Запуск процесса из сервиса
От: PaNick Россия http://sproger.ru
Дата: 13.07.03 00:01
Оценка:
Такой вот вопрос,
Нужно мне запустиить из сервиса приложения, чтобы знать его ProcessId.
Но вот из сервиса это сделать не получается, то что такое возможно,
понятно из работы Шедулера.

Вопрос как?

Подробности: Запускаю консольное приложение; Сервис интерактивный.
Re: Запуск процесса из сервиса
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 13.07.03 08:18
Оценка:
Здравствуйте, PaNick, Вы писали:

[]

Код в студию.
Re[2]: Запуск процесса из сервиса
От: PaNick Россия http://sproger.ru
Дата: 13.07.03 16:23
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Код в студию.


Вот кусок по вызову процесса:

  GetStartupInfo(SInfo);
  SInfo.wShowWindow:=SW_HIDE;
  CreateProcess('C:\temp\program.exe',nil,nil,nil,true,CREATE_NEW_CONSOLE,nil,nil,SInfo,PInfo);

  CloseHandle(PInfo.hProcess);
  CloseHandle(PInfo.hThread);

  TM_ProcessId:=PInfo.dwProcessId;


При запуске в виде приложения никаких проблем.
Сервис вроде ничего особенного не делает, только иконку в трее с менюшкой.
Использовал стандартный модуль.
Да, все это крутится под XP.
... << RSDN@Home 1.1 beta 1 >>
Re[3]: Запуск процесса из сервиса
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 14.07.03 03:46
Оценка:
Здравствуйте, PaNick, Вы писали:

[]

Ты бы хоть коды ошибок проверял.

Сервис точно интерактивный?
Re[4]: Запуск процесса из сервиса
От: Аноним  
Дата: 14.07.03 06:28
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Здравствуйте, PaNick, Вы писали:


AS>[]


AS>Ты бы хоть коды ошибок проверял.


AS>Сервис точно интерактивный?


Интересно как ты представляешь себе не интерактивный, который в трей добавляет иконку ???
Re[5]: Запуск процесса из сервиса
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 14.07.03 06:29
Оценка:
Здравствуйте, Аноним, Вы писали:

[]

А>Интересно как ты представляешь себе не интерактивный, который в трей добавляет иконку ???


А я не представляю.
Re[3]: Запуск процесса из сервиса
От: EM Великобритания  
Дата: 14.07.03 07:32
Оценка:
Здравствуйте, PaNick, Вы писали:

PN>Здравствуйте, Alexey Shirshov, Вы писали:


AS>>Код в студию.


PN>Вот кусок по вызову процесса:


PN>
PN>  GetStartupInfo(SInfo);
PN>  SInfo.wShowWindow:=SW_HIDE;
PN>  CreateProcess('C:\temp\program.exe',nil,nil,nil,true,CREATE_NEW_CONSOLE,nil,nil,SInfo,PInfo);

PN>  CloseHandle(PInfo.hProcess);
PN>  CloseHandle(PInfo.hThread);

PN>  TM_ProcessId:=PInfo.dwProcessId;
PN>





1. Что возвращает CreateProcess() ?
2. Что возвращает GetLastError() ?
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re: Запуск процесса из сервиса
От: SergH Россия  
Дата: 14.07.03 07:43
Оценка:
Здравствуйте, PaNick, Вы писали:

PN>Такой вот вопрос,

PN>Нужно мне запустиить из сервиса приложения, чтобы знать его ProcessId.

Забавная причина Т.е. само приложение тебе не нужно, что оно делеает не важно, запускаешь только для того, чтобы узнать какой полцчится ProcessId?

PN>Но вот из сервиса это сделать не получается, то что такое возможно,

PN>понятно из работы Шедулера.

PN>Подробности: Запускаю консольное приложение; Сервис интерактивный.


Посмотри http://www.rsdn.ru/Forum/?mid=58862
Автор: VVV
Дата: 29.05.02
Делай что должно, и будь что будет
Re[6]: Запуск процесса из сервиса
От: Аноним  
Дата: 14.07.03 08:47
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Здравствуйте, Аноним, Вы писали:


AS>[]


А>>Интересно как ты представляешь себе не интерактивный, который в трей добавляет иконку ???


AS>А я не представляю.


ТОгда зачем вопросы задаешь такие?
Re[7]: Запуск процесса из сервиса
От: SergH Россия  
Дата: 14.07.03 09:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>ТОгда зачем вопросы задаешь такие?


А зачем ты задаешь такие? Твой первый вопрос можно квалифицировать, как либо желание узнать, как же это возможно, либо как попытку через наводящие вопросы объяснить, что это таки невозможно. А этот вопрос, имхо, только как наезд в мягкой форме. Ну и накой оно тебе?

Кстати, неинтерактивная служба с иконкой — легко. Окрыть нужный десктоп и вперёд. Я не пробовал таким образом делать именно иконку, но окошко, вроде, выводится.
Делай что должно, и будь что будет
Re[2]: Запуск процесса из сервиса
От: PaNick Россия http://sproger.ru
Дата: 14.07.03 18:51
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Здравствуйте, PaNick, Вы писали:


SH>Забавная причина Т.е. само приложение тебе не нужно, что оно делеает не важно, запускаешь только для того, чтобы узнать какой полцчится ProcessId?


Задача сервиса заключается в запуске приложения без логона пользователя; но при этом, чтобы при входе, второй мог управлять приложением.
С консольным же приложением проблема такая, что у него заголовок постоянно меняется, и чтобы его поймать приходится использовать ProcessId.
Позже собираюсь посылать туда клавиши, поэтому без CreateProcess не развернешся.
Для вывода иконки можно использовать другое приложение, главное поймать окно и Ввод-Вывод.
... << RSDN@Home 1.1 beta 1 >>
Re[4]: Запуск процесса из сервиса
От: PaNick Россия http://sproger.ru
Дата: 14.07.03 19:37
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Ты бы хоть коды ошибок проверял.


AS>Сервис точно интерактивный?

Все ОК. Я просто ступил.
При запуске в режиме сервиса нужно указать запуск процесса в OnStart,
А так как я переделал приложение в сервис, то при этом ессно забыл исправить.
Так и висел у меня вызов в OnCreate...

Всем Спасибо за внимание.
... << RSDN@Home 1.1 beta 1 >>
Re[8]: Запуск процесса из сервиса
От: Аноним  
Дата: 15.07.03 06:27
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Здравствуйте, Аноним, Вы писали:


А>>ТОгда зачем вопросы задаешь такие?


SH>А зачем ты задаешь такие? Твой первый вопрос можно квалифицировать, как либо желание узнать, как же это возможно, либо как попытку через наводящие вопросы объяснить, что это таки невозможно. А этот вопрос, имхо, только как наезд в мягкой форме. Ну и накой оно тебе?


SH>Кстати, неинтерактивная служба с иконкой — легко. Окрыть нужный десктоп и вперёд. Я не пробовал таким образом делать именно иконку, но окошко, вроде, выводится.


Извенюсь раз не прав — но опять палце кидалово —

ЛЕГКО — но пока сам не пробовал
Re[9]: Запуск процесса из сервиса
От: SergH Россия  
Дата: 15.07.03 06:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Извенюсь раз не прав — но опять палце кидалово —


А>ЛЕГКО — но пока сам не пробовал


А кудаж мы без пальцев Я просто не люблю писать сервисы, которые имеют хоть какой-то пользовательский интерфейс. Так как весь интерактив очень плохо работает в Terminal Service и Windows XP с Fast User Switching. Предпочитаю писать для них клиентов.

Но раз уж такое дело, сегодня вечером попробую, о результатах доложу.
Делай что должно, и будь что будет
Re[10]: Запуск процесса из сервиса
От: SergH Россия  
Дата: 15.07.03 22:44
Оценка: 31 (3) :)
Здравствуйте, Аноним, Вы писали:

А>>ЛЕГКО — но пока сам не пробовал

SH>Но раз уж такое дело, сегодня вечером попробую, о результатах доложу.

Очень коротко о результатах: работает.

Коротко о результатах:
0. Написал некое UI
примерно такая основная рабочая функция:
void Work::Run()
{
    if (!IsInteractive())
    {
        MessageBox(NULL, TEXT("Not interactive!"), TEXT("TrayService"), MB_OK | MB_SERVICE_NOTIFICATION);

        if (!MakeInteractive())
        {
            MessageBox(NULL, TEXT("Sevice yet is not interactive! It can not work normal."), TEXT("TrayService"), MB_OK | MB_SERVICE_NOTIFICATION);

            StdServFunc::FatalError(NO_ERROR, 0);
            return;
        }
    }

    HWND hwnd = CreateDialog(
                    GetModuleHandle(NULL), 
                    MAKEINTRESOURCE(IDD_DIALOG),
                    NULL,
                    DlgProc);

    ShowWindow(hwnd, SW_SHOWNORMAL);

    for (;;)
    {
        DWORD res = MsgWaitForMultipleObjects(1, &hEndEvent, FALSE, INFINITE, QS_ALLEVENTS);

        if (res == WAIT_OBJECT_0)
        {
            // событие hEndEvent - кончаем работать
            PostMessage(hwnd, WM_COMMAND, IDCANCEL, 0);
        }

        MSG msg;
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT) break;

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    StdServFunc::FatalError(NO_ERROR, 0);
}


и такая диалоговая функция

BOOL CALLBACK Work::DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static int time = 130;
    NOTIFYICONDATA data = {0};

    data.cbSize = sizeof(data);
    data.hWnd   = hwnd;
    data.uID    = 1;
    
    switch (uMsg)
    {
    case WM_INITDIALOG:

        data.uFlags = NIF_ICON | NIF_MESSAGE;
        data.uCallbackMessage = WM_USER + 200;
        data.hIcon = LoadIcon(NULL, IDI_HAND);

        Shell_NotifyIcon(NIM_ADD, &data);
        break;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hwnd, 0);
            Shell_NotifyIcon(NIM_DELETE, &data);
            return TRUE;
        }
        break;

    }

    return FALSE;
}


1. написал функцию IsInteractive. Без проверок на ошибки она выглядит так:
bool IsInteractive()
{
    SC_HANDLE hSCM;
    hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);

    SC_HANDLE hService;    
    hService = OpenService(hSCM, ServiceName, SERVICE_QUERY_CONFIG);
    
    DWORD need = 0;
    QueryServiceConfig(hService, NULL, 0, &need);

    QUERY_SERVICE_CONFIG* pConfig = (QUERY_SERVICE_CONFIG*) malloc(need);

    QueryServiceConfig(hService, pConfig, need, &need);

    CloseServiceHandle(hService);
    CloseServiceHandle(hSCM);

    DWORD type = pConfig->dwServiceType;

    free(pConfig);

    return (type & SERVICE_INTERACTIVE_PROCESS);
}


2. Написал функцию MakeInteractive. Сначала она выглядела так:
bool MakeInteractive()
{
    HWINSTA hWinSta0 = OpenWindowStation(L"WinSta0", FALSE, WINSTA_READSCREEN);

    if (!hWinSta0)
    {
        return false;
    }

    SetProcessWindowStation(hWinSta0);
    CloseWindowStation(hWinSta0);

    HDESK hDefault = OpenDesktop(L"Default", 0, FALSE, DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU);

    if (!hDefault)
    {
        return false;
    }

    SetThreadDesktop(hDefault);

    CloseDesktop(hDefault);
    return true;
}


3. Неинтерактивная служба, но запущенная под LocalSystem пробивается к десктопу на ура.

4. Неинтерактивная служба, запущенная под админом не может открыть оконную станцию.

5. Немного подумав переписал MakeInteractive так:
bool MakeInteractive()
{
    HWINSTA hWinSta0 = OpenWindowStation(L"WinSta0", FALSE, WINSTA_READSCREEN);

    if (!hWinSta0)
    {
        if (GetLastError() != ERROR_ACCESS_DENIED)
        {
            return false;
        }

        // Включаем привелегию SE_TAKE_OWNERSHIP_NAME 
        EnableTakeOwnershipName();

        hWinSta0 = OpenWindowStation(L"WinSta0", FALSE, WRITE_OWNER);

        if (hWinSta0)
        {
            // Делаем текущего пользователя владельцем. Этот этап
            // не критичен, критичен следующий, поэтому здесь
            // ошибки не проверяем.
            SetUserObjectOwner(hWinSta0);
            CloseWindowStation(hWinSta0);
        }

        hWinSta0 = OpenWindowStation(L"WinSta0", FALSE, WRITE_DAC | READ_CONTROL);

        if (!hWinSta0)
        {
            return false;
        }
        
        // Даём текущему пользователю доступ. Я поступил радикально - обнулил DACL :)
        if (!SetUserObjectAccess(hWinSta0))
        {
            CloseWindowStation(hWinSta0);
            return false;
        }

        CloseWindowStation(hWinSta0);

        hWinSta0 = OpenWindowStation(L"WinSta0", FALSE, WINSTA_READSCREEN);

        if (!hWinSta0)
        {
            return false;
        }
    }

    SetProcessWindowStation(hWinSta0);
    CloseWindowStation(hWinSta0);

    HDESK hDefault = OpenDesktop(L"Default", 0, FALSE, DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU);

    if (!hDefault)
    {
        return false;
    }

    SetThreadDesktop(hDefault);

    CloseDesktop(hDefault);
    return true;
}


Код функций
bool EnableTakeOwnershipName();
bool SetUserObjectOwner(HANDLE hUser);
bool SetUserObjectAccess(HANDLE hUser);

не привожу, он довольно прост. Из под админа теперь работает.

Ну что я могу сказать — спасибо тебе, добрый человек! Наконец-то я начал потихоньку трахаться с security...
Делай что должно, и будь что будет
Re[11]: Запуск процесса из сервиса
От: Алексей Россия  
Дата: 06.05.05 17:45
Оценка:
Здравствуйте, SergH, Вы писали:

Overquoting удален модератором
Алексей, будьте вежливы к участникам форума, не цитируйте те части сообщения, которые не нужны. -- Alex Fedotov

SH>Код функций

SH>bool EnableTakeOwnershipName();
SH>bool SetUserObjectOwner(HANDLE hUser);
SH>bool SetUserObjectAccess(HANDLE hUser);

SH>не привожу, он довольно прост. Из под админа теперь работает.


SH>Ну что я могу сказать — спасибо тебе, добрый человек! Наконец-то я начал потихоньку трахаться с security...


А можно все таки получить код функций
SH>bool EnableTakeOwnershipName();
SH>bool SetUserObjectOwner(HANDLE hUser);
SH>bool SetUserObjectAccess(HANDLE hUser);

хотя конечно он и прост, но все же хотелось его посмотреть
простите за ламерские вопросы
Re[12]: Запуск процесса из сервиса
От: SergH Россия  
Дата: 07.05.05 10:14
Оценка:
Здравствуйте, Алексей, Вы писали:

А>А можно все таки получить код функций

SH>>bool EnableTakeOwnershipName();
SH>>bool SetUserObjectOwner(HANDLE hUser);
SH>>bool SetUserObjectAccess(HANDLE hUser);

А>хотя конечно он и прост, но все же хотелось его посмотреть

А>простите за ламерские вопросы

В среду, если не забуду.
Делай что должно, и будь что будет
Re[13]: Запуск процесса из сервиса
От: Алексей Россия  
Дата: 07.05.05 11:07
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Здравствуйте, Алексей, Вы писали:


А>>А можно все таки получить код функций

SH>>>bool EnableTakeOwnershipName();
SH>>>bool SetUserObjectOwner(HANDLE hUser);
SH>>>bool SetUserObjectAccess(HANDLE hUser);

А>>хотя конечно он и прост, но все же хотелось его посмотреть

А>>простите за ламерские вопросы

SH>В среду, если не забуду.

Буду очень признателен!
Re[14]: Запуск процесса из сервиса
От: SergH Россия  
Дата: 12.05.05 11:33
Оценка:
Здравствуйте, Алексей, Вы писали:

А>Буду очень признателен!


Насколько я понял, тебе уже не очень нужен. Тем не менее, тут http://sergh.pisem.net/code/serv_tray.zip
Делай что должно, и будь что будет
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.