我的wix对话框上有几个单选按钮。当我选择第一个时,我直接通过对话框输入信息,但是当选择第二个选项时,用户必须选择配置文件在网络上的位置,所以我想将此文件复制到目标位置,但仅限于第二个选项已选择单选按钮,用户已选择该文件。
所以这个问题应该分为三部分:
1)如何将外部文件从网络复制到目标位置
2)仅当第二个单选按钮和文件都已设置时,如何复制此文件。
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 :(得分: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>
最后,请注意安装顺序。这样可以确保在最后完成此操作并且之前未安装产品,选择了第二个单选按钮并且实际选择了该文件。请注意,在此阶段技术上不需要文件路径检查,因为我在“下一步”按钮上进行验证,除非包含配置文件的文本框已填满,否则我不允许单击“下一步”按钮。
<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 :(得分:1)
<CustomAction Id="ConfigureApp_Cmd" Property="ConfigureApp" Execute="immediate"
Value=""robocopy" "[FILEPATH]" "[INSDIR]"" />
<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=""robocopy" "[FILEPATH]" "[INSDIR]" /PURGE /e" />
<CustomAction Id="ConfigureApp" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/>
我假设FILEPATH是一个路径,当使用类似的东西调用安装程序时,该路径作为参数传递: msiexec / i FILEPATH = / qn / l * v install.log
让我知道这是否有效。