通过上一篇的结论,所谓兼容win7,不过是要让自己的程序拥有UAC权限。
但是微软似乎不是很喜欢告诉用户,这个程序需要UAC权限,而是默默的拦截掉了,所以我们的程序就无法实现应该做的事情。
接下去展示下程序如何知道自己是否拥有UAC权限。
外国的某位作者对此有个非常详细的阐述:
http://www.codeproject.com/KB/vista-security/UACSelfElevation.aspx
这里借花献佛摘录下检测自己是否拥有权限的代码。
vc为:
BOOL IsRunAsAdmin()
{
BOOL fIsRunAsAdmin = FALSE;
DWORD dwError = ERROR_SUCCESS;
PSID pAdministratorsGroup = NULL;
// Allocate and initialize a SID of the administrators group.
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pAdministratorsGroup))
{
dwError = GetLastError();
goto Cleanup;
}
// Determine whether the SID of administrators group is enabled in
// the primary access token of the process.
if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
{
dwError = GetLastError();
goto Cleanup;
}
Cleanup:
// Centralized cleanup for all allocated resources.
if (pAdministratorsGroup)
{
FreeSid(pAdministratorsGroup);
pAdministratorsGroup = NULL;
}
// Throw the error if something failed in the function.
if (ERROR_SUCCESS != dwError)
{
throw dwError;
}
return fIsRunAsAdmin;
}
vb为:
Friend Function IsRunAsAdmin() As Boolean
Dim principal As New WindowsPrincipal(WindowsIdentity.GetCurrent)
Return principal.IsInRole(WindowsBuiltInRole.Administrator)
End Function
c#为:
internal bool IsRunAsAdmin()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
提权的这里懒的贴了,原因有2:
1. 提权的代码必须在vs2008以上才能编译,在2006年11月8日,Windows Vista开发完成并正式进入批量生产后才有该系API,因此无法在vs2005及其以下自带的sdk编译。
2. N种要求高权限的操作,让那框出来,用户点OK都可以实现该功能,照微软的套路通用性比较差。
总之微软这东西做的有点坑爹,麻烦用户还麻烦程序员。
本文地址<http://www.cnblogs.com/yuwei/archive/2011/04/22/2025046.html>,转载请注明出处。