2012-10-30 38 views
1

我正在部署包含加密字段的产品在某些配置xml文件中。 安装期间,我正在目标机器上创建一个自签名证书。然后我用它来加密一些字符串,最后我需要将它们存储在配置文件中。如何从WiX中的延期自定义操作获取输出变量?

为了创建证书,我将带有的makecert.exe带到目标安装目录。所以,我需要等到所有文件都复制到目的地后才能运行创建证书的CustomAction。在此之后,其他一些CustomAction正在创建需要存储在配置中的加密值。

这很好,但在这一点上,我想将新值存储在我的配置文件中,但我已经错过了执行XmlFile/XmlConfig的阶段。在MSI日志我看到执行“ExecXmlConfig”行动中的文件被复制之后:

MSI (s) (6C:CC) [02:12:10:898]: Source for file 'makecert.exe' is compressed 
InstallFiles: File: makecert.exe, Directory: C:\Program Files (x86)\MyProduct\InstanceFolder\, Size: 60240 
MSI (s) (6C:CC) [02:12:10:900]: Executing op: SetTargetFolder(Folder=C:\Program Files (x86)\MyProduct\Nhibernate\) 
MSI (s) (6C:CC) [02:12:10:900]: Executing op: SetSourceFolder(Folder=1\o1lebnnf\vemzkq_g\|MyProduct\Nhibernate\) 
MSI (s) (6C:CC) [02:12:10:901]: Executing op: FileCopy(SourceName=nw4bpvhi.xml|hibernate.cfg.xml,SourceCabKey=nhibernate.config,DestName=hibernate.cfg.xml,.... 
MSI (s) (6C:CC) [02:12:10:902]: File: C:\Program Files (x86)\MyProduct\Nhibernate\hibernate.cfg.xml; Won't Overwrite; Won't patch; Existing file is unversioned but modified 
MSI (s) (6C:CC) [02:12:10:902]: Executing op: SetTargetFolder(Folder=C:\Program Files (x86)\MyProduct\InstanceFolder\) 
MSI (s) (6C:CC) [02:12:10:902]: Executing op: SetSourceFolder(Folder=1\o1lebnnf\|MyProduct\) 
MSI (s) (6C:CC) [02:12:10:902]: Executing op: FileCopy(SourceName=7z64.dll,SourceCabKey=Seven7z64.dll,DestName=7z64.dll,Attributes=512,... 
MSI (s) (6C:CC) [02:12:10:903]: File: C:\Program Files (x86)\MyProduct\InstanceFolder\7z64.dll; To be installed; Won't patch; No existing file 
MSI (s) (6C:CC) [02:12:10:903]: Source for file 'Seven7z64.dll' is compressed 
InstallFiles: File: 7z64.dll, Directory: C:\Program Files (x86)\MyProduct\InstanceFolder\, Size: 1484800 
MSI (s) (6C:CC) [02:12:10:929]: Executing op: CacheSizeFlush(,) 
MSI (s) (6C:CC) [02:12:10:929]: Executing op: ActionStart(Name=ExecXmlConfigRollback,,) 
Action 02:12:10: ExecXmlConfigRollback. 
MSI (s) (6C:CC) [02:12:10:948]: Executing op: CustomActionSchedule(Action=ExecXmlConfigRollback,ActionType=3329,Source=BinaryData,Target=ExecXmlConfigRollback,... 
MSI (s) (6C:CC) [02:12:10:949]: Executing op: ActionStart(Name=ExecXmlConfig,,) 
Action 02:12:10: ExecXmlConfig. 
MSI (s) (6C:CC) [02:12:10:951]: Executing op: CustomActionSchedule(Action=ExecXmlConfig,ActionType=3073,Source=BinaryData,Target=ExecXmlConfig,CustomActionData=1?C:\Program Files (x86)\MyProduct\Nhibernate\hibernate.cfg.xml?3?0?/hibernate-configuration/session-factory/property[@name='connection.connection_string']????0) 

所以,我被困在中间......如果配置我CustomAction运行After='InstallFiles'它试图执行早在文件被复制之前。 (我错过了正确的事件?)。另一方面,如果我将Actions配置为运行After='InstallFinalize' - 这太迟了,因为XmlConfig已经触发了,并且没有向配置文件写入任何内容。 理想情况下,我想在安装的最后运行所有这些。

看来愚蠢,我应该需要编写一个CustomAction,做酷似ExecXmlConfig相同的操作只是把它在其他时间......

这里是我的InstallExecuteSequence:

<InstallExecuteSequence> 

     <!-- Create and Register Certificate on Install --> 
     <Custom Action='GenerateProductCertificate'   After='InstallFiles'><![CDATA[REMOVE<>"ALL"]]></Custom> 
     <Custom Action='RegisterProductServiceCertificate' After='GenerateProductCertificate'><![CDATA[REMOVE<>"ALL"]]></Custom> 

     <!-- Create and NHibernate Certificate -->  
     <Custom Action='GenerateNHibernateCertificate'  After='RegisterProductServiceCertificate'><![CDATA[REMOVE<>"ALL"]]></Custom> 

     <!-- Configure NHibernate XML with Encrypted ConnectionString --> 
     <Custom Action='GenerateSecureConnectionString'     After='GenerateNHibernateCertificate'><![CDATA[(REMOVE<>"ALL")]]></Custom> 

    </InstallExecuteSequence> 

我我使用WiX的3.7(v3.7.1022.0,星期一,2012年10月22日)

我的问题是:

  • 有没有办法在我的CustomActions之后重新安排ExecXmlConfig动作来运行 ?
  • 如果没有,我可以安排我的CustomActions在复制文件和ExceXmlConfig之间运行吗?

编辑:

一些更多的尝试后,并多一点研究,我可以更准确地定义了我的问题。 我想知道的是:如何从延迟操作中设置一个输出值,以供下一个延迟操作使用?

我的方案迫使我在延迟模式下运行我的自定义操作,因此无法访问会话以存储任何新的变量。但我相信更多的延期行动是安排的,所以我想要做的是找到一种方法将一些变量传递给他们。

+0

您的自定义操作是否推迟?如果您在InstallFiles之后计划延迟的自定义操作,它将在文件安装后触发,这是肯定的。 –

+0

使自定义操作延期解决了时间。但是这些操作的要点是用加密的密码生成一个ConnectionString。名为'GenerateSecureConnectionString'的动作需要将新的ConnectionString返回到一些我想传递给XmlConfig以存储在配置文件中的Property。 但延迟操作无法访问会话 - 所以最终它不能解决我的问题... – Roman

回答

1

同样的问题出现在我正在构建的msi中。

如何从延迟操作中设置输出值,以供下一个延期操作使用?

底线是,我无法准确地做到这一点。但是,我确实通过其他自定义操作找到了解决方法。

我的情况略有不同,但希望有所帮助。对于这种情况,有一些注册表项必须更新,我希望在回滚的情况下保存以前的值。我不能使用标准的msi注册表机制,因为值名称将取决于安装(我知道可能值的范围)。

我的自定义操作都是以二进制的DLL基于C++的代码。我的第一个想法是基于这样一个假设,即一旦dll被加载,它将保持不变,并且延迟执行序列中的所有调用都可以访问任何创建的数据结构。所以,我只是创建了一个全局变量并将必要的数据保存到它。但是,在回滚调用期间,结构是空的。似乎在每次调用dll之前,dll都会重新加载。尽管我调查了足够多的DllMain,但我没有完全确认。

我终于来到了该解决方案是建立在脚本生成轮执行顺序的跑了两个额外的自定义操作,为每一个安装和回滚。他们扫描了注册表并生成了一个分隔字符串,该分隔字符串保存为用于相应安装和回滚自定义操作的CustomActionData。工作完成后的延迟自定义操作被重写,只是通过CustomActionData来完成它们的操作。所有“逻辑”(几乎全部)都在创建分隔字符串的代码中。

这似乎工作。我唯一担心的是现在在注册表扫描和注册表更新之间存在一些延迟和分离,这对于美学目的我想我是想避免的。

不知道,如果你可以做你的情况类似的事情。一个想法是也使用二进制DLL来管理所有的工作。它还会根据您的第一个自定义操作的模拟输出生成CustomActionData的自定义操作,然后可以由您的第二个自定义操作读取。由于您的自定义操作涉及调用外部exe,因此可以使用ShellExecute,System,CreateProcess或类似的操作。问题是否可以在没有实际运行第一个自定义操作的情况下获得足够的信息?