如何检测我的进程是否正在运行 UAC 提升的进程?

发布于 2024-07-06 07:31:58 字数 74 浏览 15 评论 0原文

我的 Vista 应用程序需要知道用户是否以“管理员”身份(提升权限)或标准用户(非提升权限)启动它。 我如何在运行时检测到这一点?

My Vista application needs to know whether the user has launched it "as administrator" (elevated) or as a standard user (non-elevated). How can I detect that at run time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不奢求什么 2024-07-13 07:31:58

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

private bool IsAdministrator
{
    get
    {
        WindowsIdentity wi = WindowsIdentity.GetCurrent();
        WindowsPrincipal wp = new WindowsPrincipal(wi);

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

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

For those of us working in C#, in the Windows SDK there is a "UACDemo" application as a part of the "Cross Technology Samples". They find if the current user is an administrator using this method:

private bool IsAdministrator
{
    get
    {
        WindowsIdentity wi = WindowsIdentity.GetCurrent();
        WindowsPrincipal wp = new WindowsPrincipal(wi);

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

(Note: I refactored the original code to be a property, rather than an "if" statement)

再浓的妆也掩不了殇 2024-07-13 07:31:58

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

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;
}

The following C++ function can do that:

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;
}
卸妝后依然美 2024-07-13 07:31:58

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

这是德尔福的解决方案:

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;

I do not think elevation type is the answer you want. You just want to know if it is elevated. Use TokenElevation instead of TokenElevationType when you call GetTokenInformation. If the structure returns a positive value, the user is admin. If zero, the user is normal elevation.

Here is a Delphi solution:

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;
[浮城] 2024-07-13 07:31:58

这是一个 VB6 实现,用于检查(当前)进程是否已提升

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

Here is a VB6 implementation of a check if a (current) process is elevated

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文