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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Активировать окно приложения (запуск из сервиса) 
V
    Опции темы
InvalidProperty
Дата 13.11.2009, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 356
Регистрация: 31.10.2007
Где: Россия, Казань

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



Привет,

возникла проблема:

имеется сервис, который в ответ на запрос клиента, должен запустить процесс от активного текущего пользователя (CreateProcessAsUser). Окно созданного процесса должно стать активным. В XP все работает отлично, т.к. первое созданное окно становится активным. В Viste наблюдается другое поведение: окно создается, но не становится активным. Что можно сделать, чтобы активировать окно?

Вот код со стороны сервиса, который создает процесс:

Код

 STARTUPINFOA        StartupInfo;

 memset(&StartupInfo, 0, sizeof(StartupInfo));
 StartupInfo.cb = sizeof(StartupInfo);
 StartupInfo.lpDesktop = "winsta0\\default";
 StartupInfo.dwFlags = STARTF_RUNFULLSCREEN | STARTF_USESHOWWINDOW;
 StartupInfo.wShowWindow = SW_SHOW;

 HANDLE hUserTokenDup;
 DWORD dSessId = WTSGetActiveConsoleSessionId();
 if(dSessId == 0xFFFFFFFF)
  throw CharException("%s", "no session is currently attached to the console");

 if(!WTSQueryUserToken(dSessId, &hUserTokenDup))
  throw CharException("%s", "can not query user token");

 CreateProcessAsUser(hUserTokenDup, "C:\\test.exe", 0, 0, 0, 0, 
    CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, 0, "C:\\",
    &StartupInfo, &_process_information);
 if(!_process_information.hProcess)
 {
  CloseHandle(hUserTokenDup);
  throw CharException("%s", "cannot create process");
 }

 CloseHandle(hUserTokenDup);


test.exe может быть любым приложением, в рамках которого создается окно

Это сообщение отредактировал(а) InvalidProperty - 13.11.2009, 16:36


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
BEOWOLF
Дата 13.11.2009, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Можно через BringWindowToTop вывести...
Найти окно через FindWindow, если имя класса или заголовок - не известны, то тогда через EnumWindows пролистать главные окна и определить через GetWindowThreadProcessId нужное.
PM MAIL   Вверх
InvalidProperty
Дата 13.11.2009, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 356
Регистрация: 31.10.2007
Где: Россия, Казань

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



ключевое словосочетание: сервис под вистой. Под вистой findwindow для  сервиса не работает.
Если вызывать BringWindowToTop из test.exe, то окно также не будет активным.
Вот код, который я пробовал для test.exe. Ни одна из функций в потоке не делает активным окно:
Код

#include <windows.h>
#include <stdio.h>
#include "resource.h"

HWND    g_hwnd;

DWORD WINAPI ThreadProc(
  LPVOID lpParameter
)
{
 Sleep(1000);
 //ShowWindow(g_hwnd, SW_SHOWNORMAL);
 //SwitchToThisWindow(g_hwnd, FALSE);
 //SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
 SetForegroundWindow(g_hwnd);
 BringWindowToTop(g_hwnd);
 if(!SetWindowPos(g_hwnd, HWND_TOP, 100, 100, 150, 150, /*SWP_ASYNCWINDOWPOS | */SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW))
 {
  char s[234];
  itoa(GetLastError(), s, 10);
  MessageBox(g_hwnd, s, "asdf", MB_OK);
 }
 Beep(500, 1000);

 return 0;
}


BOOL CALLBACK DialogFun(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
 switch(msg)
 {
  case WM_INITDIALOG:
  {
   g_hwnd = hwnd;
   CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);   
  }
   break;

  case WM_CLOSE:
  {
   EndDialog(hwnd, 0);
  }
   break;
 }

 return FALSE;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogFun);

 return 0;
}



--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
InvalidProperty
Дата 20.11.2009, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 356
Регистрация: 31.10.2007
Где: Россия, Казань

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



Товарищи, вопрос решен.

Решение следующее:

Сервис создает процесс как описано в первом посте, после чего только что созданный процесс производит следующие операции:
Код

   DWORD pr = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
   AttachThreadInput(pr, GetCurrentThreadId(), TRUE);
   SetForegroundWindow(g_hwnd);
   SetFocus(g_hwnd);
   AttachThreadInput(pr, GetCurrentThreadId(), FALSE);

, где g_hwnd - Handle главного окна созданного процесса
т.о. главное окно только что созданного процесса становится активным.

Примечание: процесс, чье окно сейчас активно должен быть запущен с правами меньшими, либо равными правам создаваемого процесса.

Это сообщение отредактировал(а) InvalidProperty - 20.11.2009, 18:59


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
InvalidProperty
Дата 25.11.2009, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 356
Регистрация: 31.10.2007
Где: Россия, Казань

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



что странно, если текущим активным окном, является окно командной строки, то переключение активного окна не происходит, а AttachThreadInput завершается с ошибкой 87 :( . Это очень печалит, но меня пока устраивает вариант и без этого, так что, если кто-нибудь найдет решение для окна командной строки, буду очень признателен


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
dream2work
Дата 9.12.2009, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



StartupInfo.lpDesktop = null;
тода окно создастся на рабоем столе юзера чей токен указан в CreateProcessAsUser
PM MAIL   Вверх
InvalidProperty
Дата 14.12.2009, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 356
Регистрация: 31.10.2007
Где: Россия, Казань

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



Цитата

By default, CreateProcessAsUser creates the new process on a noninteractive window station with a desktop that is not visible and cannot receive user input. To enable user interaction with the new process, you must specify the name of the default interactive window station and desktop, "winsta0\default", in the lpDesktop member of the STARTUPINFO structure. In addition, before calling CreateProcessAsUser, you must change the discretionary access control list (DACL) of both the default interactive window station and the default desktop. The DACLs for the window station and desktop must grant access to the user or the logon session represented by the hToken 


это MSDN. Откуда у тебя информация о нулевом десктопе?


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

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


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

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


 




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


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

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