Wix将端口写入etc / services文件

时间:2014-03-20 07:19:23

标签: wix

我正在使用Wix 3.8替换旧的安装程序。 旧安装程序在文件%SYS32%\Drivers\Etc\Services中插入一行,这似乎很简单。但是,我还没有找到任何使用WiX向文本文件添加新信息的简单方法。所以我想也许还有其他方法可以做到这一点 - 即不使用服务文件,而是使用Windows中的其他设置注册端口,例如使用WiX简单地写入注册表。

任何人都知道怎么做?

否则,任何针对Wix的自定义“FileWriter”的提示?我找到的唯一一个只能使用模板文件写,这不是我想要的。我当然可以写自己的,但这就像重新发明轮子一样......

谢谢!

/托马斯

2 个答案:

答案 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元素的BinaryKeyDllEntry属性来指定要调用的方法:

<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中获取值。