Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как сервисному приложению отловить вход пользователя в систему. [Win2k, WinXP]


Antoha ©   (2005-09-24 12:40:00) 

Предположим есть работающий сервис. Как известно сервисы запускаются до входа пользователя в систему. Хотелось бы узнать как сервису получить событие входа/выхода пользователя в ОС. Необходим вариант отлова данного события по Windows XP/2000/2003. Всем зарание спасибо за помошь.


GuAV   (2005-09-27 18:14:00) [1]

Polevi ©   (27.09.05 8:09) [4]

Тут видимо дилемма или нехорошая вещь Goto, или нехорошая вещь Exit.


dmitry501   (2005-09-27 09:52:00) [2]

Polevi ©   (27.09.05 8:09) [4]
http://rsdn.ru/forum/Message.aspx?mid=1250236&only=1
:)


Polevi   (2005-09-27 08:09:00) [3]

Goto Final это прикольно :)


Набережных С.   (2005-09-26 19:20:00) [4]

Не понял, при чем тут DllMain? По-моему, в MSDN очень ясно написано. Тебе нужно просто экспортировать несколько функций с требуемой сигнатурой, и их именауказать соответствующих переменных своего ключа в реестре в качестве обработчиков соответствующих событий.

Вот пример размещаемой в либе функции, производящей регистрацию этой библиотеки:

function RegisterHandler(Reg: bool; pRegName: PAnsiChar): HResult; stdcall;
const
 sKey = 'Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify';
 sLogonFunc = 'SNLogonOn';
 sLogoffFunc = 'SNLogonOff';
 sDllName = 'DllName';
 sAsync   = 'Asynchronous';
 sLogon   = 'Logon';
 sLogoff  = 'Logoff';
 sImpers  = 'Impersonate';
var
 Key, MyKey, SubKey: HKEY;
 n: integer;
 sName: string;
Label
 Final;
begin
 MyKey:=0; SubKey:=0;

 Result:=RegOpenKey(HKEY_LOCAL_MACHINE, PChar(sKey), Key);
 if Result <> ERROR_SUCCESS then Exit;

 try
   sName:=ExtractFileName(GetModuleName(HInstance));
   if Reg then
   begin
     Result:=RegOpenKey(Key, pRegName, SubKey);
     if Result = ERROR_SUCCESS then
     begin
       Result:=ERROR_ALREADY_EXISTS;
       GoTo Final;
     end;

     Result:=RegCreateKey(Key, pRegName, MyKey);
     if Result <> ERROR_SUCCESS then Goto Final;

     n:=1;
     Result:=RegSetValueEx(MyKey, PChar(sAsync), 0, REG_DWORD, @n, SizeOf(n));
     if Result <> ERROR_SUCCESS then Goto Final;

     n:=0;
     Result:=RegSetValueEx(MyKey, PChar(sImpers), 0, REG_DWORD, @n, SizeOf(n));
     if Result <> ERROR_SUCCESS then Goto Final;

     Result:=RegSetValueEx(MyKey, PChar(sDllName), 0, REG_EXPAND_SZ,
                                             PChar(sName), Length(sName));
     if Result <> ERROR_SUCCESS then Goto Final;

     Result:=RegSetValueEx(MyKey, PChar(sLogon), 0 , REG_SZ,
                                    PChar(sLogonFunc), Length(sLogonFunc));
     if Result <> ERROR_SUCCESS then Goto Final;

     Result:=RegSetValueEx(MyKey, PChar(sLogoff), 0, REG_SZ,
                                   PChar(sLogoffFunc), Length(sLogoffFunc));
   end
   else
   begin
     Result:=RegDeleteKey(Key, pRegName);
   end;

Final:
 finally
   RegCloseKey(MyKey);
   RegCloseKey(SubKey);
   RegCloseKey(Key);
 end;
end;

Соответственно, имена функций-обработчиков нужно поменять на свои.
А вот такая программа может использовать эту функцию для регистрации библиотеки:

program RegLogonEvntLib;

{$APPTYPE CONSOLE}

uses
 Windows, SysUtils;

type
 TRegisterHandler = function(Reg: bool; pRegName: PAnsiChar): Cardinal; stdcall;

var
 s, RegName, DllName: string;
 LH: THandle;
 F: TRegisterHandler;
 Res: Cardinal;
begin
 if ParamCount < 2 then
 begin
   WriteLn('Example:');
   WriteLn('/REG DllName.dll[ RegistrationName]');
   WriteLn('/UNREG DllName.dll[ RegistrationName]');
   Exit;
 end;

 s:=ParamStr(1);
 DllName:=ParamStr(2);
 if ParamCount < 3 then RegName:=ExtractFileName(ChangeFileExt(DllName, ''))
 else RegName:=ParamStr(3);

 LH:=LoadLibrary(PChar(DllName));
 if LH = 0 then
 begin
   WriteLn(Format('Library "%s" not found', [DllName]));
   Exit;
 end;

 try
   @F:=GetProcAddress(LH, 'RegisterHandler');
   if not Assigned(F) then
   begin
     WriteLn(Format('Function "RegisterHandler" not found in library "%s"', [DllName]));
     Exit;
   end;

   if SameText(s, '/REG') then
   begin
     Res:=F(true, PChar(RegName));
     if Res = ERROR_SUCCESS then
     begin
       WriteLn(Format('The library "%s" is successfully registered', [DllName]));
       Exit;
     end;
   end else

   if SameText(s, '/UNREG') then
   begin
     Res:=F(false, PChar(RegName));
     if Res = ERROR_SUCCESS then
     begin
       WriteLn(Format('The library "%s" is successfully unregistered', [DllName]));
       Exit;
     end;
   end else
   
   begin
     WriteLn(Format('Unknown parameter: "%s"', [s]));
     Exit;
   end;

   if Res = ERROR_ALREADY_EXISTS then
     s:=Format('Key named "%s" already exists', [RegName])
   else
     s:=SysErrorMessage(Res);
   CharToOem(PChar(s), PChar(s));  
   WriteLn('Error!');
   WriteLn(s);
 finally
   FreeLibrary(LH);
 end;
end.


Antoha   (2005-09-26 13:52:00) [5]

Помогло. Огромное пасибо. Тока вот непонятно как на delphi написать winlogon notification package. Потому как Delphi при создании библиотеки использует DLLMain а сервис winlogon хочет LibMain. Как быть ?Ж(


Набережных С.   (2005-09-24 15:07:00) [6]

Go to MSDN: winlogon notification package


Наверх

Титульная страница Поиск, карта сайта Написать письмо