delphi Windows服务器UAC用户账户控制CPU等参数获取及接口TGUID
备忘查询路径:D:\PulledupO2O\WinPro\WinUtilsTests
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages,
System.SysUtils, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.Buttons, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TaEventFunc<T> = reference to function: T;
TaEventProc<T> = reference to procedure(
const AResult:T );
type
TaEvent = procedure(ArrayT: TArray<string>; AProc:TProc) of object;
//:1、如果你的程序类型参数中含有TObject(匿名过程TProc或匿名函数本身也是TObject)
//:那么,程序类型后面就必须要加上of object
//:然而任何事件本身就是1个带有默认TObject参数的程序类型,
//:不管你是否传递带有TObject类型的参数
//:2、上述代码是定义1个标准化事件的格式:后面必须加of object
//:这里你定义为需要传两个参数的格式
TMyEvent = class(TObject)
private
//:定义私有属性和方法:只能在TMyEvent类内部调用
FMyEventProc:TProc;//:定义事件的的响应匿名过程//TaEventProc<string>;//TProc;
//FMyEventFunc:TFunc<TResult> //:你还可以定义事件的泛型参数的匿名函数
FMyEventResult:TArray<string>;//:定义事件的响应结果变量:字符串动态数组等变量
FMyEventFunc:TFunc<TArray<string>>;//:定义事件的响应结果变量:字符串动态数组参数的函数//TaEventFunc<TArray<string>>;
FOnMyEvent:TaEvent;//:定义事件类变量本身
procedure setOnMyEventResult(EventParamsIn:TArray<string>);
//:返回事件响应结果的私有过程:用字符串动态数组等变量
procedure setOnMyEventProc(EventProc:TProc);
//:返回事件响应结果的私有过程:用匿名过程变量
protected
public
//:定义对外调用公开的属性和方法:
constructor Create(
ArrayT: TArray<string>;
AProc:TProc//:定义构造方法
);
destructor Destroy; override;//:定义解构方法
property MyEventProc:TProc
read FMyEventProc write setOnMyEventProc;
//:我的事件的匿名过程变量
//property MyEventFunc:TFunc<TResult>
//read FMyEventFunc write setOnMyEventFunc;
//:你还可以定义事件的泛型函数,泛型<TResult>需要具体化类型
property MyEventResult:TArray<string>
read FMyEventResult //:read响应事件
write setOnMyEventResult; //:write定义和触发事件
//:我的事件的字符还动态数组变量
property OnMyEvent: TaEvent
read FOnMyEvent //:read响应事件
write FOnMyEvent; //:write定义和触发事件
//:定义一个公开的事件,在其它的对象里面
//:可以通过FTMyEvent.OnMyEvent=你要赋的触发事件的方法 这样调用:
//:其读写是通过私有的FOnMyEvent在setOnMyEventResult
//:或setOnMyEventProc中去实现的
published
end;
IMyEventStandAndExtended = interface
['{10BAC933-0000-E800-BC81-FFFFC38D4000}']
//...... 你还可以预留接口:让用户扩展你的自定义事件类
end;
type
//定义一个事件格式,要传参数的格式 后面必须要加上of object
TeacherArgnyEvent = procedure(ErrorCount: Integer) of object;
type
TTeacher = class(TObject)
private
FStudentErrorCount: Integer;
FOnTeacherArngy: TeacherArgnyEvent;
procedure SetStudentErrorCount(Value: Integer);
//:定义一个内部事件,private里的只能在TTeacher类内部调用
public
constructor Create;
destructor Destroy; override;
property StudentErrorCount: Integer
read FStudentErrorCount write SetStudentErrorCount ;
property OnTeacherArngy: TeacherArgnyEvent
read FOnTeacherArngy write FOnTeacherArngy ;
//:定义一个外部的事件,在其它的对象里面
//:可以通过FTeacher.ONTeacherArngy这样调用:
//:读写是通过内部的FOnTeacherArngy
end;
type
TfrxMain = class(TForm)
btnKillAProcess: TSpeedButton;
Memo1: TMemo;
btnMyEvent: TSpeedButton;
Panel1: TPanel;
Panel2: TPanel;
procedure btnKillAProcessClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnMyEventClick(Sender: TObject);
private
AGuid:TGUID;
AHostAppName,ModuleName,AResourceResult:string;
LIntendStr: String;
FTMyEvent:TMyEvent;
FTeacher:TTeacher;
procedure IfTeacherArngy(EC: Integer);
procedure TrigerMyEvent(EventParamsIn:TArray<string>;AProc:TProc);
{ Private declarations }
public
{ Public declarations }
end;
var
frxMain: TfrxMain;
implementation
uses
myFuc_UnifiedPlatForm,
WinUtils;
{$R *.dfm}
{ 类TMyEvent }
constructor TMyEvent.Create(
ArrayT: TArray<string>;
AProc:TProc//TaEventProc<string>//TProc
);
begin
FMyEventResult:=ArrayT;
FMyEventProc:=AProc;
setOnMyEventResult(FMyEventResult);
end;
destructor TMyEvent.Destroy;
begin
inherited;//
end;
procedure TMyEvent.setOnMyEventProc(EventProc:TProc);
begin
if Assigned(FOnMyEvent) then
FMyEventProc:=EventProc;
FMyEventProc;
end;
procedure TMyEvent.setOnMyEventResult(EventParamsIn:TArray<string>);
begin
if Assigned(FOnMyEvent) then
FOnMyEvent(EventParamsIn,FMyEventProc);
//FMyEventProc;
FMyEventResult[0]:=EventParamsIn[0];
end;
{ 类TTeacher }
constructor TTeacher.Create;
begin
FStudentErrorCount := 0;
end;
destructor TTeacher.Destroy;
begin
inherited; //
end;
procedure TTeacher.SetStudentErrorCount(Value: Integer);
begin
FStudentErrorCount := Value;
if FStudentErrorCount <>-1 then
//:给StudentErrorCount赋值的时候,
//:判断是否触发FOnTeacherArngy事件
if Assigned(FOnTeacherArngy) then
//看FOnTeacherArngy是否为空,不为空则执行该事件
//:如果不判断是否为空,则执行下面一句的时候可能会有错误
FOnTeacherArngy(FStudentErrorCount);
end;
procedure TfrxMain.IfTeacherArngy(EC: Integer);
begin
ShowMessage('学生错误了' +IntToStr(ec) +'次,老师生气了!');
//事件触发时的情况,和Button控件在事件列表中双击时出来的那段代码一样,
//只是这里是你自己定义的,而不是DELPHI给你生成的
end;
procedure TfrxMain.TrigerMyEvent(
EventParamsIn:TArray<string>;
AProc:TProc);
var Msg: String; aInt,bInt,cInt:Integer;
begin
Memo1.Lines.Add(
'你定义的事件的FTMyEvent.OnMyEvent:=TrigerMyEvent;'+sLineBreak
+IntendChar(#32,6)+'事件的响应结果:在主线程的TrigerMyEvent方法中去写代码实现!'+sLineBreak
+IntendChar(#32,6)+'事件的触发代码:在主线程的OnFormCreate中或按钮等点击事件中定义!'
);
aInt:=1; bInt:=2; cInt:=aInt +bInt;
AProc:=
procedure
begin
Memo1.Lines.Add('现在响应你触发匿名过程事件后要处理的结果:'+slineBreak
+LIntendStr +aInt.ToString+'+'+bInt.ToString+'='+cInt.ToString
+',你做的非常完美!');
end;
//:在UI中响应你触发事件(用匿名过程TProc参数触发)的处理结果:
FTMyEvent.MyEventProc:=AProc;
//:在UI中响应你触发事件(用动态数组TArray<string>参数触发)的处理结果:
Memo1.Lines.Add(FTMyEvent.MyEventResult[0]);
//:显示初始化数值及后续点击触发事件时传入的数值:
end;
procedure TfrxMain.FormCreate(Sender: TObject);
var
ATHandle:THandle; LParam:TArray<string>;
begin
LIntendStr:=IntendChar(#32,6);
if not Assigned(FTMyEvent) then
FTMyEvent:=TMyEvent.Create(
TArray<string>.create('你触发了初始化的事件OnFormCreate:用你定义的事件的动态数组属性赋值触发TArray<string>.Create'+slineBreak),
procedure
begin
Memo1.Lines.Add('你触发了初始化的事件OnFormCreate:用你定义的事件的匿名过程属性赋值触发TProc'+slineBreak);
end
);
FTMyEvent.OnMyEvent:=TrigerMyEvent;
FTeacher := TTeacher.Create ; //创建一个TTeacher的实例
FTeacher.OnTeacherArngy :=
IfTeacherArngy;
//把frxMain里的IfTeacherArngy过程
//赋值给FTeacher的OnTeacherArngy,这样它就不为空了
//ShowMessage('学生错误了' +IntToStr(6) +'次,老师生气了!');
//事件触发时的情况,和Button控件在事件列表中双击时出来的那段代码一样
//:只是这里是你自己定义的,而不是DELPHI给你生成的
{
AResourceResult:=GetResourceModuleName(ExtractFilePath(ParamStr(0)),'');
//:?! //:ModuleName?!应该指DLL等模块化的进程全路径名
ATHandle:=THandle(btnKillAProcess);
self.Caption:=
'我是1个按钮,我的THandle: '+ATHandle.ToString
+' ps GetHashCode:'+btnKillAProcess.GetHashCode.ToString;
if ATHandle<>-1 then btnKillAProcessClick(Sender);
//:相当于:
SetButtonElevated( ATHandle );
SetButtonElevated( MainInstance ); //等价于:
SetButtonElevated( HInstance ); //:等价于MainInstance
AGuid:=TGUID.Create(TGUID.Empty);
Memo1.Lines.Add(AGuid.ToString);
}
end;
procedure TfrxMain.btnMyEventClick(Sender: TObject);
var Msg: String;
begin
//触发(非初始化的、是你点击按钮等触发的)事件:
FTMyEvent.MyEventResult
:=TArray<string>.Create('你触发事件了(非OnFormCreate初始化的、是你点击按钮等触发的):'+slineBreak
+LIntendStr+'用你定义的事件的动态数组属性赋值TArray<string>.Create'+slineBreak
+LIntendStr+'或匿名过程TProc属性赋值触发!'+slineBreak);
end;
procedure TfrxMain.btnKillAProcessClick(Sender: TObject);
var Msg: String;
begin
if MainInstance = HGLOBAL(HInstance) then
Msg :='判断正确'+ sLineBreak+ sLineBreak;
//:HInstance: HINST;//:uses SysInit;
//:HMODULE = HINST; //:uses system:
//:HINST = THandle;
//:HGLOBAL = THandle;
Msg := Msg+
'管理员进入系统的吗IsAdministrator: '
+ BoolToStr(IsAdministrator, True) + sLineBreak +
'管理员账号进入系统的吗IsAdministratorAccount: '
+ BoolToStr(IsAdministratorAccount, True) + sLineBreak +
'用户账户控制是否打开IsUACEnabled: '
+ BoolToStr(IsUACEnabled, True) + sLineBreak +
'权限被提升了吗IsElevated: '
+ BoolToStr(IsElevated, True) + sLineBreak +
'当前线程捕获设备是否单CPU: '
+ BoolToStr(TThread.IsSingleProcessor, True) + sLineBreak +
'当前线程捕获设备CPU核心数: '
+ IntToStr(TThread.ProcessorCount) + sLineBreak +
'全局变量CPUCount捕获CPU核心数: '
+ IntToStr(CPUCount)+ sLineBreak +
'全局本地化系统代码页936(代表:简体中文GBK): '
+ DefaultSystemCodePage.ToString+ sLineBreak +
'全局本地化用于_NewUnicodeString函数中指新Unicode字符串的字节长度参数1200: '
+ DefaultUnicodeCodePage.ToString+ sLineBreak +
'全局本地化是(>=127)否(<127)需要用UTF8来对字符串进行比较的字节码值的序数127: '
+ (UTF8CompareLocale.ToString)+ sLineBreak +
'GetResourceModuleName:'+AResourceResult+ sLineBreak +
'模块被调用的返回值:'+IntToStr(LoadResourceModule( PChar(ParamStr(0)) ))+ sLineBreak +
'你TGUID.Create(TGUID.Empty).ToString生成的GUID:'+TGUID.Create(TGUID.Empty).ToString
;
Memo1.Lines.Add(Msg);
//MessageBox(0, PChar(Msg), 'Hello from RegisterExtension!', MB_OK or MB_ICONINFORMATION);
//ShowMessage(Msg);
//LoadResourceModule( PChar(ParamStr(0)) );
end;
procedure TfrxMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(FTMyEvent) then
FTMyEvent.Free ; //窗体关闭时释放
FTeacher.Free; //窗体关闭时释放
end;
initialization
finalization
end.
unit WinUtils;
{$WARN SYMBOL_PLATFORM OFF}
{$R+}
interface
uses
Windows;
type
TElevatedProc = function(const AParameters: String): Cardinal;
TProcessMessagesMeth = procedure of object;
// Warning: this function will be executed in external process.
// Do not use any global variables inside this routine!
// Use only supplied AParameters:
//警告:此函数将在外部执行的过程。
//不要使用任何全局变量在这个例程!
//只使用提供AParameters :
var
OnElevateProc: TElevatedProc;
// Call this routine after you have assigned OnElevateProc
//调用这个例程分配OnElevateProc之后:
procedure CheckForElevatedTask;
/// <remarks>在完整的管理员权限下运行OnElevateProc:
///: Runs OnElevateProc under full administrator rights:</remarks>
function RunElevated(
const AParameters: String;
const AWnd: HWND = 0;
const AProcessMessages: TProcessMessagesMeth = nil
): Cardinal; overload;
function IsAdministrator: Boolean;
function IsAdministratorAccount: Boolean;
function IsUACEnabled: Boolean;
/// <summary>令牌提升权限:</summary>
function IsElevated: Boolean;
/// <summary>捕获1个程序或窗体或其中的控件来执行提升令牌权限:</summary>
/// <summary>SetButtonElevated( HInstance );</summary>
/// <summary>SetButtonElevated( MainInstance );</summary>
/// <remarks>MainInstance: THandle;</remarks>
/// <remarks> :system.pas系统常量:</remarks>
/// <remarks> :当前程序:Handle of the main(.EXE):HInstance</remarks>
procedure SetButtonElevated(const AHandle: THandle);
implementation
uses
SysUtils, Registry, ShellAPI, ComObj;
const
RunElevatedTaskSwitch = '0CC5C50CB7D643B68CB900BF000FFFD5'; // some unique value, just a GUID with removed '[', ']', and '-'
/// <remarks>如果进入(获得)了管理员组指针SidToCheck,
///:开始检查(包括所有SID的检查)当前账户是否为SidToCheck的成员: </remarks>
function CheckTokenMembership(TokenHandle: THANDLE; SidToCheck: Pointer; var IsMember: BOOL): BOOL; stdcall; external advapi32 name 'CheckTokenMembership';
function RunElevated(
const AParameters: String;
const AWnd: HWND = 0;
const AProcessMessages: TProcessMessagesMeth = nil
): Cardinal; overload;
var
SEI: TShellExecuteInfo;
Host: String;
Args: String;
begin
Assert(Assigned(OnElevateProc), 'OnElevateProc must be assigned before calling RunElevated');
if IsElevated then
begin
if Assigned(OnElevateProc) then
Result := OnElevateProc(AParameters)
else
Result := ERROR_PROC_NOT_FOUND;
Exit;
end;
Host := ParamStr(0);
Args := Format('/%s %s', [RunElevatedTaskSwitch, AParameters]);
//获得设备的SEI:
FillChar(SEI, SizeOf(SEI), 0);
SEI.cbSize := SizeOf(SEI);
SEI.fMask := SEE_MASK_NOCLOSEPROCESS;
{$IFDEF UNICODE}
SEI.fMask := SEI.fMask or SEE_MASK_UNICODE;
{$ENDIF}
SEI.Wnd := AWnd;
SEI.lpVerb := 'runas';
SEI.lpFile := PChar(Host);
SEI.lpParameters := PChar(Args);
//:获取设备SEI的信息参数Args即AParameters
SEI.nShow := SW_NORMAL;
if not ShellExecuteEx(@SEI) then
RaiseLastOSError;
try
Result := ERROR_GEN_FAILURE;
if Assigned(AProcessMessages) then
begin
repeat
if not GetExitCodeProcess(SEI.hProcess, Result) then
Result := ERROR_GEN_FAILURE;
//:通过获得当前运行程序的退出码GetExitCodeProcess
//:取得当前环境账户的信息参数AParameters
AProcessMessages;//:执行1个匿名方法
until Result <> STILL_ACTIVE;
//:Result返回当前环境账户的信息参数AParameters
end
else
begin
if WaitForSingleObject(SEI.hProcess, INFINITE) <> WAIT_OBJECT_0 then
if not GetExitCodeProcess(SEI.hProcess, Result) then
Result := ERROR_GEN_FAILURE;
//:Result返回当前环境账户的信息参数AParameters
end;
finally
CloseHandle(SEI.hProcess);
end;
end;
function IsAdministrator: Boolean;
var
psidAdmin: Pointer;
B: BOOL;
const
SECURITY_NT_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
SE_GROUP_USE_FOR_DENY_ONLY = $00000010;
begin
psidAdmin := nil;
try
// Создаём SID группы админов для проверки
//:俄罗斯语:创建SID组管理员到psidAdmin指针:
Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
psidAdmin));
// Проверяем, входим ли мы в группу админов (с учётов всех проверок на disabled SID)
//:俄罗斯语:如果我们进入了管理员组指针,
//:我们开始检查(包括SID所有的检查):
if CheckTokenMembership(0, psidAdmin, B) then
Result := B
else
Result := False;
finally
if psidAdmin <> nil then
FreeSid(psidAdmin);
end;
end;
{$R-}
function IsAdministratorAccount: Boolean;
var
psidAdmin: Pointer;
Token: THandle;
Count: DWORD;
TokenInfo: PTokenGroups;
HaveToken: Boolean;
I: Integer;
const
SECURITY_NT_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
SE_GROUP_USE_FOR_DENY_ONLY = $00000010;
begin
Result := Win32Platform <> VER_PLATFORM_WIN32_NT;
if Result then
Exit;
psidAdmin := nil;
TokenInfo := nil;
HaveToken := False;
try
Token := 0;
HaveToken := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, Token);
if (not HaveToken) and (GetLastError = ERROR_NO_TOKEN) then
HaveToken := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token);
if HaveToken then
begin
Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
psidAdmin));
if GetTokenInformation(Token, TokenGroups, nil, 0, Count) or
(GetLastError <> ERROR_INSUFFICIENT_BUFFER) then
RaiseLastOSError;
TokenInfo := PTokenGroups(AllocMem(Count));
Win32Check(GetTokenInformation(Token, TokenGroups, TokenInfo, Count, Count));
for I := 0 to TokenInfo^.GroupCount - 1 do
begin
Result := EqualSid(psidAdmin, TokenInfo^.Groups[I].Sid);
if Result then
Break;
end;
end;
finally
if TokenInfo <> nil then
FreeMem(TokenInfo);
if HaveToken then
CloseHandle(Token);
if psidAdmin <> nil then
FreeSid(psidAdmin);
end;
end;
{$R+}
function IsUACEnabled: Boolean;
var
Reg: TRegistry;
begin
Result := CheckWin32Version(6, 0);
if Result then
begin
Reg := TRegistry.Create(KEY_READ);
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Policies\System', False) then
if Reg.ValueExists('EnableLUA') then
Result := (Reg.ReadInteger('EnableLUA') <> 0)
else
Result := False
else
Result := False;
finally
FreeAndNil(Reg);
end;
end;
end;
function IsElevated: Boolean;
const
TokenElevation = TTokenInformationClass(20);
//:系统令牌信息类枚举20:令牌提升
//:枚举数值的提取方法:定义1个(结构体)记录
type
TOKEN_ELEVATION = record
TokenIsElevated: DWORD;
end; //:枚举数值的提取方法:定义1个(结构体)记录
var
TokenHandle: THandle;
ResultLength: Cardinal;
ATokenElevation: TOKEN_ELEVATION;
//:枚举数值的提取方法:定义1个(结构体)记录
HaveToken: Boolean;
begin
if CheckWin32Version(6, 0) then
begin
TokenHandle := 0;
HaveToken:= OpenThreadToken(
GetCurrentThread,
TOKEN_QUERY, True, TokenHandle );
if (not HaveToken) and (GetLastError = ERROR_NO_TOKEN) then
HaveToken := OpenProcessToken(
GetCurrentProcess,
TOKEN_QUERY, TokenHandle );
if HaveToken then
begin
try
ResultLength := 0;
//通过获取令牌的信息,得到ATokenElevation令牌:
if GetTokenInformation(
TokenHandle, TokenElevation,
@ATokenElevation,
SizeOf(ATokenElevation),
ResultLength ) then
Result := ATokenElevation.TokenIsElevated <> 0
//=20=定义的常量TokenElevation=TTokenInformationClass(20);
//:令牌提升了:枚举数值的提取方法:定义1个(结构体)记录
else
Result := False;
finally
CloseHandle(TokenHandle);
end;
end
else
Result := False;
end
else
Result := IsAdministrator;
end;
procedure SetButtonElevated(const AHandle: THandle);
const
BCM_SETSHIELD = $160C;
var
Required: BOOL;
begin
//_WIN32_WINNT version各windows版本常量:
//https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?redirectedfrom=MSDN&view=vs-2019
if not CheckWin32Version(6, 0) then
Exit;
if IsElevated then //:执行IsElevated:令牌权限提升
Exit;
Required := True;
SendMessage(AHandle, BCM_SETSHIELD, 0, LPARAM(Required));
end;
procedure CheckForElevatedTask;
function GetArgsForElevatedTask: String;
function PrepareParam(const ParamNo: Integer): String;
begin
Result := ParamStr(ParamNo);
if Pos(' ', Result) > 0 then
Result := AnsiQuotedStr(Result, '"');
end;
var
X: Integer;
begin
Result := '';
for X := 1 to ParamCount do
begin
if (AnsiUpperCase(ParamStr(X)) = ('/' + RunElevatedTaskSwitch)) or
(AnsiUpperCase(ParamStr(X)) = ('-' + RunElevatedTaskSwitch)) then
Continue;
Result := Result + PrepareParam(X) + ' ';
end;
Result := Trim(Result);
end;
var
ExitCode: Cardinal;
begin
if not FindCmdLineSwitch(RunElevatedTaskSwitch) then
Exit;
ExitCode := ERROR_GEN_FAILURE;
try
if not IsElevated then
ExitCode := ERROR_ACCESS_DENIED
else
if Assigned(OnElevateProc) then
ExitCode := OnElevateProc(GetArgsForElevatedTask)
else
ExitCode := ERROR_PROC_NOT_FOUND;
except
on E: Exception do
begin
if E is EAbort then
ExitCode := ERROR_CANCELLED
else
if E is EOleSysError then
ExitCode := Cardinal(EOleSysError(E).ErrorCode)
else
if E is EOSError then
else
ExitCode := ERROR_GEN_FAILURE;
end;
end;
if ExitCode = STILL_ACTIVE then
ExitCode := ERROR_GEN_FAILURE;
TerminateProcess(GetCurrentProcess, ExitCode);
end;
{ procedure KillProcess;
var
Msg: String;
begin
Msg :=
'IsAdministrator: ' + BoolToStr(IsAdministrator, True) + sLineBreak +
'IsAdministratorAccount: ' + BoolToStr(IsAdministratorAccount, True) + sLineBreak +
'IsUACEnabled: ' + BoolToStr(IsUACEnabled, True) + sLineBreak +
'IsElevated: ' + BoolToStr(IsElevated, True);
MessageBox(0, PChar(Msg), 'Hello from RegisterExtension!', MB_OK or MB_ICONINFORMATION);
KillTask(KillProcessName);
showmessage(KillProcessName);
end; }
end.
|
请发表评论