我是Windows编程中的菜鸟,但我必须创建一个棘手的MSI安装程序,通过WiX工具集安装插件。 安装程序应通过Windows注册表API检测运行所有已安装的特定软件版本及其插件目录。之后,它应该在一个单独的页面(对话框)上显示所有这些页面,并带有相应的复选框。用户应该选择他们希望插件安装到哪个版本。
我已经创建了一个自定义操作(在C ++中并将其放入MSI数据库中的DLL中),它与注册表API进行交互,然后遍历结果并将临时记录添加到数据库表中:
它在AppSearch之后运行
<InstallUISequence>
<Custom Action="PopulateVersions" After="AppSearch">Not Installed</Custom>
</InstallUISequence>
然后单击“下一步”按钮(我知道它是一个错误的地方来执行此类操作)执行自定义操作,过滤掉活动属性路径获取第一个并执行SetTargetPath操作(它工作正常)。对于其余的操作,操作会将适当的临时记录插入:
它仅将插件安装到引用的第一个属性路径(已传递给SetTargetPath操作)。
很好......我添加了一些CopyFile元素,这些元素引用我的自定义属性(我声明了一些特性以防止由于未知属性导致的MSI构建错误)到WiX标记仅用于测试:
<Property Id="PathProperty0" Value="{}"/>
<Property Id="PathProperty1" Value="{}"/>
<Property Id="PathProperty2" Value="{}"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="INSTALLLOCATION" Name="MyPluginDir">
<Component Id="PluginExt" Guid="C112184A-307C-5E15-994F-0DFDA9DD427E">
<File Id="MyPlugin" Name="MyPlugin.dll" Source="MyPlugin.dll" Vital="yes" />
<CopyFile Id="MyPlugin_Copy1" FileId="MyPlugin" DestinationProperty="PathProperty1"/>
<CopyFile Id="MyPlugin_Copy2" FileId="MyPlugin" DestinationProperty="PathProperty2"/>
</Component>
</Directory>
</Directory>
</Directory>
现在ProgressDialog说&#34; {}&#34;是无效路径,但所有属性都设置为有效路径(我在调试中检查了这一点)! 在显示要求访问同一MSI文件的提升UAC提示后,似乎忘记或忽略所有临时数据库更改/属性更改。单击“安装”按钮(带有屏蔽图标)后会出现提示。可能它再次读取数据库并且没有找到任何更改,因为它们在内存或缓存中,我不知道。
我做错了什么或如何正确安装?恕我直言,我的实现过于复杂。我需要你的帮助。
答案 0 :(得分:2)
我发现至少有两个错误:
您希望在运行时更改的路径的属性应为PUBLIC properties(即,其名称不得包含小写字母。此外,它们可能应列在{{3}中} property,您可以通过在源中使用或不使用值声明它们并指定SecureCustomProperties
属性来确保。
您为与目录相关的属性指定的值实际上是{}
。这是一个不寻常的值,很少是正确的。通常,您需要一个空字符串。例外情况是当您处于Secure上下文并且需要指定导致空字符串值的非空字符串时,例如属性设置Formatted
。 wix源的ControlEvent元素不是这样的上下文。
我不确定您所描述的方法的完全复杂性(我无法完全考虑它),但我确实希望鼓励您以编程方式创建表格数据的一般方法让Windows Installer完成剩下的工作。这种方法非常重要,可以给出一个名称:Property。
根据半自定义操作的指导,您可能希望在InstallUISequence和InstallExecuteSequence中安排PopulateVersions操作(特别是一旦它使用RemoveFile执行清理),以确保安装,维护和静默删除全部获得正确的表格数据。
答案 1 :(得分:2)
我认为你让这个过于复杂。您可以使用一堆AddInVersionXXXX子功能创建AddIns功能,并在功能条件中使用AppSearch的结果,然后显示自定义设置对话框。
在我的IsWiX中,我做了类似的事情,除了我总是安装到检测到的每个版本。诀窍是如果目录属性没有值,CopyFile将优雅地跳过副本。这很简单,可以在这里看到: