delphi Windows服务器UAC用户账户控制CPU等参数获取及接口TGUID

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.
 

发布了63 篇原创文章 · 获赞 6 · 访问量 6846

猜你喜欢

转载自blog.csdn.net/pulledup/article/details/104964970