本文主要是介绍Vista/Win7 UAC兼容程序开发指南,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
转自:http://blog.csdn.net/chenlycly/article/details/28959293?utm_source=tuicool&utm_medium=referral
一、UAC引入
什么是UAC?
UAC的原理是什么?
为什么微软要设计UAC?
UAC对我们开发应用程序有什么影响?
要如何保证一个程序能够在Vista和Win7下运行良好?
你能回答出以上的问题么?如果不能,这篇案例将解答这些问题。
P.S.:与UAC相关的内容很多,本文只是对UAC进行了一个总结,力求让各位通过这一篇文章,对UAC有大致的了解,并知道应该如何修改程序,以适应UAC。
我会尽量在文中标出参考资料的来源,以便大家更深入的探究。
尽管看起来,我们的应用程序似乎在Windows 7上运行良好,但它们真的符合微软对Windows 7兼容程序的要求了么?其实未必。
Windows7和Vista一个很重大的改变就是,加入了用户账户控制(UserAccount Control)功能,简称UAC。
二、UAC简介
什么是UAC?
UAC(User Account Control),中文翻译为用户帐户控制,是微软在WindowsVista和Windows7中引用的新技术,主要功能是进行一些会影响系统安全的操作时,会自动触发UAC,用户确认后才能执行。
更形象的解释就是:在Vista和Windows 7中,不论你是是运行一个安装程序或者打开一个未经验证的程序,甚至复制一个文件到C盘,都会把桌面调暗并锁定,然后弹出一个对话框,让你确认操作的那个令人抓狂的东西。
图1 权限提升确认界面
相信很多人都和我一样,装完Windiows 7后,干的第一件事就是跑去用户账户设置里把UAC关掉,Vista没有流行起来,可能也有UAC的功劳。
既然大家都不喜欢UAC,微软为什么要设计出这样一个东西砸自己的脚呢?
三、为什么微软要设计UAC?
大家都用过Windows XP,我相信绝大多数人在用Windows XP的时候,都使用的是管理员权限的账户。而在微软的设想中,普通用户都应该使用标准账户(乌托邦一般的梦想)。
为什么大家不用标准账户?Windows XP里的标准账户,可能连程序都没法正常安装!没有人愿意为了装个程序,切换到管理员账户,装完了再切换回标准用户。
当然,微软也注意到了这点,于是就设计了UAC系统。UAC与Windows XP的用户账户权限管理,最大的不同在于,UAC对权限的控制很有弹性。它默认所有程序都是以标准权限运行的(无论你使用的是管理员账户还是标准账户),而当你运行一个需要管理员权限的程序时,UAC就会跑出来问你,这个程序需要管理员权限,要不要继续?如果你允许,UAC就会提升权限,用管理员权限运行这个程序。
其实从UAC的设计的本意上来看,它即避免了直接使用管理员账户导致权限控制形同虚设,又解决了标准用户需要频繁切换到管理员账户的问题(感觉是抄袭Linux的su权限提升)。
但是,Vista下的UAC一点都不智能,连复制文件之类的操作,都会跑过来问你一下,很多用户不厌其烦,直接把UAC一关了事。Windows 7的UAC则不同于Vista那个只有开启和关闭两种选项的UAC,Windows 7的UAC可以设置提示级别(有点类似IE的那个隐私设置)。
尽管Windows 7对UAC做了一些改变,但有的时候UAC还是很烦。比如,你第一次打开一个需要管理员权限的程序,UAC会尽忠职守的问你是否要提升权限;你第二次打开,UAC还会尽忠职守的问你是否要提升权限;你第三次打开,UAC还会尽忠职守的问你是否要提升权限……于是你怒了,把UAC一关了之。
用过Android手机的用户都知道,Android里有个信任程序列表,一旦加入这个列表,再次运行的时候,系统就不会做多余的询问了。而UAC则没有这种东西,因为微软的人认为,如果要创建一个信任列表,那这个列表必然会被储存在注册表或者硬盘的某个地方,这样hacker就可以想办法破解并修改这个列表了(就像XP的密码一样)。
Norton出了个小工具,可以建立信任列表:Norton UAC Tool
下载地址: http://www.onlinedown.net/soft/74600.htm
Win7的UAC配置界面
四、UAC的原理是什么?
能够触发UAC的操作包括:
* 修改Windows Update配置;
* 增加或删除用户帐户;
* 改变用户的帐户类型;
* 改变UAC设置;
* 安装ActiveX;
* 安装或卸载程序;
* 安装设备驱动程序;
* 修改和设置家长控制;
* 增加或修改注册表;
* 将文件移动或复制到Program Files或是Windows目录;
* 访问其他用户目录
在Windows 7和Vista下,若开启了UAC,所有程序都默认运行在标准权限下。
除非以下三种情况:
1. 用户手动选择使用管理员权限启动
2. 在程序的manifest文件或者内嵌的manifest信息里加入“level=highestAvaible”或者“level requireAdministrator”安全级别。
3. UAC若检测到程序为安装程序(见下文安装程序检测)。
4. 在可执行文件的属性对话框、兼容性标签页里勾选“以管理员身份启动该程序”复选框,等价于在
HKCU \Software\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags\Layers注册表分支下添加键值,也相当于修改C:\Windows\AppPatch下的sysmain.sdb兼容性数据库。
5. 利用ACT(应用程序兼容性工具)为特定应用程序创建兼容性数据库,以便IT部门可以方便地在企业里部署兼容性设置。
1、访问令牌
UAC对权限的控制,是通过访问令牌来实现的。当用户登录Windows时,系统会同市创建两个访问令牌,其中一个是完全的管理员访问令牌,另一个是经过“过滤”的标准用户访问令牌。当Windows系统启动Shell进程(Explorer.exe)时,LSA(LocalSecurityAuthor)会把标准用户的访问令牌连接到Shell进程。如果某个进程需要管理员权限,则系统会提示权限提升,得到用户亲自确认后,系统会把完全的管理员访问令牌连接到该进程上。
在没有明示的情况下,子进程一般都会继承父进程的访问令牌,而在Windows下,大多数进程都是由Explorer启动的,因此,他们默认都只有标准用户权限。
2、安装程序检测
顾名思义,这个技术提供了对安装程序的识别支持。在UAC环境下,某些传统的安装程序可能无法取得必须的权限执行安装,Windows提供了这样一种技术,使得安装或者升级程序会自动被系统识别,并在运行时自动提示用户以管理员权限运行安装程序。
Installer Detection只作用于32位可执行程序、程序的Manifest内不包含requestedExecutionLevel元素、UAC环境下的以Standard User运行的交互式进程。
当32位进程创建后,会根据以下一些属性判断是否是一个安装程序:
l. 文件名包含关键字:”install”, “setup”,”update”等等。
2. 在版本资源的以下字段内包含关键字:厂商(Vendor)、公司名(CompanyName)、产品名(ProductName)、文件说明(File Description)、初始文件名(Original Filename)、内部文件名(Internal Name)、导出名(Export Name)。
3. 在可执行文件的manifest内包含关键字。
4. 在链接到可执行文件的特定StringTable中包含关键字
5. 链接到可执行文件的资源文件数据包含关键属性。
6. 可执行文件包含特定的字节序列。(这一项应该是识别现在的各种安装包格式的特征)
安装程序识别技术默认打开,并且可以在安全管理器或者组管理器里面修改设置。
3、用户接口权限隔离(UIPI)
用户接口权限隔离主要用来将高特权进程和低特权进程隔离开,防止低权限进程向高权限进程发送消息(SendMessage或PostMessage)、注入DLL、对高权限进程使用线程钩子、或用日志钩子监控高权限进程。详细可以参考《NewUAC Technologies for Windows Vista》一文。
UIPI阻止低权限进程的如下行为:
1. 验证高权限进程的句柄的有效性
2. 调用SendMessage或者PostMessage发送消息到高权限进程。如果这样使用,函数会返回成功,但是发送的消息会被丢弃掉。
3. 使用线程钩子(Threads hooks)附加到高权限进程。
4. 使用日志钩子(Journal hooks)监控高权限进程。
5. 对高权限进程进行dll注入。
在UIPI有效的情况下,进程间的以下资源是可以跨权限访问的:
1. 前台的Desktop window。
2. 桌面堆共享内存
3. 全局的atom table
4. 剪贴板
一些特殊Windows消息是容许的。因为这些消息对进程的安全性没有太大影响。这些Windows消息包括:
0x000 - WM_NULL
0x003 - WM_MOVE
0x005 - WM_SIZE
0x00D - WM_GETTEXT
0x00E - WM_GETTEXTLENGTH
0x033 - WM_GETHOTKEY
0x07F - WM_GETICON
0x305 - WM_RENDERFORMAT
0x308 - WM_DRAWCLIPBOARD
0x30D - WM_CHANGECBCHAIN
0x31A - WM_THEMECHANGED
0x313, 0x31B (WM_???)
4、UAC虚拟化技术(数据重定向)
对于早期开发的程序,可能没有上述信息告知UAC需要管理员权限。为了保证它们能够无需修改便在Vista/Windows 7下正常运行,UAC使用了虚拟化技术(也叫做数据重定向)。
一些早期开发的程序,习惯于将程序的数据及配置文件保存到程序的安装目录(如C:\ProgramFiles\PorgramName\),或者向HKLM/Software注册表下写入信息。此类程序运行在标准用户下时,是没有权限向上述目录和注册表写入信息的。但为何我们在使用这些早期的程序时,并没有看到无法访问目录之类的提示?这全靠UAC的虚拟化技术。
所谓虚拟化技术,就是把标准用户权限下程序对 Windows 目录、 Program Files目录的写入重定向到 %LocalAppData%\VirtualStore\Windows 、%LocalAppData%\VirtualStore\ProgramFiles ;把对 HKEY_LOCAL_MACHINE的写入重定向到HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE 或HKEY_USERS\UserSID_Classes\VirtualStore\Machine 。
比如向C:\Program Files\Kedacom\文件夹下写入的文件,会被自动重定向到
C:\Users\ Username \AppData\Local\VirtualStore\ProgramFiles\Kedacom目录。
这也就是为什么有时,我们在标准用户权限下,用一个早期程序保存了一些文件到ProgramFiles下,没有提示失败,却怎么也找不到这些文件。实际上,它们都被重定向到VirtualStore目录下去了。
UAC的数据重定向是借助一个文件系统的筛选驱动程序(Filter Driver)来实现的,这个驱动的名字是luafv.sys,作为SYSTEM进程的线程在内核模式中加载。
通过微软提供的工具Process Monitor可以监控到重定向的过程,详细的步骤,可以参考相关资料中的《用户帐户控制数据重定向》一文。
注意:由于x64位程序大多在Vista之后设计,因此微软在x64系统中,虚拟化功能默认是禁用的。
五、UAC对我们开发应用程序有什么影响?
尽管似乎很多早期开发的程序无需修改,也能正常运行在Vista或者Windows 7下。但这大多有依赖于UAC的虚拟化技术。而有些程序,在开启UAC的机器下,以标用户准权限运行,根本无法正常工作。
在案例库看到一篇测试写的案例,说某程序在UAC下运行不正常,最后得出的结论竟然是关闭UAC……这对客户来说无疑是极不负责任的一种做法,UAC作为Vista/Windows 7安全系统中重要的一环,对防范病毒、木马等恶意程序起到重要的作用。很多客户,出于安全考虑,都会强制要求开启UAC。
而微软也明确指出:
Virtualization is intended only to assist inapplication compatibility with existing programs. Applications designed forWindows Vista should NOT perform writes to sensitive system areas, nor shouldthey rely on virtualization to provide redress for incorrect applicationbehavior. (虚拟化仅仅是为了保证对已有程序的兼容性。为Vista设计的程序,不应向系统敏感区域写入数据,也不应依赖UAC虚拟化技术矫正错误的行为。)
为了能够让程序兼容Vista/Windows 7,我们需要对程序进行以下修改:
1、更改程序配置、数据文件的保存目录。
在Vista之前,程序喜欢将配置文件等信息保存在程序的安装目录下,如C:\Program Files\Kedacom\XXXX\中,但在Vista中,Program Files目录需要管理员权限才能写入。因此,我们需要更改保存配置、数据文件的目录。
无特殊必要的情况下,不要向Windows、Program Files文件夹下写入文件。
微软推荐以下几个目录:
%ALLUSERSPROFILE% –所有用户的共享程序数据目录。
%LOCALAPPDATA% –Vista之后系统的每用户的程序数据目录(无法漫游)。
%APPDATA% – Vista之后系统的每用户的程序数据目录(可漫游)。
C++下可以通过SHGetKnownFolderPath函数获取上述目录(也可直接使用上述环境变量):
HRESULT SHGetKnownFolderPath(
_In_ REFKNOWNFOLDERID rfid,
_In_ DWORD dwFlags,
_In_opt_ HANDLE hToken,
_Out_ PWSTR *ppszPath
);
Rfid填入要获取的文件夹信息,可用下面三个参数:
FOLDERID_ProgramData– 所有用户的共享程序数据目录。
FOLDERID_LocalAppData– 每用户的程序数据目录(无法漫游)。
FOLDERID_RoamingAppData– 每用户的程序数据目录(可漫游)。
dwFlags一般可填0
hToken为Access Token的Handle,填NULL,则为当前用户
ppszPath为返回的目录的含结束符的字符串,使用完后需调用CoTaskMemFree释放。
这个函数更详细的信息可以查阅:
http://msdn.microsoft.com/en-us/library/bb762188(VS.85).aspx
2、更改程序信息写入注册表的位置
在Vista之前,程序喜欢向HKEY_LOCAL_MACHINE\Software键值下写入程序的配置信息,但在Vista中,HKLM键需要有管理员权限才能写入。因此,推荐将用户配置信息保存到HKEY_CURRENT_USERS键值下。当然,安装程序因为默认以管理员权限启动,所以仍可以写入HKLM。
3、为程序加入manifest文件
Manifest用于告知操作系统程序的信息,包括运行权限,运行环境,界面风格等。
通过manifest,我们可以让程序在启动的时候自动提升权限。
将下面的内容保存为 YourProgramName .manifest,加入到资源文件中,并保证资源ID为1。
<?xmlversion="1.0" encoding="UTF-8"standalone="yes"?>
<assemblyxmlns="urn:schemas-microsoft-com:asm.v1"manifestVersion="1.0">
<assemblyIdentityversion="1.0.0.0"
processorArchitecture="X86"
name="IsUserAdmin"
type="win32"/>
<description>Description of yourapplication</description>
<!-- Identify the application securityrequirements. -->
<trustInfoxmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
通过修改requestedExecutionLevel一行的level属性,可以声明程序所需的权限。
<requestedExecutionLevel
level="asInvoker|highestAvailable|requireAdministrator"
uiAccess="true|false"/>
asInvoker表示与调用者相同,highestAvailable代表可获取的最高权限requireAdministrator代表管理员权限。
除非程序的确需要在管理员权限下运行,否则一般不推荐设置为highestAvailable和requireAdministrator,因为一旦设置了这两个属性,每次运行程序时,都会弹出权限提升请求对话框,还是很烦人的。
注意:对于没有manifest的32位程序,Windows将自动默认虚拟化,而含有manifest的程序,虚拟化是默认禁用的。
4、动态提升程序权限
尽管我们可以在程序运行前,就设定程序的运行权限,但大多数时候,我们的程序仅需标准用户权限,只有在执行特定操作的时候,才需要管理员权限。
那么有没有什么方法可以动态提升程序权限呢?
方法有两个:
1. 通过ShellExecuteEx函数创建一个高权限进程。
首先要明确一点,一个进程是无法提升自己的权限的,但是他可以创建一个管理员权限进程。
BOOLShellExecuteEx(
_Inout_ SHELLEXECUTEINFO *pExecInfo
);
typedefstruct _SHELLEXECUTEINFO {
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCTSTR lpVerb;
LPCTSTR lpFile;
LPCTSTR lpParameters;
LPCTSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
LPVOID lpIDList;
LPCTSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
union {
HANDLE hIcon;
HANDLE hMonitor;
} DUMMYUNIONNAME;
HANDLE hProcess;
}SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
对于这个函数在此不多做说明,大家可以查询MSDN获取详细用法。
提升权限的关键在于lpVerb,填入”runas”,即可让这个进程以管理员权限运行(进程启动时会弹出对话框要求用户确认提升权限)。
典型的用法:
SHELLEXECUTEINFOShExecInfo ={0};
ShExecInfo.cbSize= sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask= SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd= NULL;
ShExecInfo.lpVerb= "runas";
ShExecInfo.lpFile= "C:\XXXX.exe";
ShExecInfo.lpParameters= "";
ShExecInfo.lpDirectory= NULL;
ShExecInfo.nShow= SW_SHOW;
ShExecInfo.hInstApp= NULL;
ShellExecuteEx(&ShExecInfo);
一般有两种设计方法:
一种是,将所有需要管理员权限的操作都写到另外一个程序里,通过主程序调用的方法实现。
另外一种是,以标准用户权限启动程序,再通过ShellExecuteEx启动一个管理员权限的自己。
Windows Vista/7下的任务管理器就是个典型的动态提升权限的例子。
点击“显示所有用户的进程“后,任务管理器会短暂的消失,再次出现时,就已经是管理员权限了。它采用的,其实是第二种方法,通过标准用户权限的任务管理器,启动了一个管理员权限的任务管理器。
2. 使用CoCreateInstance函数,创建一个管理员权限的COM对象,由这个COM对象,执行需要管理员权限的操作。
COM类必须在注册表中必须有权限提升支持标示,不论你的COM是DLL还是EXE,都必须得有AppID,格式如下:
a. HKEY_CLASSES_ROOT\CLSID\{CLSID}\Elevation\Enabled = 1
b. HKEY_CLASSES_ROOT\CLSID\{CLSID}\LocalizedString =displayname
说明:Enabled为DWORD值,displayname为弹出的UAC中提示的文字。
displayname格式为: @com程序路径,-num (num是程序中string资源)
使用权限提升COM类的客户端程序必须以CoCreateInstanceAsAdmin调用方式来创建COM类。
这里有详细的说明:
http://msdn.microsoft.com/en-us/library/ms679687.aspx
下面是个典型的例子:
HRESULT CoCreateInstanceAsAdmin(HWND hwnd,REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
BIND_OPTS3bo;
WCHAR wszCLSID[50];
WCHAR wszMonikerName[300];
StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));
HRESULT hr = StringCchPrintf(wszMonikerName,sizeof(wszMonikerName)/sizeof(wszMonikerName[0]),L"Elevation:Administrator!new:%s", wszCLSID);
if(FAILED(hr))
return hr;
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hwnd;
bo.dwClassContext =CLSCTX_LOCAL_SERVER;
returnCoGetObject(wszMonikerName, &bo, riid, ppv);
}
5、通过ACL检测是否有权限读写文件\文件夹
在开启了虚拟化机制后,标准用户权限程序写入Windows、Program Files目录的时候,并不会返回写入错误,而是直接重定向到虚拟目录。
为了解决这个问题,可以采用两种办法:
1.为程序增加manifest文件,禁用虚拟化,这样一来,写入无权限目录时,就会正确返回错误提示了。
2.使用NTFS的ACL(Access Control List)判断当前进程对该目录是否有访问权限。
原理是通过获取文件的进程的Token并文件/文件夹的权限信息进行比较来判断是否可以读写该文件/文件夹。
代码如下:
BOOL32 CanAccessFile(CString strPath, DWORD dwGenericAccessMask )
{
DWORD dwSize;
BOOL32 bRtn;
PSECURITY_DESCRIPTOR psd = NULL;
SECURITY_INFORMATION si =OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION;
// 获取文件权限信息结构体大小
bRtn = GetFileSecurity( strPath, si, psd, 0,&dwSize );
if ( bRtn || GetLastError() !=ERROR_INSUFFICIENT_BUFFER )
{
return FALSE;
}
char* pBuf = new char[dwSize];
psd = (PSECURITY_DESCRIPTOR)pBuf;
// 获取文件权限信息结构体大小
bRtn = GetFileSecurity( strPath, si, psd,dwSize, &dwSize );
if ( !bRtn )
{
return FALSE;
}
HANDLE hToken = NULL;
if ( !OpenProcessToken( GetCurrentProcess(),TOKEN_ALL_ACCESS, &hToken ) )
{
return FALSE;
}
HANDLE hImpersonatedToken = NULL;
if( !DuplicateToken( hToken,SecurityImpersonation, &hImpersonatedToken ))
//模拟令牌
{
return FALSE;
}
GENERIC_MAPPING genMap ;
PRIVILEGE_SET privileges = {0};
DWORD grantAccess = 0;
DWORD privLength = sizeof(privileges);
BOOL bGrantAccess = FALSE;
//将通用权限控制标志和特定类型对象权限控制标志挂钩
genMap.GenericRead = FILE_GENERIC_READ;
genMap.GenericWrite = FILE_GENERIC_WRITE;
genMap.GenericExecute = FILE_GENERIC_EXECUTE;
genMap.GenericAll = FILE_ALL_ACCESS;
MapGenericMask(&dwGenericAccessMask,&genMap);
//映射通用权限控制标志
if(AccessCheck(psd,hImpersonatedToken,
dwGenericAccessMask,
&genMap,&privileges,&privLength,&grantAccess,&bGrantAccess))
{
return bGrantAccess;
}
return FALSE;
}
6、修复UIPI问题
基于Windows Vista之前的操作系统行为所设计的应用程序,可能希望Windows消息能够在进程之间自由的传递,以完成一些特殊的工作。当这些应用程序在 Windows 7上运行时,因为UIPI机制,这种消息传递被阻断了,应用程序就会遇到兼容性问题。为了解决这个问题,Windows Vista引入了一个新的API函数ChangeWindowMessageFilter。利用这个函数,我们可以添加或者删除能够通过特权等级隔离的 Windows消息。这就像拥有较高特权等级的进程,设置了一个过滤器,允许通过的Windows消息都被添加到这个过滤器的白名单,只有在这个白名单上的消息才允许传递进来。
如果我们想容许一个消息可以发送给较高特权等级的进程,我们可以在较高特权等级的进程中调用ChangeWindowMessageFilter函数,以 MSGFLT_ADD作为参数将消息添加进消息过滤器的白名单。同样的,我们也可以以MSGFLT_REMOVE作为参数将这个消息从白名单中删除。
typedef BOOL (WINAPI*_ChangeWindowMessageFilter)( UINT , DWORD);
BOOLCVistaMsgRecvApp::AllowMeesageForVista(UINT uMessageID, BOOL bAllow)//注册Vista全局消息
{
BOOLbResult = FALSE;
HMODULEhUserMod = NULL;
//vistaand later
hUserMod= LoadLibrary( L"user32.dll" );
if( NULL== hUserMod )
{
return FALSE;
}
_ChangeWindowMessageFilterpChangeWindowMessageFilter = (_ChangeWindowMessageFilter)GetProcAddress(hUserMod, "ChangeWindowMessageFilter" );
if( NULL== pChangeWindowMessageFilter )
{
AfxMessageBox(_T("createwindowmessage filter failed"));
returnFALSE;
}
bResult= pChangeWindowMessageFilter( uMessageID, bAllow ?1 : 2 );//MSGFLT_ADD: 1,MSGFLT_REMOVE: 2
if( NULL!= hUserMod )
{
FreeLibrary(hUserMod );
}
returnbResult;
}
六、UAC对我们开发应用程序有什么影响?
UAC作为Windows Vista/7下重要的安全机制,我们不能一关了之,而应该按照微软的要求,对程序进行适当的修改,以更好地适应新的操作系统和安全机制。
由于时间、篇幅和精力所限,文章中可能存在错误和疏漏,很多东西也没法更充分的展开。这篇文章的主要目的,是希望大家对UAC能有一个基本的认识,并给出一些修改程序以兼容UAC的方法。
MSDN和互联网上都有相当多的资料,下面给出几个较为详细的:
标题:Designing UAC Applications forWindows Vista
链接: http://msdn.microsoft.com/en-us/library/bb756973.aspx
中文: http://msdn.microsoft.com/zh-cn/library/aa905330.aspx
说明:微软官方文档,详细介绍了如何判断一个程序是否兼容UAC,如何开发一个兼容UAC的程序。
标题:用户帐户控制数据重定向
链接: http://technet.microsoft.com/zh-cn/ee781806.aspx
说明:微软官方文档,详细介绍了UAC的虚拟化(数据重定向)功能。
标题:New UAC Technologies for Windows Vista
链接: http://msdn.microsoft.com/zh-cn/library/bb756960.aspx
非官方译文: http://msdn.microsoft.com/zh-cn/library/aa905330.aspx
说明:微软官方文档,介绍了UAC的原理和机制
这篇关于Vista/Win7 UAC兼容程序开发指南的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!