Einzelnen Beitrag anzeigen

Benutzerbild von mleyen
mleyen

Registriert seit: 10. Aug 2007
609 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Shutdown nach Ende der Programmausführung

  Alt 5. Jul 2011, 15:20
Hab da auch noch was, einfach den Prozessnamen oder die PID als Parameter übergeben:

Delphi-Quellcode:
program ShutDownOnProcessClosed;

uses
  Windows, TlHelp32;

function ShutdownWindows: Boolean;
const
  cSE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
var
  OSVersionInfo: TOSVersionInfo;
  hToken: THandle;
  hProcess: THandle;
  TokenPriv: TTokenPrivileges;
  ReturnLength: DWORD;
begin
  Result := False;
  OSVersionInfo.dwOSVersionInfoSize := SizeOf (OSVersionInfo);
  if not GetVersionEx(OSVersionInfo) then
    Exit;
  if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
  begin
    hProcess := GetCurrentProcess;
    if not OpenProcessToken (hProcess, TOKEN_ADJUST_PRIVILEGES, hToken) then
      Exit;
    if not LookupPrivilegeValue (nil, cSE_SHUTDOWN_NAME, TokenPriv.Privileges[0].Luid) then
      Exit;
    TokenPriv.PrivilegeCount := 1;
    TokenPriv.Privileges [0].Attributes := SE_PRIVILEGE_ENABLED;
    if not AdjustTokenPrivileges (
        hToken, False, TokenPriv, 0, PTokenPrivileges (nil)^, ReturnLength)
    then
      Exit;
    CloseHandle (hToken);
  end;
  Result := ExitWindowsEx(EWX_SHUTDOWN or EWX_POWEROFF, $FFFFFFFF);
end;

function LowerCase(const Value: string): string;
var
  Ch : Char;
  L : Integer;
  Source: PChar;
  Dest : PChar;
begin
  L := Length(Value);
  SetLength(Result, L);
  Source := Pointer(Value);
  Dest := Pointer(Result);
  while L <> 0 do
  begin
    Ch := Source^;
    if (Ch >= 'A') and (Ch <= 'Z') then
      Inc(Ch, 32);
    Dest^ := Ch;
    Inc(Source);
    Inc(Dest);
    Dec(L);
  end;
end;

function getProcessID(const Exename: string): Cardinal;
var
  hProcSnap: THandle;
  ProcEntry: TProcessEntry32;
begin
  Result := 0;
  hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  if hProcSnap <> INVALID_HANDLE_VALUE then
  begin
    ProcEntry.dwSize := SizeOf(ProcessEntry32);
    if Process32First(hProcSnap, ProcEntry) = true then
      while Process32Next(hProcSnap, ProcEntry) = true do
        if LowerCase(Exename) = LowerCase(ProcEntry.szExeFile) then
        begin
          Result := ProcEntry.th32ProcessID;
          Break;
        end;
    CloseHandle(hProcSnap);
  end;
end;

function ProcessExist(const PID: Cardinal): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if FProcessEntry32.th32ProcessID = PID then
    begin
      Result := True;
      Break;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

function CharToUInt(const AChar: Char): Cardinal; {$IFDEF Inln}inline;{$ENDIF}
begin
  Result := Ord(AChar)-ord('0');
end;

function TryCharToUInt(const AChar: Char; out AInt: Cardinal): Boolean; {$IFDEF Inln}inline;{$ENDIF}
begin
  AInt := CharToUInt(AChar);
  Result := AInt <= 9;
end;

function TryStrToUInt(const AStr: string; out AUInt: Cardinal): Boolean; {$IFDEF Inln}inline;{$ENDIF}
var
  i, tmp: Cardinal;
begin
  for i := 1 to Length(AStr) do
  begin
    if TryCharToUInt(AStr[i], tmp) then
      AUInt := AUInt * 10 + tmp
    else
    begin
      Result := false;
      Exit;
    end;
  end;
  Result := AStr <> '';
end;

var
  PID: Cardinal;
begin
  if ParamCount <> 1 then
    Exit;

  if not TryStrToUInt(ParamStr(1), PID) then
    PID := getProcessID(ParamStr(1));

  if PID <> 0 then
    while ProcessExist(PID) do
      Sleep(100);

  ShutdownWindows;
end.
Angehängte Dateien
Dateityp: zip ShutDownOnProcessClosed.zip (10,2 KB, 4x aufgerufen)
  Mit Zitat antworten Zitat