2014-09-24 78 views
0

我的wix对话框中有几个单选按钮。选择第一个时,我直接通过对话框输入信息,但是当选择第二个选项时,用户必须选择配置文件在网络上的位置,所以我想将该文件复制到目标位置,但只有第二个选项单选按钮已被选中并且该文件已被用户选择。使用wix安装程序根据条件复制外部文件

1)我如何从网络上复制一个外部文件到目标位置

2)如何只有当两个复制此文件:

所以这个问题应该真正在3个部分细分第二个单选按钮和文件已被设置。

3)如果不行,其他建议?

请注意,我的单选按钮选择存储在名为CONFIGURATIONSELECTION的变量中,所选文件存储在名为FILEPATH的变量中。

我想下面会的工作,但

<Component Id="CMP_Startup.Config" Guid="0C301558-1894-4A7C-A0A4-C47660F9D334"> 
    <Condition> 
     <![CDATA[(CONFIGURATIONSELECTION = 2 AND FILEPATH <> "")]]> 
    </Condition> 
    <File Id="FILE_Startup.Config" Source="FILEPATH" Compressed="no" /> 
    </Component> 

但它抛出一个错误,在编译即"The system cannot find the FILEPATH"

可我甚至做到这一点?如果不是,我应该使用CustomAction手动复制文件吗?如果是这样,我怎么能做到这一点作为我安装的最后一步?

谢谢。

+0

我发布了一个我认为是有效的答案,但我没有意识到,我愚蠢地将配置文件作为常规文件包含在我的安装中。一旦我将其删除,我建议的解决方案无法正常工作,因此请回到制图板! – Thierry 2014-09-24 11:54:38

回答

2

我结束了使用CustomAction方法。希望这可以帮助别人

请记住:
- 我使用单选按钮并将选择存储在CONFIGURATIONSELECTION变量中。
- 我使用自定义操作,允许用户通过文件选择对话框选择文件,并将返回的结果存储在FILEPATH变量中。

首先,照顾变量定义的:

<Product> 
    ... 
    <Property Id="CONFIGURATIONSELECTION" Value="1" Secure="yes"/> 
    <Property Id="FILEPATH" Admin="yes" Secure="yes" /> 
    ... 
</Product> 

然后定义CustomAction:

<Product> 
... 
    <Binary Id="CustomActions.CA" SourceFile="..\CustomActions\bin\ 
    $(var.Configuration)\CustomActions.CA.dll" /> 

    <CustomAction Id="CopyStartupConfig" Return="check" Execute="deferred" 
    BinaryKey="CustomActions.CA" DllEntry="CopyStartupConfig" /> 

... 
</Product> 

最后,注意安装序列。这可以确保在最后完成该操作,并且该产品以前未安装,第二个单选按钮已被选中,并且该文件实际已被选中。请注意,在这个阶段技术上不需要文件路径检查,因为我在我的Next按钮上进行了验证,除非已经填充了包含配置文件的文本框,否则不允许我单击Next按钮。

<InstallExecuteSequence> 
    <Custom Action="CopyStartupConfig" Before="InstallFinalize"> 
    <![CDATA[NOT Installed AND CONFIGURATIONSELECTION = 2 AND FILEPATH <> ""]]> 
    </Custom> 
</InstallExecuteSequence> 

...

至于自定义操作本身,它是一个简单的复制文件:

[CustomAction] 
    public static ActionResult CopyStartupConfig(Session session) 
    { 
     session.Log("CopyStartupConfig"); 
     try 
     { 
      string sourceFilename = session.CustomActionData["STARTUPCONFIG"]; 
      string targetFilename = Path.Combine(session.CustomActionData["APPLICATIONFOLDER"], Path.GetFileName(session.CustomActionData["STARTUPCONFIG"])); 

      session.Log("SourceFileName: " + sourceFilename); 
      session.Log("TargetFilename: " + targetFilename); 

      session.Log("About to copy " + sourceFilename + " to " + targetFilename); 
      File.Copy(sourceFilename, targetFilename); 
      session.Log(sourceFilename + " copied successfully."); 

      return ActionResult.Success; 
     } 
     catch (Exception ex) 
     { 
      session.Log("An unhandled exception has occured in CopyStartupConfig: " + ex.ToString()); 
      return ActionResult.Failure; 
     } 
    } 

记住,这样做是因为被应用在InstallFinalize条件和两个变量已经设定的一种方式或其他,我打电话给我的自定义对话框,其中包括单选按钮,文件选择等...

上述似乎工作,但我显然必须花更多的时间来测试它,我也必须照顾在发生卸载时删除配置文件的习惯,我必须确保这一点如果调用修理或更改,则不会发生任何事情。

更新:我最初删除了我的答案,因为我注意到它实际上并没有工作,并且我错过了将参数传递给我的自定义操作的关键部分。我认为这是自动完成的,但似乎并非如此。

不管怎么说,进一步研究这个问题后,我发现这篇文章能够解释它很清楚:

Creating Custom Action for WIX Written in Managed Code without Votive

因此,这里是缺少的部分:

您需要包括你想要的变量在自定义操作中传递给自定义操作,并在每个值之间使用分号:

<CustomAction Id="SetCopyStartupConfigDataValue" Return="check" 
       Property="CopyStartupConfig" Value="APPLICATIONFOLDER= 
       [APPLICATIONFOLDER];STARTUPCONFIG=[FILEPATH]" /> 

现在,请务必在您InstallSequence这个自定义操作,并设置它被称为复制操作之前被触发:

<InstallExecuteSequence> 
    <Custom Action="SetCopyStartupConfigDataValue" Before="CopyStartupConfig"> 
    NOT Installed</Custom> 

    <Custom Action="CopyStartupConfig" Before="InstallFinalize"> 
    <![CDATA[NOT Installed AND CONFIGURATIONSELECTION = 2 AND FILEPATH <> ""]]> 
    </Custom> 
</InstallExecuteSequence> 

的最后一步是修改我的自定义操作。我更新了上面的代码,但总之,为了访问你已经通过的变量,你不想使用session["STARTUPCONFIG"],而是想要使用会话session.CustomActionData["STARTUPCONFIG"]

希望这有助于!

1

您是否尝试过robocopy?我有要求复制一些文件和robocopy帮助。

<CustomAction Id="ConfigureApp_Cmd" Property="ConfigureApp" Execute="immediate" 
    Value="&quot;robocopy&quot; &quot;[FILEPATH]&quot; &quot;[INSDIR]&quot;" /> 
<CustomAction Id="ConfigureApp" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/> 

<InstallExecuteSequence> 
    <Custom Action="ConfigureApp_Cmd" After="StartServices"><![CDATA[NOT(Installed)]]></Custom> 
    <Custom Action="ConfigureApp" After="ConfigureApp_Cmd"><![CDATA[NOT(Installed)]]></Custom> 
</InstallExecuteSequence> 

如果目标位置已被清除,如果源目录结构必须保持那么我们可能会增加这些选项

<CustomAction Id="ConfigureApp_Cmd" Property="ConfigureApp" Execute="immediate" 
    Value="&quot;robocopy&quot; &quot;[FILEPATH]&quot; &quot;[INSDIR]&quot; /PURGE /e" /> 
<CustomAction Id="ConfigureApp" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/> 

我假设filepath是正在传递的路径作为安装程序被调用时的参数: msiexec/i FILEPATH =/qn/l * v install.log

让我知道这是否可行。

+0

谢谢,但我结束了使用标准的自定义操作,它的工作。我最初发布了一个答案,然后我删除了,因为我意识到它太迟了,但它没有工作,但我现在修复了它,并且我已经删除它并更新了我如何修复它。 – Thierry 2014-09-25 10:09:33

相关问题