4

从 Windows Vista 开始,Microsoft 添加了一类兼容性填充程序,允许假定它具有管理文件注册表访问权限的应用程序继续运行。

换句话说:在Windows XP上失败的应用程序将在Windows Vista上运行。

这些操作系统提供的错误修复可以通过在应用程序清单中添加一个部分来禁用,声明应用程序应该运行asInvoker

<!-- Disable Windows Vista standard user compatability heuristics -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
   <security>
      <requestedPrivileges>
         <requestedExecutionLevel level="asInvoker"/>
      </requestedPrivileges>
   </security>
</trustInfo>

理想情况下,开发人员会测试他们的应用程序以确保它不(不必要地)需要管理权限。为了让我对此进行测试,我需要将其显示为Invoker

但归根结底,我不会将应用程序发布给客户,表现为Invoker如果我确实错过了什么,我不希望用户受到影响。我希望微软的操作系统来修正我的错误。此解决方案的问题是:

  • 我必须在发布前修改 manfiest
  • 我永远不会知道我错过的东西,因为它们只是在 Windows Vista 上工作。

类似的难题出现在Windows 7 的supportedOS清单中。您可以将清单添加到应用程序,指示您设计和测试的 Windows 版本:

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
   <application> 
      <!--The ID below indicates application support for Windows Vista -->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
      <!--The ID below indicates application support for Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
   </application> 
</compatibility>

受支持的操作系统项目的情况下,操作系统预先知道您是为哪个操作系统设计的。如果您不说您支持 Windows 7,这会将您的应用程序置于 Windows Vista 的上下文中:

替代文字
(来源:msdn.com

此操作类似于在某些兼容模式下运行应用程序,例如:

  • Windows Server 2008(服务包 1)
  • Windows Vista(服务包 2)
  • Windows Vista(服务包 1)
  • 视窗
  • Windows Server 2003(服务包 1)
  • Windows XP(服务包 2)
  • 视窗 2000
  • Windows NT 4.0(服务包 5)
  • 视窗 98 / 视窗我
  • 视窗 95

您将在其中应用兼容 shims 的 schmorgasboard,Windows 将模拟旧的未记录行为,以帮助您的应用程序在依赖于该未记录行为时崩溃。

Windows 7 将为在Windows Vista上下文中运行的应用程序提供的兼容性填充程序示例:

  • RPC 将使用旧的私有线程池,而不是 OS 线程池
  • 您将能够锁定主视频桌面显示缓冲区
  • 您将能够在不指定剪辑窗口的情况下Blit到主桌面视频缓冲区
  • 您将容易受到 GetOverlappedResult 竞争条件的影响(如果您依赖它)
  • 您将继续获得程序兼容性助手 (PCA) 缓解

再一次,为了在Windows 7下正确测试我的应用程序,我必须添加supportOS清单条目。但是,再一次,我不会用那个标志来发布应用程序,因为我不想失去这些 shims 的好处(例如 PCA)。再说一次,如果某个应用程序由于在Vista环境中运行而出现了已修复的问题:我永远不会从我们的客户那里知道这件事——因为该应用程序正在运行。


想法?指导?最佳实践?

4

3 回答 3

2

我不会将应用程序发布给显示为 Invoker 的客户。如果我确实错过了什么,我不希望用户受到影响。

我认为这是一个不好的方法。我的建议是从一开始就正确体现并测试您部署的内容。

微软不会为了每个人的兼容性而向后弯腰。他们将针对最大的供应商所犯的最常见、影响最大的错误。如果您错过了一些小问题,那么他们将来提供 shim 的机会就很小。

每次微软添加兼容性垫片时,我们都付出了代价。有些 API 无法按应有的方式工作,因为它们必须以脑残的方式处理某些情况,以实现与其他人的错误的兼容性。这意味着漫长而痛苦的调试会话,这意味着要阅读更长(或更不完整)的文档,这意味着每个人的操作系统几乎没有效率低下。这也意味着 Windows 开发人员正在浪费时间修复其他人的错误,而不是改进操作系统。

有时,这些兼容性更改是惩罚做对的开发人员的大锤。许多应用程序不能正确处理高 DPI,因此——以兼容性的名义——Vista 假定没有应用程序正确处理它(除非它们明确声明另有说明)。Vista 应用 UI 缩放。不处理高 DPI 的应用程序得到了改进(但次优)的结果。处理high_DPI的应用程序会得到降级的结果。(而使用好应用程序的客户在升级到 Vista 时会发现它们变得更糟,并责怪微软。)没有缴纳税款的开发人员得到了微软的帮助,而我们其他人(包括微软)则受到了惩罚。避免这种情况的唯一方法是每个人都缴纳税款。

总的来说,微软在使这些兼容性垫片更有针对性方面做得越来越好(尽管 Vista 相当生硬)。然而,每个人都有一点成本。

在开发过程中遵循最佳实践。测试您计划部署的内容。如果它坏了,微软可能会为你修复它。否则,您可能必须发布更新。这比每个人都受到惩罚要好,因为一些开发人员没有做正确的事情。

于 2009-11-12T17:02:57.497 回答
1

AsInvoker 是分发应用程序的正确方法!!!

所有这一切都是使用用户的凭据运行的。它没有说“偷偷摸摸”或“使用管理员权限”。

如果没有该清单,您会将您的应用程序标记为“我不知道 UAC,所以请提供您需要的任何技巧,以使我仍然可以在任何具有 UAC 的系统上运行”

但是,如果您的应用程序不尝试仅执行管理员操作-并且您可以通过简单地以标准用户身份登录然后运行您的应用程序并观察故障来轻松地进行测试-那么 AsInvoker 是绝对正确的。

这可能会帮助您处理它:程序员对 Vista 的用户帐户控制的探索

于 2009-12-01T21:14:07.050 回答
0

据我了解,除了在您的发行版中提供清单文件之外,还可以通过将以下命令添加到您的应用程序的资源文件中,将它直接链接到您的 EXE 文件中:[1,2]。

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourApp.exe.manifest"

包含 EXE 文件的目录中的单独清单文件可以覆盖此链接清单,但这取决于客户。你不会提供它。

现在,来自 Microsoft 的“RC”资源编译器接受预处理器指令,例如 #ifdef [3]。这意味着,您可以指示您的 Visual Studio 有两个单独的构建目标,定义不同的预处理器定义,例如 TESTING 和 DEPLOYMENT。

然后,只需使用#ifdef 指令为您的测试和部署构建目标使用两个不同的清单文件,您可以根据需要编辑清单文件。这会解决你的问题吗?

[1] http://msdn.microsoft.com/en-us/library/ms997646.aspx
[2] http://doc.ddart.net/xmlsdk/htm/sdk_dependencies_5wvi.htm
[3] http://msdn .microsoft.com/en-us/library/aa381033%28VS.85%29.aspx

于 2009-11-11T18:23:16.403 回答