- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要使用在Installshield 2012中使用Patch Design创建的一系列可卸载补丁。卸载时,前两个补丁可以正常工作。但是,如果并且仅当已经应用补丁1和/或补丁2时才将其卸载,第三个补丁会产生错误:
MSI (c) (48:C4) [19:02:54:135]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg
Error 1308.Source file not found: {pathToFile}. Verify that the file exists and that you can access it.
%windir%Installer\$PatchCache$\Managed\{PackedProductCodeOfMyBaseMSI??}
上
最佳答案
我仍在寻找解决方案或至少一些指导,甚至
尽管我同意这超出正常的良好做法。 –杰克
1小时前
我没有访问部署工具的权限,但是我将尝试提供一个视角。由于我没有完全掌握您所写内容的所有方面,因此将使用通用注释。我希望它至少与您的要求有关。如我所写,它变成了一个博客。
对我来说,MSI补丁对2种基本情况有效:
您使用次要升级补丁修复了已安装产品的卸载顺序中的错误。
您为发行的产品提供了几个文件的次要升级补丁作为“修补程序”,重新安装可能非常庞大且耗时。
出于这两个目的,我已经在专业上有效地多次使用了MSI修补程序。在每种情况下,都没有其他好的解决方法。修补恕我直言是为了“修补程序”-这是整个技术的目的,而不是用于频繁的增量更新的部署。不能提供96个文件更新。
补丁程序是可行的升级:请记住,补丁程序只是用于已经生效的升级的更紧凑的交付机制。它可以是主要更新,次要更新甚至是很小的更新,每个更新的工作方式都不同。在进行其他任何操作之前,请确保先测试了实际的完整升级MSI,然后再尝试将其打包为补丁程序。这是我能给您的最佳建议。如果完整升级无法正常工作,则浪费了所有修补工作。是的,这包括在制作补丁程序之前进行所有交互的安装,卸载和升级。这也许是最常见的修补错误。
存在一些阻碍卸载补丁程序的障碍。 There are dozens of technical issues that may result in uninstallable patches(建议阅读)。有时这是一个巨大的问题,因为已发现部署了修补程序的补丁有缺陷,因此应将其完全撤回。在我看来,这是一个小补丁的核心用途之一-部署一个快速修复程序,然后可以将其回滚。
修补程序和自定义操作条件:对我而言,修补程序最糟糕的方面之一是,与正常安装相反,在执行修补程序操作时,可能无法将软件包中的自定义操作适当地设置为不运行。修补程序具有修补程序特定的属性,例如PATCH和MSIPATCHREMOVE。在自定义操作上使用这些条件,以使其在补丁程序期间运行或不运行,具体取决于必要的条件。注意自定义操作的条件,这些条件很难正确处理。这是一个“ MSI Conditions Cheat Sheet”可以帮助您。我尚未测试这些条件-测试是唯一的保证。
一些进一步的修补建议:
我会完全忘记主要的升级补丁。我已经尝试过,并且会再次尝试,但是它们往往不理想。要运行主要升级补丁的绝对要求是,在InstallExecuteSequence中的InstallFinalize之后放置RemoveExistingProducts。这样做的原因是,否则在修补程序包尝试修补现有文件之前会先卸载文件。赶上22。
次要升级不会卸载现有安装,但是评估程序会重新缓存新的MSI文件以用于维护和卸载操作。这意味着该补丁可以在运行之前修复卸载顺序-我上面列出的一种很好的补丁使用。实际上,如果次要升级有效,则根本不需要补丁。除非您的MSI文件很大并且您想提供一个小的“修补程序”,否则请使用较小的升级。
如果您需要在补丁中包含文件,建议您启用“包括整个文件”。否则,将完成位级别的修补,这是不必要的复杂性(除非您的二进制文件很大)。我也不确定位级补丁如何与签名文件和数字签名一起工作。
在补丁程序中仅包含您需要的内容。不添加不需要的文件或设置,就可以制作可靠的补丁程序。尽可能避免添加自定义操作。
如前所述:请注意,补丁程序与常规安装使用相同的InstallExecuteSequence,但是您可以使用补丁程序特定的属性(例如PATCH和MSIPATCHREMOVE)以不同的方式调整自定义操作的条件。在自定义操作上使用这些条件,以使其在补丁程序期间运行或不运行,具体取决于必要的条件。
组件引用对于任何类型的修补程序而言都必须100%正确。没有例外。
除非通过setup.exe / update.exe交付,否则必须使用正确的msiexec.exe命令行运行次要升级补丁。
根据我的经验,第三方合并模块经常会导致修补问题。
他们称其为“版本说谎”-通过在MSI文件中为磁盘上的文件添加不同的版本来确保始终更新文件的技巧似乎会导致修补错误。
修补程序将显示与主要安装相同的GUI。我认为这是错误的设计。 GUI中的自定义操作可能会打乱修补过程(您是否应该接受新的用户输入以获取修补程序的值?)。
我相信每个补丁都应该是累积性的-替换所有以前的补丁。当我测试按顺序安装的几个补丁时,我再也无法正常工作了。由于许多原因,我得出的结论是,这首先是徒劳的修补方法。我在按照补丁系列,目标发行版等描述的过程中确实遇到了问题。补丁不是太聪明,它只是一些文件的复杂组合,试图找到它所属的产品。
显而易见,我确实不建议您使用这种修补方法,即使在被要求时也是如此。但是,我读了this thread,这似乎表明已成功转换为使用WIX而不是Installshield的用户进行了修补。您也应该查看CodeProject链接。
关于您的部署方案-我没有完全掌握它的所有方面,但是听起来像开发人员想要补丁程序通过补丁程序将实时应用程序转换为当前的质量检查版本?我永远不会同意这一点,否则情况必须与听起来不同。当您必须首先交付较小或较大的升级时,就完全浪费了创建补丁的精力-它们足以交付用于QA的软件。您可以使用dev分支来交付单独的MSI,然后不时创建一些补丁,然后测试该产品是否可补丁,但是我绝不会使用补丁在内部交付产品的安装程序。我不知道这是否是您要执行的操作。
进行次要和主要升级-对于非补丁,最好是后者,并在真正需要时提供补丁。如果安装持续时间有问题,您可以安排在所有开发人员和QA PC上完成夜间构建后进行每日一次重大升级吗? (包括杀死使安装正常进行所需的所有正在运行的进程)。我不知道我是否完全偏离了您的实际情况。
查看Stefan Kruger的installsite.org了解更多升级和补丁提示。
查看this well known wix tutorial以获得升级和补丁。还有MSDN。
关于windows-installer - Windows Installer“错误1308。找不到源文件”在按顺序方案中卸载修补程序时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23439074/
我应该编写一个函数来打印一组给定的三个数字中两个较大数字的平方和。 我对这种情况的处理相当笨拙。我没有编写返回一组 3 中最大的两个数字的函数,而是编写了函数,以便表达式减少到两个所需的数字。 # S
如果有人可以提供帮助,我将不胜感激。我一直在敲我的头一天试图让这个工作。我已经在互联网上搜索并重新阅读了手册,但我就是不明白。 guile << __EOF__ ( define heading-li
目前我正在处理一个方案问题,其中我们正在使用方案列表表示一个图。我们使用的第一个变体是表示为 的边列表图 '((x y) (y z) (x z)) 我们正在使用的图的第二个变体被称为 x 图,表示为
我正在尝试创建一个函数,该函数将两个函数作为参数并执行它们。 我尝试使用 cond ,但它只执行 action1 . (define seq-action (lambda (action1 act
我提前为我的原始英语道歉;我会尽量避免语法错误等。 两周前,我决定更新我对 Scheme(及其启示)的知识,同时实现我在手上获得的一些数学 Material ,特别是我注册的自动机理论和计算类(cla
Scheme中有没有函数支持分数的“div”操作? 意思是 - 11 格 2.75 = 4。 最佳答案 我认为你的问题的答案是:没有,但你可以定义它: #lang racket (define (di
我在scheme中实现合并排序,我必须通过定义两个辅助方法来实现:merge和split。 Merge 需要两个列表(已经按递增顺序)并将它们合并在一起。我这样做了如下: (define merge
尝试从终端加载方案文件。我创建了一个名为 test.scm 的文件,其中包含以下代码: (define (square x) (* x x)) (define (sum-of-squares x y)
我有以下代码: (define (howMany list) (if (null? list) 0 (+ 1 (howMany (cdr list))))) 如果我们执行以
我有点了解如何将基本函数(例如算术)转换为Scheme中的连续传递样式。 但如果函数涉及递归怎么办?例如, (define funname (lambda (arg0 arg1)
我正在尝试附加两个字符串列表 但我不知道如何在两个单词之间添加空格。 (define (string-concat lst1 lst2) (map string-append lst1
这个问题已经有答案了: How do I pass a list as a list of arguments in racket? (2 个回答) 已关闭 8 年前。 我有一个函数,它需要无限数量的
我对这段代码的工作方式感到困惑: (define m (list 1 2 3 '(5 8))) (let ((l (cdr m))) (set! l '(28 88))) ==>(1 2 3 (5 8
我正在为学校做一项计划作业,有一个问题涉及我们定义记录“类型”(作为列表实现)(代表音乐记录)。 我遇到的问题是我被要求创建一个过程来创建这些记录的列表,然后创建一个将记录添加到该列表的函数。这很简单
我有以下代码: (define (howMany list) (if (null? list) 0 (+ 1 (howMany (cdr list))))) 如果我们执行以
我正在尝试附加两个字符串列表 但我不知道如何在两个单词之间添加空格。 (define (string-concat lst1 lst2) (map string-append lst1
如何使用抽象列表函数(foldr、foldl、map 和 filter 编写函数),无需递归,消耗数字列表 (list a1 a2 a3 ...) 并产生交替和 a1 - a2 + a3 ...? 最
我试图找出在 Scheme 中发生的一些有趣的事情: (define last-pair (lambda (x) (if (null? (cdr x))
这个问题在这里已经有了答案: Count occurrence of element in a list in Scheme? (4 个答案) 关闭 8 年前。 我想实现一个函数来计算列表中元素出现
我正在尝试使用下面的代码获取方案中的导数。谁能告诉我哪里出错了?我已经尝试了一段时间了。 (define d3 (λ (e) (cond ((number? e) 0) ((e
我是一名优秀的程序员,十分优秀!