Как запустить оконное приложение из службы, чтобы оно было видно пользователю? - C#

Узнай цену своей работы

Формулировка задачи:

Добрый день. Подобная тема обсуждалась в интернете много раз, но я так и не смог найти на нее внятного ответа. Если в кратце то вопрос звучит так: как запустить оконное приложение из службы, чтобы оно было видно пользователю? Если подробно. Есть приложение и служба. Приложение win32, сторонний разработчик, должно быть запущено постоянно, но из-за забывчивости пользователя запущено иногда. Данное приложение позволяет взаимодействовать с собой посредством COM Есть служба, приложение Java, с помощью коннектора (коннектор стороннего разработчика) соединяется с приложением и забирает инфу. Но служба, даже запущенная от имени того же пользователя (кстати доменного), не хочет видеть приложение. Как выход было принято решение запустить эту службу как обычный процесс. Но этот процесс опять же должен быть запущен постоянно, и если пользователь хоть иногда запускает первое приложение, то про существование службы он как будто не знает и объяснять бесполезно. Как выход было принято решение написать службу, которая поддерживает работоспособность обоих приложений, перезапуская их по таймеру если они не были запущены или были случайно закрыты. Вот тут и началась проблема. Самым простым вариантом для реализации службы мне показался C#. С++ уже давно забыт и память течет как из фонтана, а на Java жонглироваь пользователями не так то удобно. В общем чего я только не пробовал: ShellExecute, System.Diagnostics.Process.Start, CreateProcessAsUser, CreateProcessWithLogonW с различными наборами параметров... В любом случае процесс стартует, стартует от нужного мне пользователя, но окна приложения пользователю не видно. Видимо процесс стартует в другой сессии этого же пользователя, ну или что-то близкое. Я долго копал и наткнулся на CreateProcessWithTokenW. Может быть эта функция делает то, что мне нужно? Если да, то как достать для нее нужные параметры? Я пытался, но потонул =) Если нет, то какие еще варианты?

Решение задачи: «Как запустить оконное приложение из службы, чтобы оно было видно пользователю?»

textual
Листинг программы
bool
_stdcall
RunCalcInUserSession(DWORD SessionId)
{
    HANDLE   hToken    = NULL;
    VOID   * pEnvBlock = NULL;
 
    if (FALSE == WTSQueryUserToken(SessionId, &hToken))
    {
        goto ErrorExit;
    }
 
    if (FALSE == CreateEnvironmentBlock(&pEnvBlock, hToken, FALSE))
    {
        goto ErrorExit;
    }
 
    STARTUPINFOW StartInfo;
    GetStartupInfoW(&StartInfo);
    StartInfo.lpDesktop = L"WinSta0\\Default";
    PROCESS_INFORMATION ProcInfo;
    wchar_t CmdLine[] = {L"calc.exe"};
 
    if (FALSE == CreateProcessAsUserW(
        hToken,
        NULL, // Application name.
        CmdLine,
        NULL, // Process security attributes.
        NULL, // Thread security attributes.
        FALSE, // Inherit handles or not.
        NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT,
        pEnvBlock,
        NULL, // Current directory.
        &StartInfo,
        &ProcInfo
        ))
    {
        goto ErrorExit;
    }
 
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
    DestroyEnvironmentBlock(pEnvBlock);
    CloseHandle(hToken);
 
    return true;
 
ErrorExit:
        
    if (NULL != pEnvBlock)
    {
        DestroyEnvironmentBlock(pEnvBlock);
    }
 
    if (NULL != hToken)
    {
        CloseHandle(hToken);
    }
 
    return false;
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4 из 5
Похожие ответы