我有一个 MSI,我使用正在正常安装的 WiX 脚本动态构建。但是,UninstallString 始终具有 msiexec.exe 的 /I(“斜线眼”)参数,我希望它是 /X。我在这里读到了 UninstallString ,它说这个注册表项是由 Windows 安装程序设置的。我将通过 WiX 或我发出的安装命令将什么传递给 Windows 安装程序,这会导致 UninstallString 始终具有 /I(“斜线眼”)参数?
3 回答
我崩溃了,并就此与 MS 支持人员进行了交谈。答案是将 MSI 中的 ARPNOMODIFY 属性设置为 1,以生成使用 /X 参数的 UninstallString。
/I 参数意味着您在 appwiz.cpl 列表中提供了“更改”和“修复”选项。希望这可以帮助其他人面临这个问题。
下面的 MSDN 文章详细描述了 ARP 属性。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa367590(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa367591(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa367592(v=vs.85).aspx
您必须在 WiX 安装程序中创建一个 ARPAltRegistryEntries 组件来设置 UninstallString。将参数设置为 /I 而不是预期的 /X 允许您使用自己的卸载 UI。这是一个例子:
<DirectoryRef Id="TARGETDIR">
<!-- Create alternative ARP entry that lets us launch uninstall with
full UI. Setting ARPSYSTEMCOMPONENT above hides WI generated key
that uses the product GUID.-->
<Component Id="ARPAltRegistryEntries" Guid="">
<RegistryKey Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Your Product" Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="UninstallString" Value="MsiExec.exe /i[ProductCode] REMOVE=ALL"/>
</RegistryKey>
</Component>
</DirectoryRef>
这个问题是针对 Wix 项目提出的,但是如果有人正在使用 Visual Studio 的安装项目,那么解决方案之一是添加一个构建后的 vb 脚本以将 ARPNOMODIFY 更改为 1,正如@joe Baltimore 所建议的那样
- 创建一个VB脚本文件如下“setnomodify.vbs”:
Option Explicit
Const msiOpenDatabaseModeTransact = 1
Dim argNum, argCount:argCount = Wscript.Arguments.Count
Dim openMode : openMode = msiOpenDatabaseModeTransact
'This script adds a type 51 custom action into a given MSI database that
'ensures the ARPNOMODIFY is set to 1
' Connect to Windows installer object
On Error Resume Next
Dim installer : Set installer = Nothing
Set installer = Wscript.CreateObject("WindowsInstaller.Installer") :
CheckError
' Open database
Dim databasePath:databasePath = Wscript.Arguments(0)
Dim database : Set database = installer.OpenDatabase(databasePath, openMode) : CheckError
' Process SQL statements
Dim query, view, record, message, rowData, columnCount, delim, column
query = "INSERT INTO `Property` (`Property`, `Value`) VALUES ('ARPNOMODIFY', '1')"
Set view = database.OpenView(query) : CheckError
view.Execute : CheckError
database.Commit
If Not IsEmpty(message) Then Wscript.Echo message
Wscript.Quit 0
Sub CheckError
Dim message, errRec
If Err = 0 Then Exit Sub
message = Err.Source & " " & Hex(Err) & ": " & Err.Description
If Not installer Is Nothing Then
Set errRec = installer.LastErrorRecord
If Not errRec Is Nothing Then message = message & vbLf & errRec.FormatText
End If
Fail message
End Sub
Sub Fail(message)
Wscript.Echo message
Wscript.Quit 2
End Sub
- 将此脚本路径添加为具有正确文件夹路径的安装程序项目的构建后事件,如下所示:
PostBuildEvent = cscript "$(ProjectDir)setnomodify.vbs" "$(BuiltOuputPath)"
现在,每当您构建安装程序设置项目时,ARPNOMODIFY 将设置为 1,并且已安装应用程序的 Unistallstring 将在注册表中具有“/X”而不是“/I”
您也可以通过使用 ORCA 并在 MSI 的“属性”表中将 ARPNOMODIFY 添加为 1 来手动执行此操作。