关于Windows 7:如何检测我的进程是否正在运行UAC提升?

关于Windows 7:如何检测我的进程是否正在运行UAC提升?

How can I detect if my process is running UAC-elevated or not?

我的Vista应用程序需要知道用户是"以管理员身份"(提升)还是以标准用户(非提升)启动它的。 如何在运行时检测到?


对于使用C#的我们来说,在Windows SDK中,有一个" UACDemo"应用程序作为"跨技术示例"的一部分。 他们使用以下方法查找当前用户是否是管理员:

1
2
3
4
5
6
7
8
9
10
private bool IsAdministrator
{
    get
    {
        WindowsIdentity wi = WindowsIdentity.GetCurrent();
        WindowsPrincipal wp = new WindowsPrincipal(wi);

        return wp.IsInRole(WindowsBuiltInRole.Administrator);
    }
}

(注意:我将原始代码重构为属性,而不是" if"语句)


以下C ++函数可以做到这一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
HRESULT GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet );

/*
Parameters:

ptet
    [out] Pointer to a variable that receives the elevation type of the current process.

    The possible values are:

    TokenElevationTypeDefault - This value indicates that either UAC is disabled,
        or the process is started by a standard user (not a member of the Administrators group).

    The following two values can be returned only if both the UAC is enabled
    and the user is a member of the Administrator's group:

    TokenElevationTypeFull - the process is running elevated.

    TokenElevationTypeLimited - the process is not running elevated.

Return Values:

    If the function succeeds, the return value is S_OK.
    If the function fails, the return value is E_FAIL. To get extended error information, call GetLastError().

Implementation:
*/

HRESULT GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet )
{
    if ( !IsVista() )
        return E_FAIL;

    HRESULT hResult = E_FAIL; // assume an error occurred
    HANDLE hToken   = NULL;

    if ( !::OpenProcessToken(
                ::GetCurrentProcess(),
                TOKEN_QUERY,
                &hToken ) )
    {
        return hResult;
    }

    DWORD dwReturnLength = 0;

    if ( ::GetTokenInformation(
                hToken,
                TokenElevationType,
                ptet,
                sizeof( *ptet ),
                &dwReturnLength ) )
    {
            ASSERT( dwReturnLength == sizeof( *ptet ) );
            hResult = S_OK;
    }

    ::CloseHandle( hToken );

    return hResult;
}


我认为海拔类型不是您想要的答案。 您只想知道它是否升高。 调用GetTokenInformation时,请使用TokenElevation而不是TokenElevationType。 如果结构返回正值,则用户为admin。 如果为零,则用户为正常高程。

这是一个Delphi解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function TMyAppInfo.RunningAsAdmin: boolean;
var
  hToken, hProcess: THandle;
  pTokenInformation: pointer;
  ReturnLength: DWord;
  TokenInformation: TTokenElevation;
begin
  hProcess := GetCurrentProcess;
  try
    if OpenProcessToken(hProcess, TOKEN_QUERY, hToken) then try
      TokenInformation.TokenIsElevated := 0;
      pTokenInformation := @TokenInformation;
      GetTokenInformation(hToken, TokenElevation, pTokenInformation, sizeof(TokenInformation), ReturnLength);
      result := (TokenInformation.TokenIsElevated > 0);
    finally
      CloseHandle(hToken);
    end;
  except
   result := false;
  end;
end;

这是检查(当前)进程是否提高的VB6实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Option Explicit

'--- for OpenProcessToken
Private Const TOKEN_QUERY                   As Long = &H8
Private Const TokenElevation                As Long = 20

Private Declare Function GetCurrentProcess Lib"kernel32" () As Long
Private Declare Function OpenProcessToken Lib"advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function GetTokenInformation Lib"advapi32" (ByVal TokenHandle As Long, ByVal TokenInformationClass As Long, TokenInformation As Any, ByVal TokenInformationLength As Long, ReturnLength As Long) As Long
Private Declare Function CloseHandle Lib"kernel32" (ByVal hObject As Long) As Long


Public Function IsElevated(Optional ByVal hProcess As Long) As Boolean
    Dim hToken          As Long
    Dim dwIsElevated    As Long
    Dim dwLength        As Long

    If hProcess = 0 Then
        hProcess = GetCurrentProcess()
    End If
    If OpenProcessToken(hProcess, TOKEN_QUERY, hToken) <> 0 Then
        If GetTokenInformation(hToken, TokenElevation, dwIsElevated, 4, dwLength) <> 0 Then
            IsElevated = (dwIsElevated <> 0)
        End If
        Call CloseHandle(hToken)
    End If
End Function


推荐阅读

    linux命令删除用户组?

    linux命令删除用户组?,管理,密码,系统,用户组,用户,概念,命令,文件,管理员,

    linux命令守护进程?

    linux命令守护进程?,系统,服务,环境,状态,名字,进程,异常,基础,代码,下来,如

    linux中用户创建命令?

    linux中用户创建命令?,密码,系统,用户,软件,命令,联系方式,管理,信息,用户

    linux截取进程命令?

    linux截取进程命令?,系统,工作,状态,信息,进程,软件,地址,命令,标准,实时,lin

    linux退出进程命令?

    linux退出进程命令?,系统,软件,名称,代码,进程,报告,数字,暂停,状态,平台,lin

    linux下进程调试命令?

    linux下进程调试命令?,系统,工作,软件,信息,命令,基础,地址,状态,进程,实时,L

    linux命令限制进程?

    linux命令限制进程?,系统,时间,管理,周期,进程,命令,传播,地方,名称,标准,Lin

    linux注销命令用户?

    linux注销命令用户?,系统,服务,密码,地址,工作,命令,状态,工具,信息,基础,lin

    linux命令行创建用户?

    linux命令行创建用户?,系统,密码,软件,新增,用户,联系方式,管理,用户名,命

    linux系统用户命令?

    linux系统用户命令?,系统,工作,地址,信息,管理,命令,目录,时间,电脑,名称,请

    linux长命令查看进程?

    linux长命令查看进程?,系统,状态,信息,数据,软件,进程,情况,总量,实时,命令,l

    linux切换进程命令?

    linux切换进程命令?,服务,系统,工具,地址,命令,基础,工作,标准,情况,状态,Lin

    linux查询命令进程?

    linux查询命令进程?,系统,名称,总量,情况,状态,进程,材料,工具,电脑,数据,怎

    linux命令如何杀进程?

    linux命令如何杀进程?,状态,系统,暂停,管理,进程,命令,平台,信息,工具,电脑,L

    linux常用命令查进程?

    linux常用命令查进程?,系统,情况,软件,工具,实时,代码,电脑,地址,总量,状态,

    linux命令所有用户?

    linux命令所有用户?,系统,密码,信息,情况,名称,命令,用户,时间,地址,位置,如

    linux命令进入用户?

    linux命令进入用户?,系统,密码,用户,地址,信息,软件,命令,用户名,联系方式,

    linux命令用户管理?

    linux命令用户管理?,系统,密码,管理,工作,信息,地址,工具,命令,用户,基础,LIn

    linux命令进程状态?

    linux命令进程状态?,系统,状态,进程,命令,数据,管理,软件,名称,信息,参数,Lin

    linux用户与组的命令?

    linux用户与组的命令?,管理,系统,名称,用户组,密码,用户,命令,情况,信息,单