есть сервис, он создает оконный класс. дальше надо найти это окно.
выставляю SystemAccount, Interact with Desktop — все работает.
но!!! (как всегда, инче б и вопроса небыло) имеем второй сервис,
который не имеет возможности стартовать под SystemAccount.
вопрос такой: как из этого сервиса найти окно первого?
Здравствуйте, Bachin, Вы писали:
B>вопрос такой: как из этого сервиса найти окно первого?
Способа 2.
1) OpenDesktop/EnumDesktopWindows/CloseDesktop
2) SetThreadDesktop/FindWindow/SetThreadDesktop
Здравствуйте, vasketsov, Вы писали:
V>Здравствуйте, Bachin, Вы писали:
B>>вопрос такой: как из этого сервиса найти окно первого? V>Способа 2. V>1) OpenDesktop/EnumDesktopWindows/CloseDesktop V>2) SetThreadDesktop/FindWindow/SetThreadDesktop
ок. буду копать.
если не трудно — сразу еще один вопрос:
первый сервис мой. (может в нем свой десктоп создать?)
из второго сервиса — моя DLL.
интересует быстродействие работы функций в этой DLL.
Здравствуйте, Bachin, Вы писали:
B>первый сервис мой. (может в нем свой десктоп создать?)
Зачем?
B>интересует быстродействие работы функций в этой DLL.
Это пока что не зависит от того, на каком десктопе на выполняется, ибо ничего про нее не известно.
B>по какому пути лучше пойти?
Вот не поверите, писал и знал, что будет этот вопрос.
Путь 2 — более простой, в нем выбор окна осуществляется самой системой.
Путь 1 — предпочтительнее во всех отношениях, он и более масштабируемый (так как не меняется Desktop у сервиса) и имеется возможность гибко перебрать все окна и самому понять, то это окно или нет. Я бы выбрал его.
Здравствуйте, vasketsov, Вы писали:
V>Здравствуйте, Bachin, Вы писали:
B>>первый сервис мой. (может в нем свой десктоп создать?) V>Зачем?
B>>интересует быстродействие работы функций в этой DLL. V>Это пока что не зависит от того, на каком десктопе на выполняется, ибо ничего про нее не известно.
B>>по какому пути лучше пойти? V>Вот не поверите, писал и знал, что будет этот вопрос. V>Путь 2 — более простой, в нем выбор окна осуществляется самой системой. V>Путь 1 — предпочтительнее во всех отношениях, он и более масштабируемый (так как не меняется Desktop у сервиса) и имеется возможность гибко перебрать все окна и самому понять, то это окно или нет. Я бы выбрал его.
К сожалению вариант оказался не работоспособным ;(
если в сервисе не стоит Interact with Desktop, то максиму что удалось получить — это имя десктопа.
вот код:
type
TFindWindowStru = record
WindowHandle: HWND;
WindowClassName: PChar;
end;
PFindWindowStru = ^TFindWindowStru;
function __EnumWindowsProc(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
var
fClassName: array [0..$FF] of Char;
fClassNameLen: Integer;
begin
fClassNameLen := GetClassName(hwnd, @fClassName, SizeOf(fClassName));
fClassName[fClassNameLen] := #0;
OutputDebugString(@fClassName);
Result := not CompareMem(@fClassName, PFindWindowStru(lParam).WindowClassName, fClassNameLen);
if not Result then
PFindWindowStru(lParam).WindowHandle := hwnd;
end;
function __EnumDesktopProc(lpszDesktop: LPTSTR; lParam: LPARAM): Boolean; stdcall;
var
fDesktopHandle: HDESK;
begin
fDesktopHandle := OpenDesktop(lpszDesktop, 0, Boolean(0), DESKTOP_READOBJECTS);
if (fDesktopHandle = 0) then
OutputDebugString(PChar(SysErrorMessage(GetLastError)))
else
try
OutputDebugString(lpszDesktop);
OutputDebugString('------------------------------');
Result := EnumDesktopWindows(fDesktopHandle, @__EnumWindowsProc, lParam);
OutputDebugString('------------------------------');
finally
CloseDesktop(fDesktopHandle);
end;
end;
function __FindWindow(ClassName: PChar): THandle;
var
fWinStationHandle: HWINSTA;
fFindDindowData: TFindWindowStru;
begin
Result := 0;
fWinStationHandle := GetProcessWindowStation;
if (fWinStationHandle = 0) then
begin
OutputDebugString(PChar(SysErrorMessage(GetLastError)));
Exit;
end;
fFindDindowData.WindowClassName := ClassName;
fFindDindowData.WindowHandle := 0;
EnumDesktops(fWinStationHandle, @__EnumDesktopProc, Integer(@fFindDindowData));
Result := fFindDindowData.WindowHandle;
end;
Здравствуйте, Bachin, Вы писали:
B>К сожалению вариант оказался не работоспособным ;(
Я сам это делал, и на C и на Delphi.
Вы просто забыли, что есть несколько WindowStations, которые также надо перечислить.
А забыли потому, что Help поверхностно смотрите.
Итак, EnumWindowStations, далее для каждой OpenWindowStation, EnumDesktops и CloseWindowStation, внутри EnumDesktops — то что надо по десктопу, а именно — OpenDesktop/EnumDesktopWindows/CloseDesktop.
Здравствуйте, vasketsov, Вы писали:
V>Итак, EnumWindowStations, далее для каждой OpenWindowStation, EnumDesktops и CloseWindowStation, внутри EnumDesktops — то что надо по десктопу, а именно — OpenDesktop/EnumDesktopWindows/CloseDesktop.
да уж... виноват... вчера инет отваливался — небыло возможности глянуть... а запомнил с середины
осталась одна проблемка: не могу вычислить минимально требуемый набор
ACCESS_MASK для OpenWindowStation и OpenDesktop. и соответственно привилегии требуемые для пользователя под которым будет запущен этот сервис.