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

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

Как при выключении Windows выполнить какое-либо приложение?


p_evghenii ©   (2007-12-18 15:50:00) 

Есть такой код, но он не хочет выполняться при завершении Windows, т.к. она пишет "Сбой при инициализации приложения". Есть ли возможность победить?


procedure TForm1.IsWindowsShutDown(var Msg : TWMQueryEndSession);
var
 cmdline: string;
 si:STARTUPINFO;
 pi:PROCESS_INFORMATION;
begin
   inherited;
   ZeroMemory(@si,sizeof(si));
   si.cb:=SizeOf(si);
   si.dwFlags:=STARTF_USESHOWWINDOW;
   si.wShowWindow:=SW_HIDE;
   cmdline:='notepad.exe';
   if CreateProcess( nil, // No module name (use command line).
           PChar(cmdline),  // Command line.
           nil,             // Process handle not inheritable.
           nil,             // Thread handle not inheritable.
           False,           // Set handle inheritance to FALSE.
           0,               // No creation flags.
           nil,             // Use parent's environment block.
           nil,             // Use parent's starting directory.
           si,              // Pointer to STARTUPINFO structure.
           pi )             // Pointer to PROCESS_INFORMATION structure.
   then begin
     SetPriorityClass(pi.hProcess, HIGH_PRIORITY_CLASS);
     WaitForSingleObject(pi.hProcess, INFINITE );
     CloseHandle(pi.hProcess);
     CloseHandle( pi.hThread );
   end;
    Msg.Result := 1;
End;


Riply   (2007-12-18 19:49:00) [1]

> [15] Rouse_ ©   (18.12.07 18:02)
> Это нотификационная библиотека, т.е. штатное средство системы.
> Ни о какой подмене библиотек речи не идет :)
> Воть почитай :)

Спасибо.
Но Саш, я и не сомневалась, что ты сможешь не только
написать "нечто", но и доказать потом, что написанное тобой совсем безобидно,
ибо базируется только на штатных и документированных средствах :)

> [16] Leonid Troyanovsky ©   (18.12.07 19:29)
> Узрев пьяного (маньяка, милиционера &etc) - отойди :)

Именно так. А то и систем не напасешся.
Мне за глаза и за уши хватает моих эксприрементов,
последствия которых не всегда предсказуемы :)


Leonid Troyanovsky   (2007-12-18 19:29:00) [2]


> Riply ©   (18.12.07 17:22) [12]

> даже будучи уверенной в чистоте помыслов

Узрев пьяного (маньяка, милиционера &etc) - отойди :)

--
Regards, LVT.


Rouse_   (2007-12-18 18:02:00) [3]

Немного неверно выразился.
Это нотификационная библиотека, т.е. штатное средство системы. Ни о какой подмене библиотек речи не идет :)
Воть почитай :)
http://msdn2.microsoft.com/en-us/library/aa374783.aspx


  (2007-12-18 17:47:00) [4]

Удалено модератором


Плохиш   (2007-12-18 17:24:00) [5]


> Riply ©   (18.12.07 17:22) [12]

> Я бы такую программу не рискнула бы запустить у себя,

Так мы такие программы и не собираемся у себя запускать ;-)


Riply   (2007-12-18 17:22:00) [6]

> [11] Rouse_ ©   (18.12.07 17:18)
> Тезка, это вообщето документированная фича :)
> Ты думаешь тут есть что-то отсутствющее в MSDN? :)

Чесное слово не знала, что MSDN поощряет "перекрытие сис. dll-ек". :)
Я бы такую программу не рискнула бы запустить у себя,
даже будучи уверенной в чистоте помыслов,
ибо автор мог просто где-то ошибиться.


Rouse_   (2007-12-18 17:18:00) [7]


> А вот простых смертных за такие советы (подмена сис. dll-
> ек) и тем более код
> казнят на месте без суда и следствия :)

Тезка, это вообщето документированная фича :)
Ты думаешь тут есть что-то отсутствющее в MSDN? :)


Riply   (2007-12-18 17:12:00) [8]

> [6] Rouse_ ©   (18.12.07 17:01)
> Ну напиши свой вариант MSGina в которой перекрой WlxLogoff.
> Вот тебе простейший вариант...

А вот простых смертных за такие советы (подмена сис. dll-ек) и тем более код
казнят на месте без суда и следствия :)


Rouse_   (2007-12-18 17:10:00) [9]

Тебе надо было выполнить свою задачу. Ты ее не запустишь, поэтому перекрывай логоф и в обработчике логофа делай то, что должен был сделать запускаемый тобой процесс


p_evghenii   (2007-12-18 17:03:00) [10]

Да, конечно, не могу сказать, что именно это мне и надо было...


Rouse_   (2007-12-18 17:01:00) [11]

 function WlxNegotiate(dwWinlogonVersion: DWORD;
   var pdwDllVersion: DWORD): BOOL; stdcall; external MSGina;
 function WlxInitialize(lpWinsta: LPWSTR; hWlx: HANDLE; pvReserved: PVOID;
   pWinlogonFunctions: PVOID; var pWlxContext: PVOID): BOOL; stdcall;
   external MSGina;
 procedure WlxDisplaySASNotice(pWlxContext: PVOID); stdcall;
   external MSGina;
 function WlxLoggedOutSAS(pWlxContext: PVOID; dwSasType: DWORD;
   var pAuthenticationId: LUID; var pLogonSid: SID; var pdwOptions: DWORD;
   var phToken: HANDLE; var pNprNotifyInfo: WLX_MPR_NOTIFY_INFO;
   var pProfile: PVOID): Integer; stdcall;
   external MSGina;
 function WlxActivateUserShell(pWlxContext: PVOID; pszDesktopName: PWSTR;
   pszMprLogonScript: PWSTR; pEnvironment: PVOID): BOOL; stdcall;
   external MSGina;
 function WlxLoggedOnSAS(pWlxContext: PVOID; dwSasType: DWORD; pReserved: PVOID): Integer; stdcall;
   external MSGina;
 procedure WlxDisplayLockedNotice(pWlxContext: PVOID); stdcall;
   external MSGina;
 function WlxWkstaLockedSAS(pWlxContext: PVOID; dwSasType: DWORD): Integer; stdcall;
   external MSGina;
 function WlxIsLockOk(pWlxContext: PVOID): BOOL; stdcall;
   external MSGina;
 function WlxIsLogoffOk(pWlxContext: PVOID): BOOL; stdcall;
   external MSGina;
 procedure WlxLogoff(pWlxContext: PVOID); stdcall;
   external MSGina;
 procedure WlxShutdown(pWlxContext: PVOID; ShutdownType: DWORD); stdcall;
   external MSGina;

function PMWlxNegotiate(dwWinlogonVersion: DWORD;
 var pdwDllVersion: DWORD): BOOL; stdcall;
begin
 pdwDllVersion := WLX_VERSION_1_0;
 Result := WlxNegotiate(dwWinlogonVersion, pdwDllVersion);
end;

function PMWlxInitialize(lpWinsta: LPWSTR; hWlx: HANDLE; pvReserved: PVOID;
 pWinlogonFunctions: PVOID; var pWlxContext: PVOID): BOOL; stdcall;
var
 pgContext: PGINA_CONTEXT;
begin
 Result := False;
 pgContext := PGINA_CONTEXT(LocalAlloc(LMEM_FIXED or
   LMEM_ZEROINIT, SizeOf(GINA_CONTEXT)));
 if Assigned(pgContext) then
 begin
   pgContext^.hWlx := hWlx;
   pgContext^.station := lpWinsta;
   pgContext^.pWlxFuncs := pWinlogonFunctions;
   Result := WlxInitialize(lpWinsta, hWlx, pvReserved,
     pWinlogonFunctions, pgContext^.pGinaContext);
   pWlxContext := pgContext;
 end;
end;

procedure PMWlxDisplaySASNotice(pWlxContext: PVOID); stdcall;
begin
 WlxDisplaySASNotice(PGINA_CONTEXT(pWlxContext)^.pGinaContext);
end;

function PMWlxLoggedOutSAS(pWlxContext: PVOID; dwSasType: DWORD;
 var pAuthenticationId: LUID; var pLogonSid: SID; var pdwOptions: DWORD;
 var phToken: HANDLE; var pNprNotifyInfo: WLX_MPR_NOTIFY_INFO;
 var pProfile: PVOID): Integer; stdcall;
begin
 Result := WlxLoggedOutSAS(PGINA_CONTEXT(pWlxContext)^.pGinaContext,
   dwSasType, pAuthenticationId, pLogonSid,
   pdwOptions, phToken, pNprNotifyInfo, pProfile);
end;

function PMWlxActivateUserShell(pWlxContext: PVOID; pszDesktopName: PWSTR;
 pszMprLogonScript: PWSTR; pEnvironment: PVOID): BOOL; stdcall;
begin
 Result := WlxActivateUserShell(PGINA_CONTEXT(pWlxContext)^.pGinaContext,
   pszDesktopName, pszMprLogonScript, pEnvironment);
end;

function PMWlxLoggedOnSAS(pWlxContext: PVOID; dwSasType: DWORD;
 pReserved: PVOID): Integer; stdcall;
begin
 Result := WlxLoggedOnSAS(PGINA_CONTEXT(pWlxContext)^.pGinaContext,
   dwSasType, pReserved);
end;

procedure PMWlxDisplayLockedNotice(pWlxContext: PVOID); stdcall;
begin
 WlxDisplayLockedNotice(PGINA_CONTEXT(pWlxContext)^.pGinaContext);
end;

function PMWlxWkstaLockedSAS(pWlxContext: PVOID; dwSasType: DWORD): Integer; stdcall;
begin
 Result := WlxWkstaLockedSAS(PGINA_CONTEXT(pWlxContext)^.pGinaContext,
   dwSasType);
end;

function PMWlxIsLockOk(pWlxContext: PVOID): BOOL; stdcall;
begin
 Result := WlxIsLockOk(PGINA_CONTEXT(pWlxContext)^.pGinaContext);
end;

function PMWlxIsLogoffOk(pWlxContext: PVOID): BOOL; stdcall;
begin
 Result := WlxIsLogoffOk(PGINA_CONTEXT(pWlxContext)^.pGinaContext);
end;

procedure PMWlxLogoff(pWlxContext: PVOID); stdcall;
begin
 WlxLogoff(PGINA_CONTEXT(pWlxContext)^.pGinaContext);
end;

procedure PMWlxShutdown(pWlxContext: PVOID; ShutdownType: DWORD); stdcall;
begin
 WlxShutdown(PGINA_CONTEXT(pWlxContext)^.pGinaContext, ShutdownType);
end;

exports
 PMWlxNegotiate name 'WlxNegotiate',
 PMWlxInitialize name 'WlxInitialize ',
 PMWlxActivateUserShell name 'WlxActivateUserShell',
 PMWlxDisplayLockedNotice name 'WlxDisplayLockedNotice',
 PMWlxDisplaySASNotice name 'WlxDisplaySASNotice',
 PMWlxIsLockOk name 'WlxIsLockOk',
 PMWlxIsLogoffOk name 'WlxIsLogoffOk',
 PMWlxLoggedOnSAS name'WlxLoggedOnSAS',
 PMWlxLoggedOutSAS name 'WlxLoggedOutSAS',
 PMWlxLogoff name 'WlxLogoff',
 PMWlxShutdown name 'WlxShutdown',
 PMWlxWkstaLockedSAS name 'WlxWkstaLockedSAS';

begin
end.


Rouse_   (2007-12-18 17:01:00) [12]

Ну напиши свой вариант MSGina в которой перекрой WlxLogoff.
Вот тебе простейший вариант...

library CustomGinaLibrarry;

{$R *.res}

uses
 Windows;

const
 WLX_VERSION_1_0 = ($00010000);
 MSGina = 'MSGina.dll';
 ANYSIZE_ARRAY = 1;  

type
 HANDLE = THandle;
 PVOID = Pointer;
 PWSTR = LPWSTR;
 LONG = ULONG;

 DLGTEMPLATE = packed record
   style: DWORD;
   dwExtendedStyle: DWORD;
   cdit: WORD;
   x: short;
   y: short;
   cx: short;
   cy: short;
 end;
 TDlgTemplate = DLGTEMPLATE;
 LPCDLGTEMPLATE = ^DLGTEMPLATE;

 PWLX_MPR_NOTIFY_INFO = ^WLX_MPR_NOTIFY_INFO;
 _WLX_MPR_NOTIFY_INFO = record
   pszUserName: PWSTR;
   pszDomain: PWSTR;
   pszPassword: PWSTR;
   pszOldPassword: PWSTR;
 end;
 WLX_MPR_NOTIFY_INFO = _WLX_MPR_NOTIFY_INFO;

 PWLX_DESKTOP = ^WLX_DESKTOP;
 _WLX_DESKTOP = record
   Size: DWORD;
   Flags: DWORD;
   hDesktop: HDESK;
   pszDesktopName: PWSTR;
 end;
 WLX_DESKTOP = _WLX_DESKTOP;
 TWlxDesktop = WLX_DESKTOP;
 PWlxDesktop = PWLX_DESKTOP;

 DLGPROC = function (hwndDlg: HWND; wMsg: UINT; wParam: WPARAM; lParam: LPARAM): INT_PTR; stdcall;

 PWLX_USE_CTRL_ALT_DEL = procedure (hWlx: HANDLE); stdcall;
 PWLX_SET_CONTEXT_POINTER = procedure (hWlx: HANDLE; pWlxContext: PVOID); stdcall;
 PWLX_SAS_NOTIFY = procedure (hWlx: HANDLE; dwSasType: DWORD); stdcall;
 PWLX_SET_TIMEOUT = function (hWlx: HANDLE; Timeout: DWORD): BOOL; stdcall;
 PWLX_ASSIGN_SHELL_PROTECTION = function (hWlx, hToken, hProcess, hThread: HANDLE): Integer; stdcall;
 PWLX_MESSAGE_BOX = function (hWlx: HANDLE; hwndOwner: HWND; lpszText,
   lpszTitle: LPWSTR; fuStyle: UINT): Integer; stdcall;
 PWLX_DIALOG_BOX = function (hWlx, hInst: HANDLE; lpszTemplate: LPWSTR;
   hwndOwner: HWND; dlgprc: DLGPROC): Integer; stdcall;
 PWLX_DIALOG_BOX_INDIRECT = function (hWlx, hInst: HANDLE;
   hDialogTemplate: LPCDLGTEMPLATE; hwndOwner: HWND; dlgprc: DLGPROC): Integer; stdcall;
 PWLX_DIALOG_BOX_PARAM = function (hWlx, hInst: HANDLE; lpszTemplate: LPWSTR;
   hwndOwner: HWND; dlgprc: DLGPROC; dwInitParam: LPARAM): Integer; stdcall;
 PWLX_DIALOG_BOX_INDIRECT_PARAM = function (hWlx, hInst: HANDLE;
   hDialogTemplate: LPCDLGTEMPLATE; hwndOwner: HWND; dlgprc: DLGPROC;
   dwInitParam: LPARAM): Integer; stdcall;
 PWLX_SWITCH_DESKTOP_TO_USER = function (hWlx: HANDLE): Integer; stdcall;
 PWLX_SWITCH_DESKTOP_TO_WINLOGON = function (hWlx: HANDLE): Integer; stdcall;
 PWLX_CHANGE_PASSWORD_NOTIFY = function (hWlx: HANDLE;
   var pMprInfo: WLX_MPR_NOTIFY_INFO; dwChangeInfo: DWORD): Integer; stdcall;

 PWLX_DISPATCH_VERSION_1_0 = ^WLX_DISPATCH_VERSION_1_0;
 _WLX_DISPATCH_VERSION_1_0 = record
   WlxUseCtrlAltDel: PWLX_USE_CTRL_ALT_DEL;
   WlxSetContextPointer: PWLX_SET_CONTEXT_POINTER;
   WlxSasNotify: PWLX_SAS_NOTIFY;
   WlxSetTimeout: PWLX_SET_TIMEOUT;
   WlxAssignShellProtection: PWLX_ASSIGN_SHELL_PROTECTION;
   WlxMessageBox: PWLX_MESSAGE_BOX;
   WlxDialogBox: PWLX_DIALOG_BOX;
   WlxDialogBoxParam: PWLX_DIALOG_BOX_PARAM;
   WlxDialogBoxIndirect: PWLX_DIALOG_BOX_INDIRECT;
   WlxDialogBoxIndirectParam: PWLX_DIALOG_BOX_INDIRECT_PARAM;
   WlxSwitchDesktopToUser: PWLX_SWITCH_DESKTOP_TO_USER;
   WlxSwitchDesktopToWinlogon: PWLX_SWITCH_DESKTOP_TO_WINLOGON;
   WlxChangePasswordNotify: PWLX_CHANGE_PASSWORD_NOTIFY;
 end;
 WLX_DISPATCH_VERSION_1_0 = _WLX_DISPATCH_VERSION_1_0;
 TWlxDispatchVersion1_0 = WLX_DISPATCH_VERSION_1_0;
 PWlxDispatchVersion1_0 = PWLX_DISPATCH_VERSION_1_0;

 PGINA_CONTEXT = ^GINA_CONTEXT;
 GINA_CONTEXT = record
   hWlx: HANDLE;
   station: LPWSTR;
   pWlxFuncs: PWLX_DISPATCH_VERSION_1_0;
   pGinaContext: Pointer;
 end;

 PLuid = ^LUID;
 _LUID = record
   LowPart: DWORD;
   HighPart: LONG;
 end;
 {$EXTERNALSYM _LUID}
 LUID = _LUID;
 {$EXTERNALSYM LUID}
 TLuid = LUID;

  PSid = ^SID;
 _SID = record
   Revision: Byte;
   SubAuthorityCount: Byte;
   IdentifierAuthority: SID_IDENTIFIER_AUTHORITY;
   SubAuthority: array [0..ANYSIZE_ARRAY - 1] of DWORD;
 end;
 {$EXTERNALSYM _SID}
 SID = _SID;
 {$EXTERNALSYM SID}
 PPSID = ^PSID;
 {$NODEFINE PPSID}
 TSid = SID;


p_evghenii   (2007-12-18 16:40:00) [13]

(4) - Нет, более мирная задача.

(3) - А без скриптов, только на Дельфе, есть возможность?


Riply   (2007-12-18 16:34:00) [14]

> [2] p_evghenii   (18.12.07 16:28)
> Мне надо запустить "не свою" задачу,

TrojanInstaller ?  :)


clickmaker   (2007-12-18 16:32:00) [15]


> [2] p_evghenii   (18.12.07 16:28)

на этот случае есть такая фишка, как logoff-script

http://support.microsoft.com/kb/198642


p_evghenii   (2007-12-18 16:28:00) [16]

Мне надо запустить "не свою" задачу, которая должна отработать именно в момент выхода из Windows.


Rouse_   (2007-12-18 16:21:00) [17]


> но он не хочет выполняться при завершении Windows

А зачем ты при завершении хочешь запустить задачу?


Наверх

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