Конференция "WinAPI" » Как при выключении Windows выполнить какое-либо приложение?
 
  • p_evghenii (18.12.07 15:50) [0]
    Есть такой код, но он не хочет выполняться при завершении 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;

  • Rouse_ © (18.12.07 16:21) [1]

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

    А зачем ты при завершении хочешь запустить задачу?
  • p_evghenii (18.12.07 16:28) [2]
    Мне надо запустить "не свою" задачу, которая должна отработать именно в момент выхода из Windows.
  • clickmaker © (18.12.07 16:32) [3]

    > [2] p_evghenii   (18.12.07 16:28)

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

    http://support.microsoft.com/kb/198642
  • Riply © (18.12.07 16:34) [4]
    > [2] p_evghenii   (18.12.07 16:28)
    > Мне надо запустить "не свою" задачу,

    TrojanInstaller ?  :)
  • p_evghenii (18.12.07 16:40) [5]
    (4) - Нет, более мирная задача.

    (3) - А без скриптов, только на Дельфе, есть возможность?
  • Rouse_ © (18.12.07 17:01) [6]
    Ну напиши свой вариант 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;


  • Rouse_ © (18.12.07 17:01) [7]
     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.

  • p_evghenii (18.12.07 17:03) [8]
    Да, конечно, не могу сказать, что именно это мне и надо было...
  • Rouse_ © (18.12.07 17:10) [9]
    Тебе надо было выполнить свою задачу. Ты ее не запустишь, поэтому перекрывай логоф и в обработчике логофа делай то, что должен был сделать запускаемый тобой процесс
  • Riply © (18.12.07 17:12) [10]
    > [6] Rouse_ ©   (18.12.07 17:01)
    > Ну напиши свой вариант MSGina в которой перекрой WlxLogoff.
    > Вот тебе простейший вариант...

    А вот простых смертных за такие советы (подмена сис. dll-ек) и тем более код
    казнят на месте без суда и следствия :)
  • Rouse_ © (18.12.07 17:18) [11]

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

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

    Чесное слово не знала, что MSDN поощряет "перекрытие сис. dll-ек". :)
    Я бы такую программу не рискнула бы запустить у себя,
    даже будучи уверенной в чистоте помыслов,
    ибо автор мог просто где-то ошибиться.
  • Плохиш © (18.12.07 17:24) [13]

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

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

    Так мы такие программы и не собираемся у себя запускать ;-)
  • имя (18.12.07 17:47) [14]
    Удалено модератором
  • Rouse_ © (18.12.07 18:02) [15]
    Немного неверно выразился.
    Это нотификационная библиотека, т.е. штатное средство системы. Ни о какой подмене библиотек речи не идет :)
    Воть почитай :)
    http://msdn2.microsoft.com/en-us/library/aa374783.aspx
  • Leonid Troyanovsky © (18.12.07 19:29) [16]

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

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

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

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

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

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

    Именно так. А то и систем не напасешся.
    Мне за глаза и за уши хватает моих эксприрементов,
    последствия которых не всегда предсказуемы :)
 
Конференция "WinAPI" » Как при выключении Windows выполнить какое-либо приложение?
Есть новые Нет новых   [134431   +15][b:0][p:0.006]