我正在使用Wix 3.8替换旧的安装程序。
旧安装程序在文件%SYS32%\Drivers\Etc\Services
中插入一行,这似乎很简单。但是,我还没有找到任何使用WiX向文本文件添加新信息的简单方法。所以我想也许还有其他方法可以做到这一点 - 即不使用服务文件,而是使用Windows中的其他设置注册端口,例如使用WiX简单地写入注册表。
任何人都知道怎么做?
否则,任何针对Wix的自定义“FileWriter”的提示?我找到的唯一一个只能使用模板文件写,这不是我想要的。我当然可以写自己的,但这就像重新发明轮子一样......
谢谢!
/托马斯
答案 0 :(得分:0)
对于写入文件,您可以创建一个动态链接库,其中包含将执行您要完成的任务的方法(编辑文件等)。然后,您可以创建一个 Type 1 自定义操作,该操作从dll文件调用方法。从技术上讲,Type 1操作意味着创建一个非托管C / C ++ dll(Windows Installer本身不支持.NET操作),但您可以使用C#Custom Action项目(随WiX扩展一起提供)从托管创建C / C ++ dll C#代码。
aCustomAction.cs
using System;
using Microsoft.Deployment.WindowsInstaller;
namespace someLibrary
{
public class CustomActions
{
[CustomAction]
public static ActionResult MyFunction(Session session)
{
// do something
return ActionResult.Success;
}
}
}
ActionResult
返回类型通知安装程序操作是成功还是失败。请注意,每个CustomAction
项目可以使用128个自定义操作(在Wix 3.6之前为16个)。
编译项目时,您将拥有.dll和.CA.dll文件。您应该通过向Product.wxs添加以下行来引用wix项目中的第二个(包括非托管代码):
<Binary Id="aCustomActionDLL" SourceFile=".\aCustomAction.CA.dll" />
或者您可以使用$var
直接从项目中引用。
最后,您可以使用CustomAction
元素的BinaryKey
和DllEntry
属性来指定要调用的方法:
<CustomAction Id="CA_aCustomAction"
BinaryKey="aCustomActionDLL"
DllEntry="MyFunction"
Execute="deferred"
Return="Check" />
然后安排它运行:
<InstallUISequence>
<Custom Action="CA_aCustomAction" After="CostFinalize" />
</InstallUISequence>
dll文件不会安装到用户的计算机上;他们履行职责但仍留在MSI包中。
作为替代方案,您可以创建完整的可执行文件,然后将其作为自定义操作(类型2,类型18或类型34 )运行。我推荐输入类型2,因为它将exe文件嵌入到MSI中:
<Binary Id="yourProgramEXE" SourceFile="source.exe" />
<CustomAction Id=""CA_ProgramExe"
BinaryKey= "yourProgramEXE"
Impersonate="yes"
Execute="deferred"
ExeCommand=""
Return=""check />
Impersonate
告诉安装程序是否模拟启动安装程序的用户。如果不是,则您的操作将以LocalUser
运行。即时操作不需要模拟,如果您立即将其设置为no
,则会收到ICE68警告。但是,我强烈建议将它们设置为deferred
,以便在安装失败时进行设置。它们可以回滚。
答案 1 :(得分:0)
非常简单的操作的另一种选择是嵌入式vbscript。只需要“CustomAction”和“InstallSequence”节点,CustomAction看起来像这样:
<CustomAction Id="RestoreBackupDbFile" Script="vbscript" >
<![CDATA[
Set fso = CreateObject("Scripting.FileSystemObject")
path = fso.BuildPath(Session.Property("DATAFOLDER"), "Default")
if fso.FolderExists(path) then
dbp = fso.BuildPath(path, "TEST.db.bak")
if fso.FileExists(dbp) then
fso.CopyFile dbp, fso.BuildPath(path, "TEST.db"), true
fso.DeleteFile dbp
end if
end if
]]>
</CustomAction>
请注意使用Session.Property从正在执行的MSI中获取值。