Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Programmeren

[Delphi] Windows afsluiten

RowdyVanDerVeen
7 antwoorden
  • Hoe doe je dat? Ik heb wel iets gevonden voor Windows 98… Maar die werkt weer niet in Windows 2000/XP en omgekeerd. Weet iemand hoe dit moet??

    Alvast bedankt,

    Johan
  • Dit kan eenvoudig met de Windows API (gebruik ExitWindowsEx). Informatie over de Windows API functies is te vinden in Delphi Help.

    [quote:6b84b5da1c="Johan Stokking"]Hoe doe je dat? Ik heb wel iets gevonden voor Windows 98… Maar die werkt weer niet in Windows 2000/XP en omgekeerd. Weet iemand hoe dit moet??

    Alvast bedankt,

    Johan[/quote:6b84b5da1c]
  • [quote:4a43358d05="Johan Stokking"]Hoe doe je dat? Ik heb wel iets gevonden voor Windows 98… Maar die werkt weer niet in Windows 2000/XP en omgekeerd. Weet iemand hoe dit moet??
    [/quote:4a43358d05]

    [code:1:4a43358d05]
    function SetPrivilege(PrivilegeName: string; Enable: boolean): boolean;
    var
    tpPrev, tp: TTokenPrivileges;
    token: THandle;
    dwRetLen: DWord;
    OSVersionInfo: TOSVersionInfo;
    begin
    Assert(not (PrivilegeName = ''), 'Pre-conditie: PrivilegeName is niet ingevuld');

    result := False;

    OSVersionInfo.dwOSVersionInfoSize := SizeOf(OsVersionInfo);
    if GetVersionEx(OSVersionInfo) then
    begin
    if (OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT) then
    begin
    if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, token) then
    try
    tp.PrivilegeCount := 1;
    if LookupPrivilegeValue(Nil, PChar(PrivilegeName), tp.Privileges[0].LUID) then
    begin
    if Enable then
    tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else
    tp.Privileges[0].Attributes := 0;

    dwRetLen := 0;
    result := AdjustTokenPrivileges(token, False, tp, SizeOf(tpPrev), tpPrev, dwRetLen);
    end;
    finally
    CloseHandle(token);
    end;
    end
    else
    begin
    result := True;
    end;
    end;
    end;


    begin
    SetPrivilege('SeShutdownPrivilege', True);
    if (not ExitWindowsEx(EWX_POWEROFF,0)) then
    ExitWindowsEX(EWX_SHUTDOWN,0));
    end;

    [/code:1:4a43358d05]

    Kan zijn dat deze code toch niet onder Windows 9x werkt, dan komt dit omdat de volgende functies alleen op NT+ systemen werken die geprobeerd worden om te laden door de Windows Program Loader. Het beste kun je deze dus dynamisch laden i.p.v. statisch zoals bovenstaand stukje code. Dit kun je doen met GetModuleHandle en GetProcAddress.

    OpenProcessToken (advapi32.dll)
    LookupPrivilegeValue (advapi32.dll)
    AdjustTokenPrivileges (advapi32.dll)
  • Wat ik zou doen, is gewoon onder Windows 9x het systeem afsluiten door RUNDLL USER.EXE,ExitWindows aan te roepen, en onder Windows XP het programma SHUTDOWN aan te roepen, bijv. SHUTDOWN -s -t 01 of iets dergelijks.
    Maar dan zou je dus eerst even een routine moeten maken die de Windows-versie bepaalt… Je kan dat op de officiele manier doen, je kan ook naar wat omgevingsvariabelen kijken, zoals OS en WINDIR (gebruikt onder NT) en WINBOOTDIR (gebruikt onder 9x). Ikzelf maak gebruik van een Class (VB6) om het besturingsysteem te achterhalen. Maargoed, ik ben dus VB programmeur en heb niet zoveel verstand van Delphi, misschien dat je hier toch iets aan hebt…
  • Ja hoor! Ik heb hier ook al aan gedacht, maar misschien dat er een andere (snellere) oplossing voor was.
  • [quote:066efb2ba3="h4xX0r"][quote:066efb2ba3="Johan Stokking"]Hoe doe je dat? Ik heb wel iets gevonden voor Windows 98… Maar die werkt weer niet in Windows 2000/XP en omgekeerd. Weet iemand hoe dit moet??
    [/quote:066efb2ba3]



    Kan zijn dat deze code toch niet onder Windows 9x werkt, dan komt dit omdat de volgende functies alleen op NT+ systemen werken die geprobeerd worden om te laden door de Windows Program Loader. Het beste kun je deze dus dynamisch laden i.p.v. statisch zoals bovenstaand stukje code. Dit kun je doen met GetModuleHandle en GetProcAddress.

    OpenProcessToken (advapi32.dll)
    LookupPrivilegeValue (advapi32.dll)
    AdjustTokenPrivileges (advapi32.dll)[/quote:066efb2ba3]

    Stop de volgende code in een aparte unit.

    [code:1:066efb2ba3]

    { ************************************************** }
    { Shutdown Code for Win9x/NT/2000/XP (c) 2002 h4xX0r }
    { ************************************************** }


    function FunctionDetect(LibName, FuncName: String; var LibPointer: Pointer): boolean;
    var
    LibHandle: THandle;
    begin
    Result := false;
    LibPointer := Nil;
    if (LoadLibrary(PChar(LibName)) = 0) then Exit;
    LibHandle := GetModuleHandle(PChar(LibName));
    if (LibHandle <> 0) then
    begin
    LibPointer := GetProcAddress(LibHandle, PChar(FuncName));
    if (LibPointer <> Nil) then Result := true;
    end;
    end;

    function SetPrivilege(const PrivilegeName: string; Enable: boolean): boolean;
    var
    tpPrev, tp: TTokenPrivileges;
    token: THandle;
    dwRetLen: DWord;
    OSVersionInfo: TOSVersionInfo;
    _OpenProcessToken: function (
    ProcessHandle: THandle;
    DesiredAccess: Cardinal;
    var TokenHandle: Cardinal): LongBool; stdcall;
    _LookupPrivilegeValue: function (
    lpSystemName: PChar;
    lpName: PChar;
    var lpLuid: Int64): LongBool; stdcall;
    _AdjustTokenPrivileges: function (
    TokenHandle: Cardinal;
    DisableAllPrivileges: LongBool;
    const NewState: _TOKEN_PRIVILEGES;
    BufferLength: Cardinal;
    var PreviousSate: _TOKEN_PRIVILEGES;
    var ReturnLength: Cardinal): LongBool; stdcall;
    begin
    Assert(not (PrivilegeName = ''), 'Pre-conditie: PrivilegeName is niet ingevuld');

    result := False;

    OSVersionInfo.dwOSVersionInfoSize := SizeOf(OsVersionInfo);
    if GetVersionEx(OSVersionInfo) then
    begin
    if (OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT) then
    begin
    if (FunctionDetect('ADVAPI32.DLL','OpenProcessToken',@_OpenProcessToken) and
    FunctionDetect('ADVAPI32.DLL','LookupPrivilegeValueA',@_LookupPrivilegeValue) and
    FunctionDetect('ADVAPI32.DLL','AdjustTokenPrivileges',@_AdjustTokenPrivileges)) then
    begin
    if _OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, token) then
    try
    tp.PrivilegeCount := 1;
    if _LookupPrivilegeValue(Nil, PChar(PrivilegeName), tp.Privileges[0].LUID) then
    begin
    if Enable then
    tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else
    tp.Privileges[0].Attributes := 0;

    dwRetLen := 0;
    result := _AdjustTokenPrivileges(token, False, tp, SizeOf(tpPrev), tpPrev, dwRetLen);
    end;
    finally
    CloseHandle(token);
    end
    else
    begin
    // ShowMessage(IntToStr(GetLastError));
    end;
    end;
    end
    else
    begin
    result := True;
    end;
    end;
    end;


    procedure Shutdown;
    begin
    SetPrivilege('SeShutdownPrivilege', True);
    if (not ExitWindowsEx(EWX_POWEROFF,0)) then
    ExitWindowsEX(EWX_SHUTDOWN,0);
    end;

    [/code:1:066efb2ba3]
    Het is wel iets meer code dan alleen maar de functie ExitWindowsEx aanroepen, maar dit geeft je wel de garantie dat dit altijd gaat werken onder zowel Windows 9x,NT,2000,XP en hoger, mits je natuurlijk de juiste rechten hebt om het systeem te mogen afsluiten.
  • Kijk ff op mijn site naar PC-uit 1.0 die heb ik in delphi 6 geschreven.
    Daar kun je me eventueel ook om de sourcecode vragen…

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.