这是我使用WiX的第一个项目。
我正在为Windows Service创建一个安装程序,在安装过程中,我需要收集服务将使用的一些配置数据。这包括到数据库的连接字符串。
<Binary Id="CustomActionBinary" SourceFile="$(var.ServiceSetupActions.TargetDir)$(var.ServiceSetupActions.TargetName).CA.dll"/>
<CustomAction
Id="ServiceSetupActions"
BinaryKey="CustomActionBinary"
DllEntry="SaveCompanySettings"
Execute="deferred"
Return="check"
Impersonate="no" />
<CustomAction
Id="SetupCustomProperties"
Property="ServiceSetupActions"
Value="DBTYPE=[DBTYPE];CONNECTIONSTRING=[CONNECTIONSTRING];INSTALLFOLDER=[INSTALLFOLDER]"/>
<InstallExecuteSequence>
<Custom Action="SetupCustomProperties" Before="ServiceSetupActions" />
<Custom Action="ServiceSetupActions" After="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence>
问题是WiX使用分号作为数据分隔符(https://github.com/wixtoolset/Dtf/blob/09dc7b4e4494182c0906bf5492f12e09c918444f/src/WixToolset.Dtf.WindowsInstaller/customactiondata.cs#L32),因此在设置过程中输入的连接字符串在我的自定义操作中被错误地反序列化。
问题是:我如何才能正确地传递一个包含分号的字符串到自定义操作(使用session.CustomActionData
),这样它就不会被歪曲。
另一种选择是一个完整的SQL连接对话框,它将询问服务器,数据库,用户名和密码,但服务可以处理PostgresSQL和MS SQL,有时连接字符串可能包含一些修改。
我看到你标记了这个c#,所以我假设你使用DTF自定义操作。
在DTF中,您可以创建另一个自定义操作并在立即执行时运行它。在该操作中,您可以创建一个CustomActionData集合,填充键值对,然后调用session.DoAction(),并将延迟的定制操作的名称传递给调度和CustomActionData集合。序列化将神奇地发生,键值对将在延迟的自定义操作中可用,只需输入session.CustomActionData(key);
请检查这个示例,看看它是否适用于您:https://github.com/glytzhkof/WiXDeferredModeSample
这里是示例的另一个版本,这个版本使用DTF CustomActionData类来实现更多的"auto-magic":https://github.com/glytzhkof/WiXDeferredModeSampleDTF—它将为您调度自定义操作,并且您可以以延迟模式访问属性。已完成有限测试
-
在
"PUT-GUID-HERE"
的源代码行设置一个升级GUID-你可以在这里创建一个GUID -
改变属性
MYPROPERTY
包含分号;
。在这个WiX源代码行这样做。如果您愿意,可以使用下面的示例文本(当然,任何其他文本都可以):<Property Id="MYPROPERTY" Hidden="yes" Secure="yes">Test;Test1;Test2</Property>
-
编译并运行测试。将显示一个消息框,它应该包含您在源文件中指定的完整字符串。
如果你想在你发送到延迟模式的字符串中组合几个属性值,你有几个选项。最简单的方法是用需要的值设置几个属性,然后将它们组合成一个字符串发送到延迟模式。您可以通过以下几种方式设置属性:对话框、命令行、输入框等…
- MYCOMPANY = "Some Company">
- MYDATABASE = " thedatabasname ">
- 等等…
则调用Session.Format
在立即模式下,自定义动作解析字符串中的值。像这样:
COMPANYID = [COMPANYID]; DBTYPE = [DBTYPE]; CONNECTIONSTRING = [CONNECTIONSTRING]; INSTALLFOLDER = [INSTALLFOLDER]
var CAdata = Session.Format("MYCOMPANY=[MYCOMPANY];MYDB=[MYDB];MYDBTYPE=[MYDBTYPE]");
session["MYPROPERTYSENTTODEFERREDMODE"] = CAdata;
您还需要Type 51 CA来实际将该字符串发送到延迟模式自定义操作。您可以在上面的示例中看到这是如何实现的。
然后检索MYPROPERTYSENTTODEFERREDMODE
的字符串值在延迟模式自定义动作,你应该能够直接使用它?与:
- 关于延迟模式和WiX标记的现有回答。