1
4
组件引用
对于MSI文件,是在Windows Installer组件的基础上完成的,而不是基于在注册表中找到的旧SharedDLL ref计数:
共享DDLL :奇怪的是,这个shareddl ref计数器有时也与MSI一起使用,但这只是为了提供与旧版安装程序和部署技术的兼容性-我稍后会澄清。旧式技术使用此SharedDLL计数器作为确定是否可以卸载文件的唯一方法。一旦ref count降至0,就可以删除该文件。 Windows Installer的实际引用计数是基于Windows Installer组件和非共享dll引用计数器完成的 . 这些组件是文件和注册表设置的“原子安装包”。它始终作为一个整体安装或卸载。组件基本上可以包含“任何内容”,但在将要部署到组件集合中的文件和注册表设置分解时,有关于最佳实践的规则。就我个人而言,我总是为每个组件使用一个文件,因为这样可以避免 Windows Installer升级 .
关键路径
:基本上每个组件都有一个“键路径”-单个文件或注册表项/值,用于确定是否安装了组件。MSI的总体概念是
合并模块
:所有试图部署相关文件或组件的安装程序都应使用此组件GUID(用于特定的绝对磁盘或注册表位置)。Window Installer允许此操作的机制称为
“合并模块”
. 这是一个部分MSI数据库,可以在构建时合并到多个MSI文件中-允许在MSI文件之间共享相同的组件,并在所有MSI文件中使用正确的组件GUID,以便可以进行引用计数。
这允许这些共享组件在每次由不同的产品安装时增加ref计数,然后该组件将保留在系统上,直到使用它的产品按顺序卸载时ref计数减少到0为止
. 需要注意的是,如果
GUID :再次重复, 一个绝对路径的一个GUID (一个GUID来管理所有组件)-一个GUID有一个关联的ref计数器,该计数器统计已注册组件的产品数量及其关联的绝对密钥路径,以供使用。因此,作为一个示例,三个产品可能会注册某个组件GUID的使用,使其引用计数为3,从而使其关联的键路径文件或注册表值保持不变,直到所有3个产品都卸载为止。 是否启用共享DDLL? :请注意,对于MSI组件,不一定要启用旧的SharedDLL ref计数器。一些工具,如 只有一句话 ,启用一个标志以递增所有已安装文件的旧共享DLL引用计数器,实际上,您必须为每个组件关闭该标志才能消除此行为。这与其他工具不同,例如 WiX公司 ,这不会默认所有文件的共享dll引用计数器都处于打开状态(我不确定它们启用了哪些文件-如果有的话)。 安装包制作 也不会为所有组件启用SharedDLL ref count标志(由于 Bogdan Mitrache公司 要验证这一点,请参见下面的评论)。
使现代化 :让我们具体谈谈你的具体问题。
请务必阅读此答案,因为它似乎为其他人澄清了一些事情: 是否更改wix中的组件GUID? (与上述建议相同)。 最后,我应该注意到 共享组件 也可以通过以下方式安装 WiX包含文件 -WiX完全引入了一个新概念。这些文件类似于C++中的常规包含文件,只需定义一次,即可在编译时包含在多个WiX源文件中。老实说,我从未使用过它,但从概念上讲,它类似于合并模块,这是一种内置的Windows Installer概念,用于处理共享组件。但有一个重要的区别:合并模块作为一个整体进行版本控制,而WiX include files动态地包含源文件夹中的文件。我觉得这样更好,但这肯定是一个很大的讨论和偏好问题。我不会在这里详细阐述这一点。 如果您使用的是WiX,我建议您尝试使用WiX包含文件来管理共享组件。在我看来,它们似乎是合并模块更灵活的实现。主观上讲,我从来都不是合并模块的狂热粉丝,尽管如果您有许多共享文件要与不同的产品一起安装,那么它们是必不可少的。为什么我不喜欢合并模块?它们似乎是一个额外的复杂性和需要额外维护的二进制blob。实际上,它们相当于一种奇怪的静态链接形式——我们从常规静态链接中了解到的所有问题。这可能太主观了,所以我将就此结束,但对于共享文件和组件,请使用合并模块或WiX包含文件或任何其他结构来实现我不知道的相同效果。 |
2
2
实际上只有少数规则适用,但困难在于它们适用于许多有时很复杂的场景。 如果资源(文件)的组件id ref计数为零,并且: a) 它没有剩余的SharedDLRefCount。 b) 该组件在安装MSI中从未被标记为永久(因为这会使其粘滞且无法关闭)。 c) 组件被设置为可传递,并且发生了一个安装/维护操作,该操作将关联的属性值设置为“false”。同样,这对系统来说是粘性的,而不是项目设置。 d) 尚未将其标记为安装共享的msidbComponentAttributesShared。 可以在组件上设置永久、可传递、组件共享和共享Dll。 如果产品A安装版本1,产品B安装版本2,然后卸载产品B,则版本化的共享文件不会还原为以前的二进制文件。根据定义(实际上并不总是如此),共享文件需要支持较旧的客户端。 在“end”处使用RemoveExistingProducts(REP)进行主要升级期间,升级会对文件应用文件版本控制规则,并增加已安装组件的引用计数(如果组件是新的,则安装引用计数为1的组件)。在这种升级中,组件与旧产品已安装的相同组件ID有效共享。当REP卸载旧产品时,ref计数将减少。 因此,在包含所有相同组件ID的升级的最简单情况下,不会删除任何文件:如果组件ID A、B、C和D在较旧的已安装产品中,并且组件ID A、B、C和D在新的升级中,则会应用文件版本控制规则,并且当REP删除较旧的产品时,减少引用计数会将文件保留在那里,可能版本更高。这就是为什么这种升级或补丁必须遵循组件规则,或者通过重新安装模式=vomus重新安装=ALL进行升级。 如果组件ID A、B、C和D在旧安装的产品中,并且组件ID A、B、C和E在新升级中,则会发生相同的情况,但D将被删除,因为其引用计数现在为零,假设没有其他客户端,并且上述规则不适用。 REP“early”的主要升级在最好的情况下很简单,因为它是先卸载旧产品,然后再安装新产品,因此可以安装旧版本的文件,然后根据上述规则再次删除或不删除文件。在没有其他产品使用的共享文件的最简单情况下,所有组件ID都不需要相同。 常见问题包括将组件设置为永久或共享Dll(仅当文件与非MSI安装共享时才需要)。似乎有这样一种想法,即可以通过进行另一次更改来关闭这些设置,但这些是系统设置,而不是项目设置。 |
EduOak · 如何将WIX捆绑包(EXE文件)强制为特定语言 6 年前 |
Cornelis · 读取延迟自定义操作中的复选框值 6 年前 |
Praveen M · 在WIX中强制终止windows服务 6 年前 |
crocodayl · Wix卸载快捷方式无法完全删除应用 6 年前 |