Windows Installer 常见问题

常见问题
问: Windows Installer是一种什么样的产品?
答: Windows Installer是一种系统服务,用来安装和管理系统中的应用程序。它为应用程序的开发、定制、安装和升级提供了一种标准化的方法和手段。
 
问: Windows Installer都提供了哪些基本功能?
答: WindowsInstaller提供了以下基本功能:

? 事务型操作:所有的安装操作都是事务形式的。对于WindowsInstaller执行的每项操作,它都会产生一个对应的撤销(Undo)操作,以便在需要时撤销用户对系统所做的修改。如果在安装过程中发生了一个错误,WindowsInstaller可以将系统还原回进行安装前的状态。
 
? 自我治愈:WindowsInstaller支持应用程序的“自我治愈”能力。应用程序可以在启动时检查各种常见的安全问题,例如文件或注册表键丢失问题,并且可以自动修复自己。
 
? 按需安装:WindowsInstaller支持应用程序的按需安装。例如,MicrosoftOfficeWord的拼写检查功能在默认情况下不会被安装,但是用户也可以根据需要安装该功能。
 
? 在“锁定”环境下的安装:在全面锁定的环境中,用户一般没有安装应用程序所需的权限或能力。在大多数情况中,他们没有对计算机“ProgramFiles”文件夹或者HKEY_LOCAL_MACHINE注册表位置的“写”权限。例如,如果管理员通过组策略允许用户安装某个程序包,WindowsInstaller便可以代表用户进行程序的安装。
 
? 状态管理:WindowsInstaller为应用程序提供了一组标准的Win32?应用程序编程接口(API)和自动化接口,管理员可以使用它们查询程序在计算机中的安装状态。API能够查询程序的当前状态,校验现有状态,或者修复受损的状态,并且能够从一种状态过渡到另一种状态。
 
 
问: Windows Installer V2.0是该产品的最新版本。2.0版本提供了哪些新增功能和改进功能?
答: 同先前版本相比,2.0版本的WindowsInstaller包括了大量的新增特性和改进特性,例如:

? 组件的安装和管理:WindowsInstaller2.0与SxS(Fusion)和CommonLanguageRuntime(CLR)组件完全集成。.
 
? 更高的安全性:WindowsInstaller的体系结构经过修改,具有更高的安全性。
 
? 隐藏个人信息的能力:WindowsInstaller为作者提供了一种在日志文件中隐藏信息(例如口令)的方法。
 
? 多个用户间的隔离:对WindowsInstaller架构所做的修改实现了每个用户安装的真正隔离,因为每个用户对产品进行的配置不再在多个用户间进行共享。
 
? 对数字签名的支持:数字签名支持已经包括在有关WindowsInstaller的文件之中,例如软件包(.msi)、补丁(.msp)和转换(.mst)。WindowsInstaller还能够对与安装有关的外部.cab文件进行数字签名验证。
 
? 更健壮的补丁:2.0版本修正了众多的补丁问题。
 
? 简化了补丁的制作过程:在2.0版本中,补丁冲突问题的圆满解决消除了用户在制作补丁过程中的一些负担。针对2.0版本开发安装程序的制作人员不再需要跟踪每一个磁盘ID和先前补丁使用的最后一个序列号。
 
? 改进了补丁和升级文件的安装过程:2.0版本减少了不必要的源程序解析尝试。在大多数情况下,当应用某个补丁的时候,用户不再被要求访问原始程序的位置,除非补丁和升级文件的制作者特别强调这一点。此外,由于无需复制那些和版本变化无关的文件,升级过程的效率也提高了。
 
? 支持转化和来自URL源的补丁:WindowsInstaller的2.0版本现在允许使用转化和来自URL(统一资源定位符)的补丁。
 
? 操作系统特性的增强:与系统还原和软件限制策略(Windows?XP的功能特性)集成在一起,并且改善了对终端服务的支持。
 
? 64位Windows上的64位服务:WindowsInstaller是一个天生的64位服务,能够64位版本的Windows上安装64位的应用程序。
 
? 得到增强的日志记录能力:事件的日志记录已经得到了极大的改进,以便帮助技术人员解决安装过程中出现的问题。这包括确保每一个不同的错误都拥有一个独一无二的事件ID。
 
? 可配置的合并模块:经过改进的MergeMod.dll允许用户制作合并模块(.msm文件),这些文件包含一些属性,能够由合并模块的使用者加以配置。
 
 
问: 我可以从哪里获得有关Windows Installer的更多信息?
答: 有关WindowsInstaller的更多信息可以在WindowsInstaller软件开发工具包(SDK)中找到。

有关WindowsInstaller的进一步信息还可以通过以下白皮书获得:
 
问:
答: 

可用性
问: 哪些版本的Windows包括了Windows Installer?
答: Microsoft Windows 2000、Windows Millennium Edition(Windows Me)以及Windows XP 包括了Windows Installer。Windows 2000包括了1.1版本的Windows Installer,Windows Me 包括的是1.2版本,而Windows XP包括的Windows Installer则为2.0版本。Windows 2000 SP3 也包含了2.0版本的Windows Installer。
 
问: Windows Installer支持哪些操作系统?
答: 下表详细介绍了每个版本的Windows Installer所支持的操作系统。
 
问: 我可以从何处获得最新版本的Windows Installer再分发程序?
答: 您可以通过Microsoft Platform SDK Redistributables站点获得最新版本的Windows Installer再分发程序,Windows Installer的再分发程序有两个不同的版本:一个适用于Windows 95、Windows 98和Windows Me;另一个适用于Windows NT和Windows 2000。
 
问: 我需要在我的安装程序中再次分发这些技术,我可以从哪里获得针对Microsoft技术的合并模块?
答: Microsoft合并模块随同Microsoft Visual Studio .NET一同提供。它们的默认安装位置为 [ProgramFilesFolder]/Common Files/Merge Modules。请注意:并不是所有的Microsoft再分发组件都有可用的合并模块。
 
问:
答: 

教学指导
问: 我应该怎样在“添加或删除程序”中隐藏某个应用此程序?
答: 为了在“添加或删除程序”中隐藏某个应用程序,请将ARPSYSTEMCOMPONENT属性设置为1。该属性可以在命令行、在程序包的“属性”表中设置,或者通过转换进行设置。在Windows 2000以前的操作系统上,可以通过将ARPNOREMOVE属性设置为1 来在“添加或删除程序”中隐藏应用程序。在Windows 2000和Windows XP操作系统中, ARNOREMOVE可以禁用“添加或删除程序”中的“删除”按钮。
 
问: 在Orca中对我的.msi程序包进行多次编辑之后,程序包的体积显著增加了。我应该怎样减小.msi文件的大小呢?
答: .msi程序包的数据库格式是建立在OLE结构化存储基础上的。频繁对数据库进行编辑回导致碎片的出现,并因此浪费一些空间。您可以通过在Orca中使用“另存为”命令减小.msi程序包的大小。或者,您也可以使用msidb.exe导出所有表,然后再将这些表重新导入到一个新建的数据库中,以便减小程序包的体积大小。

Orca和msidb.exe工具可以通过WindowsInstallerSDK获得。
 
问: 如何在安装期间隐藏“取消”按钮?
答: 从WindowsInstaller2.0开始,我们提供了一个命令行选项,以便在显示简单的安装界面(UI)时,隐藏“取消”按钮。以下命令行脚本演示了这个新选项的使用方法:

msiexec/i{pathtopackage}/qb!

此外,您还可以使用MsiSetInternalUIWin32API并结合使用INSTALLUILEVEL_HIDECANCEL和INSTALLUILEVEL_BASIC来隐藏“取消”按钮。或者,在使用WindowsInstaller对象的读写UILevel属性时,您可以结合使用msiUILevelHideCancel和msiUILevelBasic,通过WindowsInstaller自动化来实现这一目的。

在程序安装期间,“取消”按钮的存在与否可以通过一个DLL或者脚本定制操作加以改变,该操作会发送一个INSTALLMESSAGE_COMMONDATA消息。DLL定制操作使用MsiProcessMessageWin32API发送INSTALLMESSAGE_COMMONDATA消息,在该消息中,记录的字段1被设置为“2”,而字段2被设置为“0”。为了解除“取消”按钮的隐藏状态,您可以仍然使用这个消息,但是请将字段2设置为“1”。脚本定制操作使用会话对象的等效消息(Message)方法。
 
问: 我怎样才能只安装那些我希望使用的功能特性?
答: 您可以使用ADDLOCAL、ADDSOURCE和ADVERTISE属性安装某些特定的功能特性。以下命令行脚本可以将example.msi程序包中的“Sports”(体育)和“News”(新闻)特性安装在本地计算机上。

msiexec/iexample.msiADDLOCAL=Sports,News/qb

以下命令行脚本可以通告“Sports”特性和安装“News”特性,以便从源程序运行这些特性。

Msiexec/iexample.msiADVERTISE=SportsADDSOURCE=News/qb

另一个重要的注意事项是:功能特性的名称是大小写敏感的。
 
问: 我怎样在升级期间强制升级一个和版本无关的文件,即使用户已经修改了该文件?
答: 通过在“文件”(File)表中为文件制作一个版本号,您可以在升级期间“强制升级”一个和版本无关的文件。根据Windows Installer的文件版本控制原则,版本发生变化的文件将覆盖一个和版本无关的文件。需要注意的是:所有的后续重新安装过程都需要访问源程序,因为所有的后续版本检查都会指出文件需要被重新安装。
 
问: 我怎样才能正确地书写路径字符串?
答: 目录属性值以一个目录分隔符结束。因此,路径字符串的书写不要求使用目录分隔符。

错误写法:[DirectoryProperty]/someLocation
正确写法:[DirectoryProperty]someLocation
 
问: 我应该怎样为不同的地理区域开发产品?
答: 对于拥有不同版本的产品--这种不同既可以是产品语言上的不同,也可以是产品功能间的差异,您可以使用不同的产品代号。以便指明方向、熟悉产品间的关系,并且让产品共享相同的升级代码。
 
问:
答: 

安全性
问: 我怎样在升级期间强制升级一个和版本无关的文件,即使用户已经修改了该文件?
答: 通过在“文件”(File)表中为文件制作一个版本号,您可以在升级期间“强制升级”一个和版本无关的文件。根据Windows Installer的文件版本控制原则,版本发生变化的文件将覆盖一个和版本无关的文件。需要注意的是:所有的后续重新安装过程都需要访问源程序,因为所有的后续版本检查都会指出文件需要被重新安装。
 
问: 我怎样在升级期间强制升级一个和版本无关的文件,即使用户已经修改了该文件?
答: 通过在“文件”(File)表中为文件制作一个版本号,您可以在升级期间“强制升级”一个和版本无关的文件。根据Windows Installer的文件版本控制原则,版本发生变化的文件将覆盖一个和版本无关的文件。需要注意的是:所有的后续重新安装过程都需要访问源程序,因为所有的后续版本检查都会指出文件需要被重新安装。
 
问: 我怎样在升级期间强制升级一个和版本无关的文件,即使用户已经修改了该文件?
答: 通过在“文件”(File)表中为文件制作一个版本号,您可以在升级期间“强制升级”一个和版本无关的文件。根据Windows Installer的文件版本控制原则,版本发生变化的文件将覆盖一个和版本无关的文件。需要注意的是:所有的后续重新安装过程都需要访问源程序,因为所有的后续版本检查都会指出文件需要被重新安装。
 
问:
答: 

定制操作
问: “延迟”定制操作和“立即”定制操作有何不同?
答: “延迟”定制操作仅仅能够以执行后续表中的InstallInitialize或InstallFinalize操作作为其后续操作。而“立即”定制操作可以以后续表中的任何地方作为其后续操作。

“延迟”定制操作不能访问安装数据库。事实上,“延迟”定制操作只具有十分有限的安装会话访问能力,因为安装脚本可以在创建该脚本的安装会话的外部执行。“立即”定制操作可以访问安装数据库,并且可以读取和设置安装属性,修改特性和组件状态,以及添加临时行、临时列和临时表等其它东西。

尽管“延迟”和“立即”定制操作都可以运行在初始化安装操作的用户上下文环境中,但是只有“延迟”定制操作可以使用系统上下文环境以得到提升的权限运行。

“延迟”定制操作不能够立即执行。相反,它们按照预先设定的日程在脚本执行期间运行。在InstallExecute、InstallExecuteAgain或InstallFinalize操作运行之前,执行脚本并不会被处理。
 
问: 我什么时候应该使用延迟定制脚本,而不是使用立即定制脚本?
答: 如果定制操作必须修改系统或者调用另一个系统服务,那么您必须使用延迟定制脚本。此外,只有延迟定制操作能够运行经过权限提升的上下文环境中。如果您的定制脚本需要经过提升的权限才能运行,那么您需要将定制脚本标记为“延迟”脚本。注意:只有在安装程序自身经过权限提升的情况下,标记为在系统上下文环境(msidbCustomActionTypeInScript+msidbCustomActionTypeNoImpersonate)中运行的定制操作才能够运行。

此外,如果希望通过定制操作对系统进行修改,您还应该包括一个回滚定制操作,以便撤销修改,将系统还原回先前状态。
 
问: 如何向我的延迟定制脚本提供数据?
答: 延迟定制操作只能对安装会话进行有限访问。如果您的延迟定制操作无法通过这种有限的访问获取到有关安装的信息,您可以通过CustomActionData属性为延迟定制操作提供这些信息。这种方法仅仅对脚本和DLL延迟定制操作有效。其具体工作方式如下:

在延迟定制操作之前执行的立即定制操作会使用与延迟定制操作所使用的相同名称将某个属性设置为延迟定制操作需要的值。所以,如果延迟定制操作的主键名称为“DeferredCA”,那么立即定制操作将把名为“DeferredCA”的属性设置为延迟定制操作需要的值。类型51的定制操作可以很容易地设置该属性。另一种方法是:立即定制操作使用“szName”参数调用MsiSetProperty,其中szName参数等于“DeferredCA”。注意:操作名称是大小写敏感的。

当延迟定制操作排队进入安装脚本之后,安装程序将会把“DeferredCA”属性值写入到安装脚本之中,并用它作为CustomActionData属性的值。

在执行时,延迟定制脚本通过调用带有szName参数的MsiGetProperty来获得所需的值,其中szName参数等于CustomActionData。或者,脚本定制操作会使用会话(Session)对象的“Property”属性。
 
问: 我能够使用定制操作重新启动计算机吗?
答: 通过使用MSIRUNMODE_REBOOTATEND或MSIRUNMODE_REBOOT的运行模式以及等于“TRUE”的状态值调用MsiSetMode,立即定制操作可以重新启动计算机。因为MsiSetMode需要一个hInstall句柄,所以只有DLL和脚本定制操作能够重新启动计算机。脚本定制操作将使用“会话”对象的“模式”属性。或者,立即定制操作也可以使用等于“ScheduleReboot”的szAction参数调用MsiDoAction。

延迟定制操作不能调用MsiSetMode。延迟定制操作需要对注册表某个位置的值进行设置,该值会被立即定制操作和随后的InstallFinalize读取。然后,立即定制操作可以使用MsiSetMode设定计算机的重新启动日程。如果需要使用该方法,您还应该提供一个回滚定制操作,以便在取消安装时,从注册表中删除能够触发重新启动的该键值。
 
问: 我的定制操作应该如何向日志文件添加信息?
答: 通过使用MsiProcessMessage API发送INSTALLMESSAGE_INFO消息,DLL和脚本定制操作可以向日志文件添加信息。脚本定制操作将使用“Session”(会话)对象的“Message”(消息)方法。
 
问: 为什么在安装程序时,会有多个MSIExec.exe进程运行在我的计算机上?
答: 在程序安装期间,会有多个MSIExec进程运行。之所以会出现这种现象,主要是因为Windows Installer使用了客户机-服务器模式来执行程序安装任务。此外,出于安全方面的考虑,Windows Installer会在一个“沙箱”(sandbox)进程中驻留DLL和脚本定制操作。根据安装过程初始化方式的不同,一个MSIExec进程将作为客户机进程。另一个MSIExec进程将作为Windows Installer服务。在计算机上运行的所有MSIExec进程通常都是用来托管定制操作的沙箱进程。决定哪一个MSIExec进程将作为面向脚本或DLL定制操作的沙箱进程的具体过程部分取决于定制操作是以经过提升的权限运行还是以人格化的方式运行,以及该定制操作是32位的还是64位的。
 
问:
答: 

补丁和升级
问: 小型、次要和主要升级之间有何不同?
答: “小型”升级是一种只对很少的文件进行修改或者只增加少量新内容的产品升级。“次要”升级是对产品进行的修改足以改变产品版本号的产品升级,而“主要”升级则是对产品进行了大量修改,以致需要修改产品代号的产品升级活动。下表总结了每一种升级方式所做的产品修改内容以及每种升级方式可能使用的分发载体形式。

在某种程度上,您可以将一个小型升级看作是一个“热修补”或者“快速修补工程”(Quick Fix Engineering,QFE)升级,将次要升级看作服务包,而将主要升级看作是产品升级。

除了次要升级会改变产品版本号而小型升级不会改变版本号之外,小型升级和次要升级可以被认为是基本相同的。它们所遵循的原则和补丁程序都是相同的。小型升级和次要升级的应用程序都需要进行明确的重新安装。主要升级则不受此限制,补丁程序不需要重新安装。此外,小型升级和次要升级的补丁程序对程序包的功能组件结构所做的修改比较有限。而主要升级则会对程序的功能组件结构进行显著的修改。
 
问: 什么时候补丁程序会需要原始源文件?
答: Windows Installer 2.进行了大量改进,以便将补丁程序需要原始源文件的次数降低到最少。但是,在以下一些特殊情况下,它仍然会需要原始源文件:

? 应用于某个功能特性的补丁当前正在源文件中运行。在这种情况下,该特性会从“run-from-source”状态过渡到本地状态。
 
? 需要应用补丁的组件出现了问题(文件丢失或者受到损害)。
 
? 需要应用补丁的文件在一个组件之中,该组件还包含一些与版本变化无关的文件,并且没有MsiFileHash项目。需要一个经过填充的MsiFileHash表,以防止从源位置重新复制这些与版本变化无关的文件。
 
? 补丁应用时带有一个值为“amus”的REINSTALLMODE选项。该选项比较危险,因为它会忽略文件的版本对文件进行复制。从而导致对较早的文件进行修订,所以它总是需要源文件。我们建议将REINSTALLMODE的值设置为“omus”。
 
? 产品的缓存程序包丢失了。经过缓存的程序包对于补丁程序来说是必需的。这个缓存下来的程序包存储在“%windir%/Installer”文件夹中。
 
? 程序包被设计为需要调用ResolveSource操作。该操作一般应该被尽量避免,或者仅仅用在某些特定的条件下,因为执行该操作总是会导致系统访问源文件。
 
? 程序包拥有一个定制操作,该操作试图通过某种方式访问源文件。
 
? 补丁程序包由二进制的补丁文件组成,这些文件不能应用到计算机文件的当前版本之上。请看以下示例:

1.
 安装示例产品的RTM版本。这会将1.0版本的Example.dll安装到计算机中。
 
2.
 在计算机上应用补丁程序qfe1.msp。该补丁将Example.dll的版本从1.0升级到1.1。
 
3.
 新的补丁qfe2.msp已经发布,它可以将Example.dll升级到1.2版本。但是,该补丁仅仅适用于Example.dll的1.0版本,因为它是利用该产品的RTM制作生成的。1.2版本的Example.dll包括了Example.dll1.1版本中的所有修补,但是MSP是在RTM和QFE2映像间生成的。所以,如果在计算机上应用qfe2.msp,WindowsInstaller将需要访问原始的源文件。example.dll的二进制补丁不能应用到1.1版本上;它只能应用于1.0版本。这会使安装程序重新从原始的源文件位置复制1.0版本的example.dll,以便补丁能够成功得到应用。
 
 
 
问: 我怎样才能防止我的补丁程序需要访问源文件?
答: 目前,您还无法完全阻止补丁程序访问源文件,但是,以下步骤可以帮助您减少程序访问源文件的次数:

? 使用只包含完整文件的补丁。这使得补丁创建程序无需根据每个先前发布的补丁程序和产品的RTM版本创建二进制补丁。通过将PatchCreationProperties(补丁创建属性,PCP)文件的“Properties”(属性)表中的IncludeWholeFilesOnly属性的值设置为“1”,您可以轻松制作出仅仅包含完整文件的补丁。
 
? 确保您所有的定制操作都不会访问原始的源文件位置。
 
? 确保ResolveSource操作只有在特定条件中才会执行,或者根本不存在此操作。
 
? 为程序包中所有与版本变化无关的文件建立“MsiFileHash”表。WindowsInstallerSDK包括了一个名为“MSIFiler.exe”的工具和一个名为“Wifilver.vbs”的脚本,它们可以自动完成这项工作。
 
 
问: 为什么虽然我的补丁成功应用到了计算机上,但是文件却没有被升级?
答: 这很可能是因为您简单地双击了一个小型或次要升级补丁。小型升级或者次要升级的补丁程序需要对将要升级的文件执行一次明确的重新安装过程。您可以使用MSIExec命令行完成这个工作,并且将REINSTALL和REINSTALLMODE属性包括在命令行命令之中(也就是:msiexec /p {path to my patch.msp} REINSTALL=ALL REINSTALLMODE=omus)。另一种方法是:在补丁中包括一个定制操作,对REINSTALL和REINSTALLMODE属性进行相应的设置。您应该确信您对该操作的执行条件进行了严格的限制,只在补丁程序的第一次应用期间执行。产品的后续重新安装不应该导致该定制操作的执行,否则您的产品可能会变得无法卸载。其它方法包括使用一个启动执行文件并利用正确的属性设置调用MsiApplyPatch,或者使用Windows Installer自动化对象,使用脚本编写补丁应用程序。
 
问: 我能通过补丁升级一个定制操作吗?
答: 可以,您可以使用补丁升级某个定制操作。如果定制操作包括在 “Binary”(二进制)表中,那么您可以简单地对升级安装映像中的定制操作进行升级。如果您使用原始文件和升级安装映像制作补丁程序,该补丁将包含一个数据库转换,将老的二进制数据流转换成新的二进制数据流。
 
问:
答: 

故障处理
问: 我如何才能找出程序包安装失败的原因?
答: 有三种比较好的方法可以对程序包的安装问题进行跟踪。第一种方法是通过运行校验确信您的程序包合法有效。通过进行验证,您可以发现错误和警告,并找出一些常见的安装程序制作问题。有两个工具可以对安装程序包进行验证,这两个程序都可以通过Windows Installer SDK获得:MsiVal2和Orca。MsiVal2是一个用来校验程序包的命令行工具。Orca则为验证提供了一个图形化的用户界面,并且可以突出显示程序包中的无效实体。

第二种方法是使用应用程序事件日志。Windows Installer会把成功和失败信息记录在应用程序事件日志当中。

最后一种方法是生成一个详细日志文件。然后分析该详细日志文件,并从中找出错误的根源。Windows Installer SDK提供的WILogUtl.exe工具可以帮助您分析详细日志文件。 日志记录可以通过Windows Installer日志记录策略加以启用,或者,您也可以通过在MSIExec命令行中附加“/L*v path to logfile”来启用该功能。

为了通过策略获得详尽的详细日志文件, 请使用如下注册表键:

? HKLM/Software/Policies/Microsoft/Windows/Installer
 
? 设置:Logging=REG_SZvoicewarmup
 
? 设置:Debug=REG_DWORD0x7
 

通过策略键生成的日志文件将以msiXXXXX.log的格式存储在用户的“%temp%”文件夹中。

注意:通过命令行产生的日志记录比所有的日志记录策略设置拥有更高的优先级。
 
问: 在我每次启动程序的时候,Windows Installer都会执行安装操作。我怎样确定产生这种按需安装的原因是什么?
答: 有一种方法可以容易地确定引起按需安装的原因,那就是:在应用程序事件日志中查找以下格式的MsiInstaller日志信息:

事件类型:警告
事件来源:MsiInstaller
事件ID:1001
描述:检测产品'{000C1109-0000-0000-C000-000000000046}',特性'Example'在请求组件'{00030829-0000-0000-C000-000000000046}'时发生失败

事件类型:警告
事件来源:MsiInstaller
事件ID:1004
描述:检测产品'{000C1109-0000-0000-C000-000000000046}',特性'Example',组件'{00030829-0000-0000-C000-000000000046}'失败。资源'C:/ProgamFiles/example/example.exe'不存在。

第一条信息(事件ID为1001)说明了哪一个组件正在被安装。此处列出的组件是在针对特殊快捷方式的Shortcut(快捷方式)表中的Component(组件)列中所指定的组件。

第二条信息(事件ID为1004)指出了哪一个组件在检测时发生失败。WindowsInstaller2.0经过改进的事件日志功能已经对信息进行了更新,以便在大多数情况下,用户都可以通过事件信息查找出导致检测失败的真正问题根源。如果组件的键路径(Keypath)丢失或者受损,可能会导致用户重新安装程序。

在上例中,用户需要重新安装程序,因为资源“c:/ProgramFiles/example/example.exe“不存在。您应该找出导致键路径不存在的原因所在--在本例中,是因为用户删除了该文件。
 
问: 我如何才能找出程序包安装失败的原因?
答: 有三种比较好的方法可以对程序包的安装问题进行跟踪。第一种方法是通过运行校验确信您的程序包合法有效。通过进行验证,您可以发现错误和警告,并找出一些常见的安装程序制作问题。有两个工具可以对安装程序包进行验证,这两个程序都可以通过WindowsInstallerSDK获得:MsiVal2和Orca。MsiVal2是一个用来校验程序包的命令行工具。Orca则为验证提供了一个图形化的用户界面,并且可以突出显示程序包中的无效实体。

第二种方法是使用应用程序事件日志。WindowsInstaller会把成功和失败信息记录在应用程序事件日志当中。

最后一种方法是生成一个详细日志文件。然后分析该详细日志文件,并从中找出错误的根源。WindowsInstallerSDK提供的WILogUtl.exe工具可以帮助您分析详细日志文件。日志记录可以通过WindowsInstaller日志记录策略加以启用,或者,您也可以通过在MSIExec命令行中附加“/L*vpathtologfile”来启用该功能。

为了通过策略获得详尽的详细日志文件,请使用如下注册表键:

? HKLM/Software/Policies/Microsoft/Windows/Installer
 
? 设置:Logging=REG_SZvoicewarmup
 
? 设置:Debug=REG_DWORD0x7
 

通过策略键生成的日志文件将以msiXXXXX.log的格式存储在用户的“%temp%”文件夹中。

注意:通过命令行产生的日志记录比所有的日志记录策略设置拥有更高的优先级。
 
问: 我怎样才能确定Windows Installer是否安装了我的功能特性或组件?
答: 确定WindowsInstaller是否安装了某个特定功能或组件的方法十分简单。您可以通过WindowsInstaller的verbose日志文件找到答案。您首先需要查找的是InstallValidate操作的日志信息。该操作将会把程序包中每个功能和组件的安装、请求和操作状态记录下来。

MSI(s)(5C:F4):执行操作:InstallValidate
操作开始1:51:18:InstallValidate.
MSI(s)(5C:F4):功能:Example;安装:缺席;请求:本地;操作:本地
MSI(s)(5C:F4):组件:Example;安装:缺席;请求:本地;操作:本地
操作结束1:51:18:InstallValidate.返回值1.

在上述日志文件片断中“Example”功能将在本地进行安装,因为它的操作状态为“本地”此外,组件“Example”也将根据给定的操作状态进行本地安装。
 
问: 为什么我的文件在卸载过程中没有被删除?
答: 产生这个问题的原因主要有四种:

1.
 这些文件所属的组件被标记为“永久”(permanent)。(这一点可以通过Component表的Attributes列来实现)
 
2.
 这些文件所属的组件没有一个拥有组件GUID。(位于Component表的ComponentId列的该值为NULL)。WindowsInstaller无法管理那些没有GUID的组件。
 
3.
 如果组件的键路径(keypath)拥有一个共享的DLLrefcount,那么该组件将不能被卸载。
 
4.
 如果该组件安装在系统文件夹中,而且在程序卸载之时,组件中的某一个文件拥有一个外部共享的DLLrefcount,那么该组件将不能被卸载。
 
 
问: 为什么我的文件夹在程序卸载时没有被删除?
答: 导致文件夹在程序卸载过程中不能被删除的原因主要有以下几种:

? 在同时使用CreateFolder表和CreateFolders操作时,执行顺序表中的RemoveFolders操作丢失。
 
? 该文件夹不是由Windows Installer创建的文件夹,因此它不会删除它们,除非您告诉Windows Installer删除这些文件夹。
 
? 文件夹中仍然存在资源。
 
 
问: 为什么我的注册表键在程序卸载是没有被删除?
答: 导致程序卸载时注册表键没有被删除的最常见原因有以下几种:

1.
 Registry(注册表)表包含了带有“+”标记的实体。该符号将指示Installer在卸载程序时保留这些注册表键。
 
2.
 在InstallExecuteSequence表中,RemoveRegistryValues操作位于UnregisterProgIdInfo和 UnregisterMIMEInfo操作之后。您需要反转这些操作的顺序。Registry表所写入的某些注册表键值会阻止特定的ProgId、扩展和CLSID 键被删除。
 
 
问: 为什么安装过程所占用的磁盘空间远远大于我实际安装的文件尺寸?
答: WindowsInstaller会计算两种类型的磁盘占用:带有回滚操作的磁盘占用;以及没有回滚操作的空间占用。没有回滚的空间占用是程序安装实际占用的磁盘空间。带有回滚操作的空间占用包括了在安装过程中为回滚操作提供支持所需的备份文件所占用的空间。此外,WindowsInstaller还会计算出执行安装操作所需的一些额外空间占用。其中包括安装脚本所需占用的空间以及缓存程序包的空间需求。此外,在安装期间,Installer需要对安装程序包进行临时复制。安装脚本和程序包运行副本所占用的空间是临时性的。在安装结束之后,这些文件将会被清除。请看以下示例,在本例中,您的安装程序包的大小约为80KB,而您正在安装一个4KB的文件。(注意:根据硬盘簇大小的不同,您的数字与我的可能会有所不同):

89120字节(被缓存的MSI,基本上是4KB簇大小的整数倍)
89120字节(MSI的临时工作副本)
8192字节(估计的脚本大小)
4096字节(小文件,与大小为4KB磁盘簇基于相等)
--------------------------------------
176128字节=172KB
 
问: 为什么Windows Installer提示我重新启动计算机?
答: 如果WindowsInstaller需要覆盖一个正在使用的文件,或者安装程序包明确要求Installer重新启动计算机,那么WindowsInstaller将会提示您重新启动。我们可以很容易地判断出WindowsInstaller是否是因为需要覆盖一个正在使用的文件而提示您重新启动计算机。我们首先需要生成一个详细日志文件。在这个详细日志文件中,在属性部分中查找是否存在ReplacedInUseFiles属性。如果该属性存在,并且值为1,那么Installer将会因为需要覆盖一个正在使用的文件而提出重新启动计算机的请求。

为了确定哪一个文件正在被使用,请扫描日志文件,查找“Info1603”和“Info1903”信息1603信息由InstallValidate操作记录在日志文件中。例如:

MSI(s)(DC:DC):执行操作:InstallValidate
操作开始19:55:42:InstallValidate.

Info1603.文件“d:/test/sample.exe”正在被以下进程使用:名称:sample.exe,Id:4068,窗口标题:‘Sample’。请关闭该程序,然后再试。

一般情况下,出现该消息的同时,也会出现“FilesInUse”(文件正在使用)对话框。但是在使用“安静”UI的情况下,该对话框不会出现。此外,并不是所有正在被使用的文件都会出现在“FilesInUse”对话框中。如果处于使用状态的文件不是一个可执行文件,持有这些文件的进程是一个与安装过程有关的进程,或者持有文件的进程没有一个与之相关的窗口标题,“FilesInUse”对话框都可能不会显示。

安装脚本中的FileCopyopcode也会将Info1603信息记录在日志中。在上例中,日志文件包含:

MSI(s)(DC:DC):Executingop:FileCopy(SourceName=sample.exe,SourceCabKey=sample.exe,DestName=sample.exe,Attributes=0,FileSize=2044928,PerTick=32768,,VerifyMedia=1,,,,,CheckCRC=0,Version=2.0.2600.0,Language=0,InstallMode=59244544,,,,,,)

Info1603.文件“D:/test/sample.exe”正在被使用。请关闭程序然后再试。

在文件清理期间的脚本末尾,以下日志文件信息将指出要求用户重新启动计算机的“元凶”:

Info1903.设定重启日程:删除文件“D:/Config.Msi/12544a31.rbf”。您必须重新启动以完成操作。

尽管文件名为“12544a31.rbf”,但实际上它是“Sample.exe”文件。为了安装文件,正在使用的文件会被重新命名为.rbf文件,然后在重新启动后被删除。
 
问: “ERROR_INSTALL_PACKAGE_VERSION 错误(1613)是什么意思?
答: “ERROR_INSTALL_PACKAGE_VERSION”错误表示:计算机上的WindowsInstaller不支持本程序包的架构。程序包架构由程序包摘要信息流中的PID_PAGECOUNT属性指出。如果程序包的架构号大于WindowsInstaller所能够支持的最大架构,您就需要升级WindowsInstaller的版本或者重新制作该安装程序包,利用较早期的架构对其进行编译。

所有版本的MSI所支持的最小架构号为30。

每个版本的MSI所支持的最大架构号如下:

? WindowsInstaller1.0:100
 
? WindowsInstaller1.1:110
 
? WindowsInstaller1.2:120
 
? WindowsInstaller2.0:200
 
 
问: 在我用系统账户启动一个安装过程的时候,我得到了编号为2103的错误信息,这是为什么?
答: 从系统账户(例如计划任务服务)启动程序安装可能会导致2103错误。如果您进行的是一个针对用户的安装,这种情况就会发生。只有针对计算机的安装才能够使用系统账户,因为系统账户不能够对所有必要的用户配置文件夹进行访问。
 
问: 在我从终端服务器上的一个映射驱动器进行安装的时候,为什么出现了2755错误?
答: Windows 2000和更早期的操作系统不支持在终端服务器会话间传递映射驱动器盘符信息。因为Windows Installer服务是在控制台会话中作为一个服务运行,在远程会话中建立的映射驱动器盘对于Windows Installer服务来说是不可见的,从而导致了本错误的出现。只有服务运行于应用程序服务器模式下时才会出现本错误,在远程管理(Remote Admin)模式下不会出现。

注意:Windows XP以及其后的操作系统不存在此限制。
 
问: 在我安装一个使用Web下载启动文件的程序包时,我为什么会得到一个安全性警告对话框,对话框中的消息称“访问在线撤销服务器时发生错误”?
答: 安全性警告对话框之所以会出现,是因为在Web下载启动文件(Setup.exe)执行数字签名验证的过程中发生了问题。我们已经通过Windows Installer SDK提供的最新示例代码解决了这个问题,该SDK可以从Microsoft Download Center获得。您只需要使用工具对Setup.exe进行简单的重新配置即可。您可以从SDK Update站点下载该经过修正的示例代码。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值