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.