Vista/Win7 UAC兼容程序开发指南

2024-03-12 02:08

本文主要是介绍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兼容程序开发指南的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/799818

相关文章

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

Spring Boot结成MyBatis-Plus最全配置指南

《SpringBoot结成MyBatis-Plus最全配置指南》本文主要介绍了SpringBoot结成MyBatis-Plus最全配置指南,包括依赖引入、配置数据源、Mapper扫描、基本CRUD操... 目录前言详细操作一.创建项目并引入相关依赖二.配置数据源信息三.编写相关代码查zsRArly询数据库数

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

JavaScript错误处理避坑指南

《JavaScript错误处理避坑指南》JavaScript错误处理是编程过程中不可避免的部分,它涉及到识别、捕获和响应代码运行时可能出现的问题,本文将详细给大家介绍一下JavaScript错误处理的... 目录一、错误类型:三大“杀手”与应对策略1. 语法错误(SyntaxError)2. 运行时错误(R

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详

MySQL中慢SQL优化方法的完整指南

《MySQL中慢SQL优化方法的完整指南》当数据库响应时间超过500ms时,系统将面临三大灾难链式反应,所以本文将为大家介绍一下MySQL中慢SQL优化的常用方法,有需要的小伙伴可以了解下... 目录一、慢SQL的致命影响二、精准定位问题SQL1. 启用慢查询日志2. 诊断黄金三件套三、六大核心优化方案方案

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解