我需要找到一种方法来确保使用我的库的人已将应用程序清单中的设置requestedExecutionLevel
为的最小值highestAvailable
,如下所示:
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
</requestedPrivileges>
当他们没有正确设置清单时,我想抛出一个异常,以便开发人员知道此需求,而不必阅读文档。
主要问题:是否可以访问此信息,如果可以,如何访问?
我已经考虑过检查此设置的结果,而不是检查此设置。设置为时,highestAvailable
我希望Administrators组的任何用户部分都可以以管理员身份运行。
可以使用以下方法实现:
正如Hans Passant在他的回答中指出的那样,真正的基本问题-在这种情况下为什么要检查清单-为什么:
如何检查当前用户是否可以提升权限运行进程?
如问题中所建议,以下方法将起作用:
var myPrincipal = new WindowsPrincipal( WindowsIdentity.GetCurrent() );
if ( !myPrincipal.IsInRole( WindowsBuiltInRole.Administrator ) &&
IsUserInAdminGroup() )
{
throw new NotSupportedException( "Some useful comments ..." );
}
因此,主要的问题是,你怎么写IsUserInAdminGroup()
?UAC自提升示例中列出的代码虽然有用,但并未说明发生了什么以及为什么需要这样做。
汉斯·帕桑(Hans Passant)在评论中 回答:“ Windows很好地模拟了非提升过程,无法从.NET得知用户帐户实际上是管理员帐户。回退到使用pinvoke询问令牌是链接中使用的解决方法代码。” 。
简而言之,您需要依赖P / Invoke来实现IsUserInAdminGroup()
,其中的代码可以在UAC示例中找到。
也许更有趣,为什么呢?
为了找出答案,我重构了示例代码并将该函数合并到我的库中。我认为结果更加清楚。在下面可以找到大纲,注释可能比代码更相关,因为它取决于其他类,等等。
从Windows Vista开始,您具有由TOKEN_ELEVATION_TYPE表示的不同令牌类型。尽管您可以WindowsIdentity.Token
通过.NET访问,但这不是我们需要检查某人是否为管理员的令牌。这是一个有限的令牌。它附有链接的提升令牌,但这在.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 );
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句