Интерактивный сервис
От: MadMaks Украина  
Дата: 06.11.01 13:53
Оценка:
Возникла проблема с написанием интерактивного сервиса, а именно — в переключении desktop'а.
Не удается переключиться на "WinSta0\\Default" десктоп, когда на машине произвели login, а затем logout. Причем, если машина загрузилась (сервис стартует автоматически) и еще не логинились, то десктоп переключается нормально. Но что самое обидное, так это то, что SwitchDesktop возвращает 0 (завершилась неуспешно), а GetLastError почему-то тоже 0 (типа нет ошибки).
В чем может быть проблема и почему она возникает после логина на машине?
MadMaks
Come out and play...
Re: Интерактивный сервис
От: Alex Fedotov США  
Дата: 06.11.01 15:30
Оценка:
Здравствуйте MadMaks, Вы писали:

MM>Возникла проблема с написанием интерактивного сервиса, а именно — в переключении desktop'а.

MM>Не удается переключиться на "WinSta0\\Default" десктоп, когда на машине произвели login, а затем logout. Причем, если машина загрузилась (сервис стартует автоматически) и еще не логинились, то десктоп переключается нормально. Но что самое обидное, так это то, что SwitchDesktop возвращает 0 (завершилась неуспешно), а GetLastError почему-то тоже 0 (типа нет ошибки).
MM>В чем может быть проблема и почему она возникает после логина на машине?

1. Какой изначально десктоп у сервиса?
2. Почему надо постоянно переключаться, а не с самого начала зарегистрировать сервис как интерактивный?
-- Alex Fedotov
Re[2]: Интерактивный сервис
От: MadMaks Украина  
Дата: 06.11.01 16:23
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>1. Какой изначально десктоп у сервиса?

"WinSta0\\Default"

AF>2. Почему надо постоянно переключаться, а не с самого начала зарегистрировать сервис как интерактивный?

Сервис зарегестрирован как интерактивный. А переключаться нужно для запроса информации у пользователя. Понимаю, что несколько абсурдно выглядит, но так поставлена задача.
То есть, висит приглашение нажать Ctrl+Alt+Del. По сети сервис принимает задание вывести форму и прозвести ввод данных. Он должет переключиться на "Default" десктоп, чтобы вывести окно и запросить данные у пользователя (либо предоставить информацию пользователю). Далее он восстанавливает десктоп ("Winlogon").
MadMaks
Come out and play...
Re[3]: Интерактивный сервис
От: Alex Fedotov США  
Дата: 07.11.01 09:00
Оценка:
Здравствуйте MadMaks, Вы писали:

MM>Здравствуйте Alex Fedotov, Вы писали:


AF>>1. Какой изначально десктоп у сервиса?

MM>"WinSta0\\Default"

AF>>2. Почему надо постоянно переключаться, а не с самого начала зарегистрировать сервис как интерактивный?

MM>Сервис зарегестрирован как интерактивный. А переключаться нужно для запроса информации у пользователя. Понимаю, что несколько абсурдно выглядит, но так поставлена задача.
MM>То есть, висит приглашение нажать Ctrl+Alt+Del. По сети сервис принимает задание вывести форму и прозвести ввод данных. Он должет переключиться на "Default" десктоп, чтобы вывести окно и запросить данные у пользователя (либо предоставить информацию пользователю). Далее он восстанавливает десктоп ("Winlogon").

То есть процесс всегда остается ассоциированным с winsta0\default, он только переключает активный десктоп.
Хм, а можно взглянуть на код переключения туда и обратно? А если создать свой собственный декстоп, и переключаться на него, проблема остается?
-- Alex Fedotov
Re[4]: Интерактивный сервис
От: MadMaks Украина  
Дата: 07.11.01 09:20
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>То есть процесс всегда остается ассоциированным с winsta0\default, он только переключает активный десктоп.

AF>Хм, а можно взглянуть на код переключения туда и обратно? А если создать свой собственный декстоп, и переключаться на него, проблема остается?
Код самый простой:

HDESK hInputDesktop;
HDESK hDesktop;

hInputDesktop = OpenInputDesktop(0,FALSE,MAXIMUM_ALLOWED);

if (hInputDesktop != NULL)
{
hDesktop = OpenDesktop("WinSta0\\Default",0,FALSE,MAXIMUM_ALLOWED);

if (hDesktop != NULL)
{
if (SwitchDesktop(hDesktop))
{
Sleep(1000);
SwitchDesktop(hInputDesktop);
}

CloseDesktop(hDesktop);
}

CloseDesktop(hInputDesktop);
}

Я этот кусок вырезал из тестового сервиса и несколько изменил, но идею я думаю передал. Могу выслать тестовый пример сервиса.

Относительно создания своего десктопа — проблема остается.
MadMaks
Come out and play...
Re[5]: Интерактивный сервис
От: ole  
Дата: 08.11.01 13:39
Оценка:
Вот цитата из MSDN:

If you decide to include a user interface and common controls within your service, make sure that the service loads and initializes the Comctl32.dll file only when it needs to show the window containing the common controls. The service should close the window and completely unload the common controls library before the user logs off. The sample code in the "More Information" section of this article demonstrates how to dynamically load and initialize the Comctl32.dll file.


А это код примера:

DWORD dwGuiThreadId = 0;

int
UserMessageBox(
RPC_BINDING_HANDLE h,
LPSTR lpszWindowStation,
LPSTR lpszDesktop,
LPSTR lpszText,
LPSTR lpszTitle,
UINT fuStyle)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
int result;

// Ensure connection to service window station and desktop, and
// save their handles.

GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);

// Impersonate the client and connect to the User's
// window station and desktop.

RpcImpersonateClient(h);
hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
RpcRevertToSelf();
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
RpcRevertToSelf();
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);

// Display message box.

dwGuiThreadId = dwThreadId;
result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
dwGuiThreadId = 0;

// Restore window station and desktop.

SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);

return result;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.