如何访问正在运行的应用程序的应用程序清单?

How can I access the application manifest of the running application?(如何访问正在运行的应用程序的应用程序清单?)

本文介绍了如何访问正在运行的应用程序的应用程序清单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要找到一种方法来确保使用我的库的用户在应用程序清单中将requestedExecutionLevel设置为最小highestAvailable,如下所示:

<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
  <requestedExecutionLevel level="highestAvailable" uiAccess="false" />
</requestedPrivileges>

当他们未正确设置清单时,我希望引发异常,以便开发人员无需阅读文档即可了解此需求。

主要问题:是否可以访问此信息?如果可以,访问方式是什么?

我没有检查此设置,而是考虑检查此设置的结果。当设置为highestAvailable时,我希望管理员组的任何用户部分都以管理员身份运行。

这是可以使用的:

  • WindowsPrinciple.IsInRole()检查当前使用的角色。
  • 似乎更难找到一种检查用户是否在给定组中,或者更具体地说是管理员组中的方法。IsUserInAdminGroup() method listed on the UAC code samples可能会成功。

推荐答案

作为Hans Passant points out in his answer,真正的基本问题--为什么在这种情况下您会想要检查清单--是:

如何检查当前用户是否可以使用提升的权限运行进程?

正如问题中所建议的,以下方法是可行的:

var myPrincipal = new WindowsPrincipal( WindowsIdentity.GetCurrent() );
if ( !myPrincipal.IsInRole( WindowsBuiltInRole.Administrator ) &&
     IsUserInAdminGroup() )
{
    throw new NotSupportedException( "Some useful comments ..." );
}
主要问题是,您如何编写IsUserInAdminGroup()?code listed in the UAC self-elevation sample虽然有用,但无法解释发生了什么以及为什么需要它。

Hans passant回答in a comment"Windows模拟非提升进程的效果太好了,无法从.NET看出用户帐户实际上是管理员帐户。回退到使用PInvoke询问令牌是链接代码中使用的解决方法。"

简而言之,实现IsUserInAdminGroup()需要依赖P/Invoke,代码in the UAC sample。

也许更有趣的是为什么?

以便找出I refactored the sample code and incorporated the function into my library。在我看来,结果会更清楚一些。下面您可以找到大纲,注释可能比代码更相关,因为它依赖于其他类等...

从Windows Vista开始,您有不同的令牌类型,如TOKEN_ELEVATION_TYPE所示。虽然您可以通过.NET访问WindowsIdentity.Token,但这不是我们检查某人是否为管理员所需的令牌。这是受限令牌。它附加了一个链接提升的令牌,但这不会在.NET中公开。

下面的(半伪)代码所做的几乎就是查找原始令牌上是否附加了这种提升的令牌,并使用该令牌来检查IsInRole()

// Default token's received aren't impersonation tokens,
// we are looking for an impersonation token.
bool isImpersonationToken = false;

// Open the access token of the current process.
SafeTokenHandle processToken;
if ( !AdvApi32.OpenProcessToken( ..., out processToken ) )
{
    MarshalHelper.ThrowLastWin32ErrorException();
}

// Starting from Vista linked tokens are supported which need to be checked.
if ( EnvironmentHelper.VistaOrHigher )
{
    // Determine token type: limited, elevated, or default.
    SafeUnmanagedMemoryHandle elevationTypeHandle = ...;
    if ( !AdvApi32.GetTokenInformation( ... elevationTypeHandle ) )
    {
        MarshalHelper.ThrowLastWin32ErrorException();
    }
    var tokenType = (AdvApi32.TokenElevationType)Marshal.ReadInt32( 
        elevationTypeHandle.DangerousGetHandle() );

    // If limited, get the linked elevated token for further check.
    if ( tokenType == AdvApi32.TokenElevationType.TokenElevationTypeLimited )
    {
        // Get the linked token.
        SafeUnmanagedMemoryHandle linkedTokenHandle = ...;
        if ( !AdvApi32.GetTokenInformation( ... linkedTokenHandle ) )
        {
            MarshalHelper.ThrowLastWin32ErrorException();
        }
        processToken = new SafeTokenHandle(
             Marshal.ReadIntPtr( linkedTokenHandle.DangerousGetHandle() ) );
        // Linked tokens are already impersonation tokens.
        isImpersonationToken = true;
    }
}

// We need an impersonation token in order
// to check whether it contains admin SID.
if ( !isImpersonationToken )
{
    SafeTokenHandle impersonatedToken;
    if ( !AdvApi32.DuplicateToken( ..., out impersonatedToken ) )
    {
        MarshalHelper.ThrowLastWin32ErrorException();
    }
    processToken = impersonatedToken;
}

// Check if the token to be checked contains admin SID.
var identity= new WindowsIdentity( processToken.DangerousGetHandle() );
var principal = new WindowsPrincipal( identity );
return principal.IsInRole( WindowsBuiltInRole.Administrator );

这篇关于如何访问正在运行的应用程序的应用程序清单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何访问正在运行的应用程序的应用程序清单?

基础教程推荐