用Wix手工编辑XML制作C++ MSI安装程序,怎样保证安装新版本时候强制卸载旧版本,急急急!!!

Anson__Hu 2009-04-10 06:15:37
★★我的问题如下,为了能说清楚,我写了比较长,希望能耐心看看★★
本程序是一个网络监控客户端程序,安装好后会在系统中注册一个服务,为了和服务器端通信。
我只是负责制作MSI安装程序,有人专门做开发,当然我对于VC++一无所知。

按照常规我在wix的wxs中进行相应编辑设置,生成第一版MSI程序setup1.msi,安装在系统中,菜单显示版本号:1.4.0.3
之后因为程序做了修改,所以我把版本号和ProductCode进行修改,再次生成第二版MSI安装程序setup2.msi这次根据客户要求,
想把原来程序彻底清除,进行重新安装。当然如果能覆盖安装也行,最终验证程序菜单显示新版本号:1.4.0.12,
并且第二次修改的功能得以正常运行就可以了。

★★现在问题来了,setup2.msi正常安装后,发现控制面板的"添加/删除程序"中出现2个相同名字的程序,菜单版本号还是原来的1.4.0.3,没有变。

怎样修改wix的wxs文件才能达到我要的效果,还是本身就不支持这个功能呢。当然我使用如下方法可以达到这个目的:
就是用控制面板中添加/删除程序卸载用setup1.msi安装的旧程序,然后再用setup2.msi进行全新安装。

但是这个程序是需要用SMS2003远程发布到8000个客户端,当然发布的时候用msiexec.exe /qn setup1.msi 进行远程静默安装
当程序版本升级时候,目前的方法,msiexec.exe /x setup1.msi 进行远程卸载第一版程序,
再用msiexec.exe /qn setup2.msi,远程安装第二版程序。就是说如果要卸载第一版程序,必须用msiexec.exe /x setup1.msi ,而不是msiexec.exe /x setup2.msi,无法用第二版程序setup2.msi加上/x参数卸载以前的程序。更无法用用第二版程序msiexec.exe /qn setup2.msi,进行覆盖安装,因为本身本地环境就测试没有通过。



第一版MSI安装程序基本版本信息,安装程序名 setup1.msi
MajorVersion:0
MinorVersion:0
BuildVersion:0

ProductCode:
8C47739C-9821-4eb0-8723-1FF719601F42

UpgradeCode:
EC8F55C0-1089-46b9-884D-CB7CEC4C0FE7

第二版MSI安装程序基本版本信息,安装程序名 setup2.msi
MajorVersion:1(修改)
MinorVersion:1(修改)
BuildVersion:1(修改)

ProductCode:(修改)
81B1D01B-42A6-48a4-8BDA-774A3F966421

UpgradeCode:(不变)
EC8F55C0-1089-46b9-884D-CB7CEC4C0FE7

其实2个版本安装目录下的文件名字和目录名都没有变化,当然程序内部做了调整。
第一个版本的菜单显示这样的版本号:1.4.0.3
第一个版本的菜单显示这样的版本号:1.4.0.12
这个版本号和wix中控制的版本号有啥区别,我不知道,可能是VC++中控制的


第一版wix配置文件截取片段
##############################################################################################################################
<Product Id="8C47739C-9821-4eb0-8723-1FF719601F42"
UpgradeCode="EC8F55C0-1089-46b9-884D-CB7CEC4C0FE7"
Name="My product name"
Version="0.0.0"
Manufacturer="My Company name"
Language="1041"
Codepage="932" >

<Package Id="????????-????-????-????-????????????"
Description="My product Version 0.0.0"
Comments="My product package"
InstallerVersion="200"
Platforms="Intel"
Manufacturer="My Company name"
Languages="1041"
SummaryCodepage="932" />

<!-- ParseAddress是为了取得网络监控服务器端的IP地址用CustomAction -->
<CustomAction Id="SetCustomActionData" Property="ParseAddress" Value="[OriginalDatabase]" />
<CustomAction Id="ParseAddress" BinaryKey="AddressParser" DllEntry="ParseAddress" Execute="deferred" Impersonate="no" />

<InstallUISequence>
<Custom Action="DetectUpgrade" After="FindRelatedProducts">UPGRADEFOUND</Custom>
<Custom Action="DetectNewerVersion" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
<Custom Action="DetectOldCWS" After="FindRelatedProducts">DETECTOLDCWS</Custom>
</InstallUISequence>

<InstallExecuteSequence>
<Custom Action="DetectUpgrade" After="FindRelatedProducts">UPGRADEFOUND</Custom>
<Custom Action="DetectOldCWS" After="FindRelatedProducts">DETECTOLDCWS</Custom>
<Custom Action="DetectNewerVersion" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>

<Custom Action="SetCustomActionData" Before="ParseAddress" ><![CDATA[ &Complete>2 ]]></Custom>
<Custom Action="ParseAddress" Before="InstallFinalize" ><![CDATA[ &Complete>2 ]]></Custom>
<RemoveExistingProducts After="InstallFinalize" />
</InstallExecuteSequence>

<Binary Id="AddressParser" SourceFile="CustomActions\debug\AddressParser.dll" />

##############################################################################################################################

第二版wix配置文件截取片段,这一版本中,加了RemovePreviousVersions,DetectNewerInstalledVersion这2个参数,同时
删除InstallUISequence节点,还有InstallExecuteSequence节点中DetectUpgrade,DetectOldCWS,DetectNewerVersion三个action
原因是如果不删除这些,不管怎么修改版本号和ProductCode,在安装的时候都会报告,已经安装一个版本的程序,请到控制面板卸载后再安装。
当然我对于这些参数,不是很懂,网上也差不到资料。
##############################################################################################################################
<Product Id="81B1D01B-42A6-48a4-8BDA-774A3F966421"
UpgradeCode="C4CE1A62-2C9E-11DD-8316-BA7755D89593"
Name="My product name"
Version="1.1.1"
Manufacturer="My Company name"
Language="1041"
Codepage="932" >

<Package Id="????????-????-????-????-????????????"
Description="My product Version 1.1.1"
Comments="My product package"
InstallerVersion="200"
Platforms="Intel"
Manufacturer="My Company name"
Languages="1041"
SummaryCodepage="932" />

<!-- ParseAddress是为了取得网络监控服务器端的IP地址用CustomAction -->
<CustomAction Id="SetCustomActionData" Property="ParseAddress" Value="[OriginalDatabase]" />
<CustomAction Id="ParseAddress" BinaryKey="AddressParser" DllEntry="ParseAddress" Execute="deferred" Impersonate="no" />

<InstallExecuteSequence>

<Custom Action="SetCustomActionData" Before="ParseAddress" ><![CDATA[ &Complete>2 ]]></Custom>
<Custom Action="ParseAddress" Before="InstallFinalize" ><![CDATA[ &Complete>2 ]]></Custom>

<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>

<Property Id="RemovePreviousVersions" Value='True' />
<Property Id="DetectNewerInstalledVersion" Value='false' />

<Binary Id="AddressParser" SourceFile="CustomActions\debug\AddressParser.dll" />
##############################################################################################################################




我在网上搜索了一番,找到如下讨论
相关网址 http://www.itzhe.cn/news/20080128/66246.html

##################################################################################################################################
★★如何在部署时,对已经存在的文件进行覆盖处理★★

网友回复:
假如安装了,会提示卸载呀
在文件属性里面可能有设置,看看吧

网友回复:2楼完全没有做过任何部署。
3楼。同UpgradeCode的情况下,卸载会自动发生。但由于用户设置的不同,不能保证一定会完全卸载。对于没有卸载的文件,可能需要在释放新版本的情况下,进行覆盖处理。要害是这个地方要设哪个属性,有没有这样的属性?

网友回复:不知道VS的安装程序是怎么处理的,InstallShield是有多个选择项的,可以选择强制覆盖,比较时间更新覆盖,等

网友回复:修改RemovePreviousVersions行不?
网友回复:为了解决这个问题,似乎只能先卸载再安装...

网友回复:继续一下。RemovePreviousVersions的行为,是要比较前后版本的差异后才定下来的。我上面所说的情况下,他不会完全卸载全部组件。

网友回复:楼主我试过,程序版本相同的情况下,把 UpgradeCode 换了,第二次安装的时候,也还是会自动卸载第一次安装的文件,然后安装新文件。不会出现楼主说的那种不覆盖文件的情况。
  不同版本的把 UpgradeCode 换了重复安装没测试过,应该不会卸载旧版本文件了,因为UpgradeCode变了,效果应该等同于 DetectNewerInstalledVersion 和RemovePreviousVersions 都为false。
  不过把安装项目的 ProductCode 换了的话。就会出现楼主说的这种情况,原先安装的文件不会自动卸载掉,也不会覆盖掉,安装过程一点提示都没有,不过查看“控制面板”-〉“添加删除程序”就会发现,这两个“不同”的程序同时存在,显示都被安装了,但后来那次安装肯定不完整,缺文件。也就是说安装项目什么也不认,就认 ProductCode,相同就当成同一个程序,不同就当成两个独立的程序。当两个独立程序要把同一个文件部署在同一个目录时,先到先得,晚到就被挤掉了。
  这可能也是微软出于安全的考虑。假如不这样做,恶意安装程序就很轻易假借你写的程序的文件名,覆盖掉你的程序,破坏客户机器,因为存在这种危险隐患,所以干脆也不弹覆盖对话框了,省得满头浆糊的客户在安装时候不小心装上了恶意程序都不知道。
  所以楼主这问题我认为无解,微软的设计目的使然,所以还是按照微软说的,不要改变 UpgradeCode 和 ProductCode ,且应当小心保存这两个值(ProductCode 可有多个,随版本和语言的不同而不同),实在不行找个记事本,Ctrl-C Ctrl-V,不小心弄乱了还可以恢复。

网友回复:这个倒是有可能。我没有找到相关的选项来处理。
网友回复:不过确实很不好,这样部署不完整都不知道。
#########################################################################################################################
...全文
318 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
hahanibc 2009-10-08
  • 打赏
  • 举报
回复
请高手帮忙看看

关闭文件句柄 fclose 会出错 求解 付上代码 2楼

http://topic.csdn.net/u/20091008/19/85c0ef22-5fe7-4f59-bb49-c1161c35c8f1.html
devinside 2009-09-25
  • 打赏
  • 举报
回复
up
mengde007 2009-04-10
  • 打赏
  • 举报
回复
楼主好像发错了区。你到WEB区去看看。
verywzm 2009-04-10
  • 打赏
  • 举报
回复
帮顶

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧